Skip to content

Commit 8b817d1

Browse files
committed
feat: added /chat-history endpoint
1 parent 2b568f5 commit 8b817d1

File tree

14 files changed

+201
-84
lines changed

14 files changed

+201
-84
lines changed

.DS_Store

0 Bytes
Binary file not shown.

.env-example

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
PORT=3000
2-
IS_DOCKER=false
32

43
LANGCHAIN_API_KEY=
54
LANGCHAIN_TRACING_V2=true
65
LANGCHAIN_CALLBACKS_BACKGROUND=true
76

87
LLM_API_KEY=
98

10-
REDIS_URL=redis://127.0.0.1:6379
11-
REDIS_URL_DOCKER=redis://redis:6379
9+
REDIS_URL=redis://redis:6379
1210
REDIS_USER=
1311
REDIS_PASSWORD=
1412

15-
DATABASE_URL=postgresql://genaiapp:password@localhost:5432/app_db?schema=public
16-
DATABASE_URL_DOCKER=postgresql://genaiapp:password@postgres:5432/app_db?schema=public
13+
DATABASE_URL=postgresql://genaiapp:<password>@postgres:5432/app_db?schema=public
1714

1815
JWT_SECRET=
1916
JWT_EXPIRATION=1h
2017

21-
QDRANT_URL=qdrant://qdrant:6333
22-
QDRANT_COLLECTION=genai-api-docs
18+
QDRANT_URL=http://qdrant:6333
19+
QDRANT_COLLECTION=genai_documents

docker-compose.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ services:
88
- '3000:3000'
99
env_file:
1010
- .env
11-
environment:
12-
IS_DOCKER: true
13-
DATABASE_URL: ${DATABASE_URL_DOCKER}
14-
REDIS_URL: ${REDIS_URL_DOCKER}
1511
volumes:
1612
- ./src:/usr/workspace/app/src
1713
- pnpm_store:/pnpm/.pnpm-store
1814
command: sh -c "pnpm migrate:dev && pnpm dev"
1915
depends_on:
2016
- postgres
2117
- redis
18+
- qdrant
2219

2320
postgres:
2421
container_name: genai_app_postgres

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"scripts": {
66
"prestart": "node dynamic-url-config.js",
77
"migrate:dev": "npx prisma migrate dev",
8-
"predev": "node dynamic-url-config.js",
98
"start": "tsx src/app.ts",
109
"dev": "tsx watch src/app.ts",
1110
"postinstall": "npx prisma generate"

src/di/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ const vectorDataBaseProvider = new VectorDataBaseProvider()
1818
// Gen AI Module
1919
const genAIController = new GenAIController()
2020
const documentService = new DocumentsService()
21-
const searchInDocumentUseCase = new SearchInDocumentUseCase(documentService)
21+
const searchInDocumentsUseCase = new SearchInDocumentUseCase(
22+
documentService,
23+
vectorDataBaseProvider,
24+
)
2225

2326
const translateUseCase = new TranslateTextUseCase()
2427

@@ -42,10 +45,11 @@ export {
4245
genAIController,
4346
prismaClient,
4447
resourcesController,
45-
searchInDocumentUseCase,
48+
searchInDocumentsUseCase,
4649
storeDocumentsUseCase,
4750
translateUseCase,
4851
userDatProvider,
4952
usersController,
5053
vectorDataBaseProvider,
5154
}
55+

src/modules/core/adapters/dataproviders/vector-store/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { VectorStoreRetriever } from '@langchain/core/vectorstores'
12
import { QdrantVectorStore } from '@langchain/qdrant'
23
import { QdrantClient } from '@qdrant/js-client-rest'
34
import { Document } from 'langchain/document'
@@ -18,8 +19,8 @@ export class VectorDataBaseProvider {
1819
})
1920
}
2021

