Skip to content

Commit 23888f7

Browse files
committed
Follow endpoint pattern of build/process as two dedicated functions
1 parent 15baeae commit 23888f7

File tree

1 file changed

+67
-52
lines changed

1 file changed

+67
-52
lines changed

pages/api/chat.ts

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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(/\/chat\/ca-rag$/, '/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(/\/chat\/ca-rag$/, '/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

9889
async 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+
135142
async 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(/\/chat\/ca-rag$/, '/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

Comments
 (0)