Initial ChatGPT Agent demo

This commit is contained in:
Rami Bitar
2026-09-14 19:49:51 -04:00
commit 8790cfb1e2
121 changed files with 20112 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
import {
streamText,
convertToModelMessages,
stepCountIs,
pruneMessages,
} from 'ai';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { tools } from '@/chat.config';
const openrouter = createOpenRouter({
apiKey: process.env.OPENROUTER_API_KEY,
});
export async function POST(request: Request) {
try {
const { messages } = await request.json();
if (!process.env.OPENROUTER_API_KEY) {
return Response.json(
{ error: 'OPENROUTER_API_KEY is not configured' },
{ status: 503 }
);
}
const model = openrouter(
process.env.OPENROUTER_MODEL || 'openai/gpt-5.6-luna-pro'
);
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 convertedMessages = await convertToModelMessages(messages);
const prunedMessages = pruneMessages({
messages: convertedMessages,
reasoning: 'all',
toolCalls: 'none',
});
const result = await streamText({
model,
instructions,
messages: prunedMessages,
tools: webSearchEnabled ? tools : {},
stopWhen: stepCountIs(20),
providerOptions: {
openrouter: {
reasoning: {
enabled: true,
effort: 'medium',
},
},
},
});
return result.toUIMessageStreamResponse({ sendReasoning: true });
} catch (error) {
console.error('Chat API error:', error);
return new Response(
JSON.stringify({ error: 'Failed to process chat request' }),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
}
);
}
}