@@ -38,62 +38,53 @@ function buildOpenAIChatPayload(messages: any[]) {
3838 } ;
3939}
4040
41- // Track initialized conversations to avoid re-initialization
42- const initializedConversations = new Set < string > ( ) ;
41+ // Context Aware RAG payload builder with initialization tracking
42+ const buildContextAwareRAGPayload = ( ( ) => {
43+ // Track initialized conversations to avoid re-initialization
44+ const initializedConversations = new Set < string > ( ) ;
45+
46+ return async ( messages : any [ ] , conversationId : string , chatCompletionURL : string ) => {
47+ if ( ! messages ?. length || messages [ messages . length - 1 ] ?. role !== 'user' ) {
48+ throw new Error ( 'User message not found: messages array is empty or invalid.' ) ;
49+ }
4350
44- function getBackendURL ( frontendURL : string ) : string {
45- // Map frontend endpoints to their backend equivalents
46- return frontendURL . replace ( / \/ c h a t \/ c a - r a g $ / , '/call' ) ;
47- }
51+ // Initialize the retrieval system only once per conversation
52+ // Combine RAG_UUID and conversation.id to create unique identifier
53+ const ragUuid = ( globalThis as any ) . process ?. env ?. RAG_UUID || '123456' ;
54+ const combinedConversationId = ` ${ ragUuid } - ${ conversationId || 'default' } ` ;
4855
49- async function initializeContextAwareRAG ( conversationId : string , chatCompletionURL : string ) {
50- // Initialize the retrieval system only once per conversation
51- // Combine RAG_UUID and conversation.id to create unique identifier
52- const ragUuid = ( globalThis as any ) . process ?. env ?. RAG_UUID || '123456' ;
53- const combinedConversationId = `${ ragUuid } -${ conversationId || 'default' } ` ;
54-
55- if ( ! initializedConversations . has ( combinedConversationId ) ) {
56- const initUrl = getBackendURL ( chatCompletionURL ) . replace ( '/call' , '/init' ) ;
57-
58- try {
59- const initResponse = await fetch ( initUrl , {
60- method : 'POST' ,
61- headers : { 'Content-Type' : 'application/json' } ,
62- body : JSON . stringify ( { uuid : ragUuid } ) ,
63- } ) ;
64-
65- if ( ! initResponse . ok ) {
66- console . log ( 'aiq - CA RAG initialization failed' , initResponse . status ) ;
67- throw new Error ( `CA RAG initialization failed: ${ initResponse . statusText } ` ) ;
68- }
56+ if ( ! initializedConversations . has ( combinedConversationId ) ) {
57+ const initUrl = chatCompletionURL . replace ( / \/ c h a t \/ c a - r a g $ / , '/init' ) ;
6958
70- const initData = await initResponse . json ( ) ;
71- console . log ( 'aiq - CA RAG initialization' , initData ?. status ) ;
59+ try {
60+ const initResponse = await fetch ( initUrl , {
61+ method : 'POST' ,
62+ headers : { 'Content-Type' : 'application/json' } ,
63+ body : JSON . stringify ( { uuid : ragUuid } ) ,
64+ } ) ;
65+
66+ if ( ! initResponse . ok ) {
67+ throw new Error ( `CA RAG initialization failed: ${ initResponse . statusText } ` ) ;
68+ }
7269
73- // Mark this conversation as initialized
74- initializedConversations . add ( combinedConversationId ) ;
75- } catch ( initError ) {
76- console . log ( 'aiq - CA RAG initialization error' , initError ) ;
77- throw new Error ( `CA RAG initialization failed: ${ initError instanceof Error ? initError . message : 'Unknown error' } ` ) ;
70+ // Mark this conversation as initialized
71+ initializedConversations . add ( combinedConversationId ) ;
72+ } catch ( initError ) {
73+ throw new Error ( `CA RAG initialization failed: ${ initError instanceof Error ? initError . message : 'Unknown error' } ` ) ;
74+ }
75+ } else {
76+ console . log ( 'aiq - CA RAG conversation already initialized' , combinedConversationId ) ;
7877 }
79- } else {
80- console . log ( 'aiq - CA RAG conversation already initialized' , combinedConversationId ) ;
81- }
82- }
83-
84- function buildContextAwareRAGPayload ( messages : any [ ] ) {
85- if ( ! messages ?. length || messages [ messages . length - 1 ] ?. role !== 'user' ) {
86- throw new Error ( 'User message not found: messages array is empty or invalid.' ) ;
87- }
8878
89- return {
90- state : {
91- chat : {
92- question : messages [ messages . length - 1 ] ?. content ?? ''
79+ return {
80+ state : {
81+ chat : {
82+ question : messages [ messages . length - 1 ] ?. content ?? ''
83+ }
9384 }
94- }
85+ } ;
9586 } ;
96- }
87+ } ) ( ) ;
9788
9889async function processGenerate ( response : Response ) : Promise < Response > {
9990 const data = await response . text ( ) ;
@@ -117,7 +108,6 @@ async function processChat(response: Response): Promise<Response> {
117108 try {
118109 const parsed = JSON . parse ( data ) ;
119110 const content =
120- parsed ?. result ||
121111 parsed ?. output ||
122112 parsed ?. answer ||
123113 parsed ?. value ||
@@ -132,6 +122,23 @@ async function processChat(response: Response): Promise<Response> {
132122 }
133123}
134124
125+ async function processContextAwareRAG ( response : Response ) : Promise < Response > {
126+ const data = await response . text ( ) ;
127+ try {
128+ const parsed = JSON . parse ( data ) ;
129+ const content =
130+ parsed ?. result ||
131+ ( Array . isArray ( parsed ?. choices )
132+ ? parsed . choices [ 0 ] ?. message ?. content
133+ : null ) ||
134+ parsed ||
135+ data ;
136+ return new Response ( typeof content === 'string' ? content : JSON . stringify ( content ) ) ;
137+ } catch {
138+ return new Response ( data ) ;
139+ }
140+ }
141+
135142async function processGenerateStream ( response : Response , encoder : TextEncoder , decoder : TextDecoder , additionalProps : any ) : Promise < ReadableStream < Uint8Array > > {
136143 const reader = response ?. body ?. getReader ( ) ;
137144 let buffer = '' ;
@@ -306,16 +313,22 @@ const handler = async (req: Request): Promise<Response> => {
306313 payload = buildGeneratePayload ( messages ) ;
307314 } else if ( chatCompletionURL . includes ( chatCaRagEndpoint ) ) {
308315 const conversationId = req . headers . get ( 'Conversation-Id' ) || '' ;
309- await initializeContextAwareRAG ( conversationId , chatCompletionURL ) ;
310- payload = buildContextAwareRAGPayload ( messages ) ;
316+ payload = await buildContextAwareRAGPayload ( messages , conversationId , chatCompletionURL ) ;
311317 } else {
312318 payload = buildOpenAIChatPayload ( messages ) ;
313319 }
314320 } catch ( err : any ) {
315321 return new Response ( err . message || 'Invalid request.' , { status : 400 } ) ;
316322 }
317323
318- const response = await fetch ( getBackendURL ( chatCompletionURL ) , {
324+ let backendURL = chatCompletionURL ;
325+ if ( chatCompletionURL . includes ( chatCaRagEndpoint ) ) {
326+ // Replace '/chat/ca-rag' with '/call' to get the backend URL. The Context Aware RAG backend
327+ // uses '/call' as its endpoint, which is too generic to use as the frontend endpoint here.
328+ backendURL = chatCompletionURL . replace ( / \/ c h a t \/ c a - r a g $ / , '/call' ) ;
329+ }
330+
331+ const response = await fetch ( backendURL , {
319332 method : 'POST' ,
320333 headers : {
321334 'Content-Type' : 'application/json' ,
@@ -338,6 +351,8 @@ const handler = async (req: Request): Promise<Response> => {
338351 return new Response ( await processGenerateStream ( response , encoder , decoder , additionalProps ) ) ;
339352 } else if ( chatCompletionURL . includes ( chatStreamEndpoint ) ) {
340353 return new Response ( await processChatStream ( response , encoder , decoder , additionalProps ) ) ;
354+ } else if ( chatCompletionURL . includes ( chatCaRagEndpoint ) ) {
355+ return await processContextAwareRAG ( response ) ;
341356 } else if ( chatCompletionURL . includes ( generateEndpoint ) ) {
342357 return await processGenerate ( response ) ;
343358 } else {
0 commit comments