21-
get asRetriever() {
22-
return this._vectorStore.asRetriever
22+
get asRetriever(): VectorStoreRetriever<QdrantVectorStore> {
23+
return this._vectorStore.asRetriever()
2324
}
2425

2526
storeDocuments(documents: Document[]): Promise<void> {
Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AppRequest, AppResponse } from '@/common/types';
2-
import { searchInDocumentUseCase, translateUseCase } from '@/di';
3-
import { uploadSingle } from '@/modules/core'
2+
import { searchInDocumentsUseCase, translateUseCase } from '@/di'
3+
import { ChatMemory } from '@/modules/core'
44

55
export class GenAIController {
66
async translateText(
@@ -12,37 +12,26 @@ export class GenAIController {
1212
return res.send({ success: true, data: result })
1313
}
1414

15-
async searchInDocument(
15+
async searchInDocuments(
1616
req: AppRequest<any, any, { query: string }>,
1717
res: AppResponse,
1818
) {
19-
uploadSingle(req, res, async (err) => {
20-
if (err) {
21-
return res
22-
.status(500)
23-
.json({ success: false, error: { message: 'File upload failed!' } })
24-
}
25-
26-
if (!req.file) {
27-
return res.status(400).json({
28-
success: false,
29-
error: { message: 'Please provide a valid file!' },
30-
})
31-
}
19+
const { query } = req.body
20+
const { result } = await searchInDocumentsUseCase.invoke({
21+
query: query,
22+
userId: req.user!.id,
23+
})
3224

33-
const query = req.body.query
34-
const filePath = `/uploads/${req.file.filename}`
25+
return res.send({ success: true, data: result })
26+
}
3527

36-
const { result } = await searchInDocumentUseCase.invoke({
37-
query,
38-
filePath,
39-
userId: req.user!.id,
40-
})
28+
async getChatHistory(req: AppRequest, res: AppResponse) {
29+
const chatMemory = new ChatMemory(req.user!.id)
30+
const history = await chatMemory.retrieveMemoryHistory()
4131

42-
return res.json({
43-
success: true,
44-
data: result,
45-
})
32+
return res.send({
33+
success: true,
34+
data: history,
4635
})
4736
}
4837
}

src/modules/genai/application/routes/index.ts

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,20 @@ router.post(
7070

7171
/**
7272
* @swagger
73-
* /genai/search-in-document:
73+
* /genai/search-in-documents:
7474
* post:
75-
* summary: Performs a search in a PDF document and returns a text as a response for follow-up questions
75+
* summary: Performs a search in stored documents and returns a text as a response
7676
* tags: [AI]
7777
* requestBody:
7878
* required: true
7979
* content:
80-
* multipart/form-data:
80+
* application/json:
8181
* schema:
8282
* type: object
8383
* properties:
84-
* file:
85-
* type: string
86-
* format: binary
87-
* description: The PDF file to be uploaded and analyzed
8884
* query:
8985
* type: string
90-
* example: What is this document about?
86+
* example: What is the purpose of the developed projects on these documents?
9187
* responses:
9288
* 200:
9389
* description: Success
@@ -101,29 +97,76 @@ router.post(
10197
* example: true
10298
* data:
10399
* type: string
104-
* example: This document describes how to implement an API service using Node, Docker and Redis.
105-
* 400:
106-
* description: Bad Request
100+
* example: The project aims to develop and validate a web platform (software) for automatically correcting assessments created in Microsoft Word.
101+
* security:
102+
* - bearerAuth: []
103+
*/
104+
router.post(
105+
'/search-in-documents',
106+
isAuthenticated,
107+
genAIController.searchInDocuments,
108+
)
109+
110+
/**
111+
* @swagger
112+
* /genai/chat-history:
113+
* get:
114+
* tags:
115+
* - AI
116+
* summary: Returns all messages between human and AI from chat history
117+
* responses:
118+
* 200:
119+
* description: Successfully retrieved chat history
107120
* content:
108121
* application/json:
109122
* schema:
110123
* type: object
111124
* properties:
112125
* success:
113126
* type: boolean
114-
* example: false
115-
* error:
127+
* example: true
128+
* data:
116129
* type: array
117130
* items:
118-
* type: string
119-
* example: ["Please provide a valid file!"]
120-
* security:
121-
* - bearerAuth: []
131+
* type: object
132+
* properties:
133+
* lc:
134+
* type: integer
135+
* example: 1
136+
* type:
137+
* type: string
138+
* example: constructor
139+
* id:
140+
* type: array
141+
* items:
142+
* type: string
143+
* example: ["langchain_core", "messages", "HumanMessage"]
144+
* kwargs:
145+
* type: object
146+
* properties:
147+
* content:
148+
* type: string
149+
* example: What is the purpose of the developed projects on these documents?
150+
* additional_kwargs:
151+
* type: object
152+
* example: {}
153+
* response_metadata:
154+
* type: object
155+
* example: {}
156+
* parameters:
157+
* - in: header
158+
* name: Content-Type
159+
* required: true
160+
* schema:
161+
* type: string
162+
* example: application/json
163+
* - in: header
164+
* name: Authorization
165+
* required: true
166+
* schema:
167+
* type: string
168+
* example: Bearer <token>
122169
*/
123-
router.post(
124-
'/search-in-document',
125-
isAuthenticated,
126-
genAIController.searchInDocument,
127-
)
170+
router.get('/chat-history', isAuthenticated, genAIController.getChatHistory)
128171

129172
export default router
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export * from './search-in-document/search-in-document.usecase'
1+
export * from './search-in-documents/search-in-documents.usecase'
22
export * from './translate/translate.usecase'

src/modules/genai/core/usecases/search-in-document/types.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)