@@ -5,35 +5,8 @@ import { NotFoundError } from "../utils/appError.utils.js";
55import { streamText as honoStreamText } from "hono/streaming" ;
66import logger from "../utils/logger.utils.js" ;
77import { streamLoading , streamText , streamError } from "../utils/stream.utils.js" ;
8- import { type UploadedFile } from "@app/shared/src/schemas/message.schema.js"
9-
10- async function handleImageExtraction ( messageFiles : UploadedFile [ ] , stream : any ) : Promise < string > {
11- if ( messageFiles ?. length === 0 ) return "" ;
12-
13- try {
14- await streamLoading ( stream , "Analyzing image..." ) ;
15- const extractionPromises = messageFiles . map ( ( file : UploadedFile ) => {
16- if ( file . fileUrl ) {
17- return extractImageData ( file . fileUrl ) ;
18- }
19- return Promise . resolve ( null ) ;
20- } ) ;
21-
22- const extractionResults = await Promise . allSettled ( extractionPromises ) ;
23-
24- const successfulData = extractionResults
25- . filter ( ( result ) => result . status === "fulfilled" && result . value )
26- . map ( ( result : any ) => result . value as string ) ;
27-
28- if ( successfulData . length > 0 ) {
29- return `\n\nExtracted information from attached images:\n${ successfulData . join ( "\n---\n" ) } \n\nUse this information if relevant when answering.` ;
30- }
31- } catch ( error ) {
32- logger . error ( { message : "Failed to process attached images" , error } ) ;
33- }
34-
35- return "" ;
36- }
8+ import { type UploadedFile } from "@app/shared/src/schemas/message.schema.js" ;
9+ import { vectorStore } from "../config/vectorStore.config.js" ;
3710
3811export async function handleUserMessageResponse ( c : Context ) {
3912 const requestStartTime = new Date ( ) ;
@@ -50,7 +23,7 @@ export async function handleUserMessageResponse(c: Context) {
5023
5124 try {
5225 const [ chat , preferences , memories ] = await Promise . all ( [
53- prisma . chat . findUnique ( { where : { id : chatId , userId } , select : { id : true } } ) ,
26+ prisma . chat . findUnique ( { where : { id : chatId , userId } , select : { id : true , isRag : true } } ) ,
5427 prisma . userPreference . upsert ( { where : { userId } , create : { userId } , update : { } } ) ,
5528 prisma . userMemory . findMany ( { where : { userId } , select : { content : true } } ) ,
5629 ] ) ;
@@ -60,6 +33,23 @@ export async function handleUserMessageResponse(c: Context) {
6033 return ;
6134 }
6235
36+ if ( chat . isRag && query . trim ( ) !== "" ) {
37+ try {
38+ await streamLoading ( stream , "Searching documents..." ) ;
39+
40+ const results = await vectorStore . similaritySearch ( query , 4 , {
41+ chatId : chat . id ,
42+ } ) ;
43+
44+ if ( results . length > 0 ) {
45+ const context = results . map ( ( r ) => r . pageContent ) . join ( "\n\n---\n\n" ) ;
46+ finalQuery = `Context Information:\n${ context } \n\nUser Query: ${ finalQuery } \n\nPlease answer the user query using the context information provided above if it is relevant.` ;
47+ }
48+ } catch ( err ) {
49+ logger . error ( { message : "Vector search failed" , error : err , chatId } ) ;
50+ }
51+ }
52+
6353 const aiStream = generateAIResponse ( {
6454 query : finalQuery ,
6555 threadId : chatId ,
@@ -85,7 +75,7 @@ export async function handleUserMessageResponse(c: Context) {
8575
8676 const filesToCreate = messageFiles ?. length ? messageFiles : undefined ;
8777
88- await prisma . chat . update ( {
78+ const createdChat = await prisma . chat . update ( {
8979 where : { id : chatId } ,
9080 data : {
9181 updatedAt : requestStartTime ,
@@ -101,6 +91,7 @@ export async function handleUserMessageResponse(c: Context) {
10191 ] ,
10292 } ,
10393 } ,
94+ include : { messages : { include : { messageFiles : true } } } ,
10495 } ) ;
10596
10697 scheduleMemoryExtraction ( userId , query , memories ) ;
@@ -115,6 +106,34 @@ export async function handleUserMessageResponse(c: Context) {
115106 } ) ;
116107}
117108
109+ async function handleImageExtraction ( messageFiles : UploadedFile [ ] , stream : any ) {
110+ if ( ! messageFiles ?. length ) return "" ;
111+
112+ const imageFiles = messageFiles . filter ( ( file ) => file . fileType ?. includes ( "image" ) && file . fileUrl ) ;
113+
114+ if ( imageFiles . length === 0 ) return "" ;
115+
116+ try {
117+ await streamLoading ( stream , "Analyzing image..." ) ;
118+
119+ const extractionPromises = imageFiles . map ( ( file ) => extractImageData ( file . fileUrl ) ) ;
120+
121+ const extractionResults = await Promise . allSettled ( extractionPromises ) ;
122+
123+ const successfulData = extractionResults
124+ . filter ( ( result ) => result . status === "fulfilled" && result . value )
125+ . map ( ( result : any ) => result . value as string ) ;
126+
127+ if ( successfulData . length > 0 ) {
128+ return `\n\nExtracted information from attached images:\n${ successfulData . join ( "\n---\n" ) } \n\nUse this information if relevant when answering.` ;
129+ }
130+ } catch ( error ) {
131+ logger . error ( { message : "Failed to process attached images" , error } ) ;
132+ }
133+
134+ return "" ;
135+ }
136+
118137export async function handleGetAllChatMessages ( c : Context ) {
119138 const userId = c . get ( "user" ) ;
120139 const { chatId } = c . get ( "param" ) ;
@@ -124,6 +143,8 @@ export async function handleGetAllChatMessages(c: Context) {
124143 select : {
125144 id : true ,
126145 title : true ,
146+ ragStatus : true ,
147+ isRag : true ,
127148 messages : {
128149 orderBy : { createdAt : "asc" } ,
129150 select : {
0 commit comments