Improve chat navigation, model selection, and streaming

This commit is contained in:
Rami Bitar
2026-09-16 13:14:55 -04:00
parent 8790cfb1e2
commit dd04493e25
73 changed files with 1272 additions and 1367 deletions
+23 -30
View File
@@ -4,16 +4,20 @@ import {
stepCountIs,
pruneMessages,
} from 'ai';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { tools } from '@/chat.config';
import { getChatModel } from '@/services/chat/model';
import { getChatInstructions } from '@/services/chat/instructions';
import { chatTools } from '@/services/chat/tools';
import { isOpenRouterModelId } from '@/lib/openrouter';
const openrouter = createOpenRouter({
apiKey: process.env.OPENROUTER_API_KEY,
});
export const maxDuration = 300;
export async function POST(request: Request) {
try {
const { messages } = await request.json();
const { messages, modelId } = await request.json();
if (modelId !== undefined && !isOpenRouterModelId(modelId)) {
return Response.json({ error: 'Select a supported model' }, { status: 400 });
}
if (!process.env.OPENROUTER_API_KEY) {
return Response.json(
@@ -22,30 +26,11 @@ export async function POST(request: Request) {
);
}
const model = openrouter(
process.env.OPENROUTER_MODEL || 'openai/gpt-5.6-luna-pro'
);
const model = getChatModel(modelId);
const webSearchEnabled = Boolean(process.env.FIRECRAWL_API_KEY);
const instructions = webSearchEnabled
? `You are an expert ChatGPT Agent with real-time access to the internet.
Your capabilities:
- Search the web using Firecrawl to find up-to-date information
- Fetch and read full web pages to extract detailed content
- Synthesize information from multiple sources into clear, accurate answers
- Cite your sources inline so the user can verify information
Guidelines:
- Always search the web before answering questions that require current or factual information
- Use multiple searches when needed to get comprehensive answers
- Cross-reference sources for accuracy
- Structure your responses clearly with headings, bullet points, and citations where appropriate
- When fetching pages, extract only the relevant information
- Be transparent about the sources you used
- Today's date is ${new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}`
: `You are a helpful AI research assistant. Answer clearly and accurately. You do not have live web access, so be transparent when a question requires current information. Today's date is ${new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}.`;
const instructions = getChatInstructions(webSearchEnabled);
const convertedMessages = await convertToModelMessages(messages);
@@ -55,12 +40,16 @@ Guidelines:
toolCalls: 'none',
});
const result = await streamText({
const result = streamText({
model,
instructions,
messages: prunedMessages,
tools: webSearchEnabled ? tools : {},
abortSignal: request.signal,
tools: webSearchEnabled ? chatTools : {},
stopWhen: stepCountIs(20),
onError: ({ error }) => {
if (!request.signal.aborted) console.error('Chat stream error:', error);
},
providerOptions: {
openrouter: {
reasoning: {
@@ -71,7 +60,11 @@ Guidelines:
},
});
return result.toUIMessageStreamResponse({ sendReasoning: true });
return result.toUIMessageStreamResponse({
sendReasoning: true,
headers: { 'Cache-Control': 'no-cache, no-transform' },
onError: () => 'The response was interrupted. Please try again.',
});
} catch (error) {
console.error('Chat API error:', error);
return new Response(