(req: NextRequest)
| 46 | // ── Route handler ────────────────────────────────────────────────────────── |
| 47 | |
| 48 | export async function POST(req: NextRequest) { |
| 49 | const { prompt, messages } = await req.json(); |
| 50 | |
| 51 | const systemPrompt = getPrompt(); |
| 52 | |
| 53 | const chatMessages: Array<{ role: string; content: string }> = [ |
| 54 | { role: "system", content: systemPrompt }, |
| 55 | ]; |
| 56 | if (messages && Array.isArray(messages)) { |
| 57 | for (const m of messages) { |
| 58 | chatMessages.push({ role: m.role, content: m.content }); |
| 59 | } |
| 60 | } |
| 61 | chatMessages.push({ role: "user", content: prompt }); |
| 62 | |
| 63 | const apiKey = process.env.OPENROUTER_API_KEY; |
| 64 | if (!apiKey) { |
| 65 | return Response.json( |
| 66 | { error: { message: "OPENROUTER_API_KEY not configured" } }, |
| 67 | { status: 500 }, |
| 68 | ); |
| 69 | } |
| 70 | |
| 71 | const res = await fetch("https://openrouter.ai/api/v1/chat/completions", { |
| 72 | method: "POST", |
| 73 | headers: { |
| 74 | Authorization: `Bearer ${apiKey}`, |
| 75 | "Content-Type": "application/json", |
| 76 | "HTTP-Referer": `${BASE_URL}/demo/github`, |
| 77 | "X-Title": "OpenUI GitHub Demo", |
| 78 | }, |
| 79 | body: JSON.stringify({ |
| 80 | model: GITHUB_DEMO_MODEL, |
| 81 | stream: true, |
| 82 | messages: chatMessages, |
| 83 | }), |
| 84 | signal: req.signal, |
| 85 | }); |
| 86 | |
| 87 | if (!res.ok) { |
| 88 | const err = await res.json().catch(() => ({})); |
| 89 | if (isDemoCreditsExhaustedError(err, res.status)) { |
| 90 | return createDemoCreditsExhaustedResponse(); |
| 91 | } |
| 92 | |
| 93 | return Response.json( |
| 94 | { |
| 95 | error: (err as { error?: { message?: string } }).error ?? { |
| 96 | message: `OpenRouter error ${res.status}`, |
| 97 | }, |
| 98 | }, |
| 99 | { status: res.status }, |
| 100 | ); |
| 101 | } |
| 102 | |
| 103 | // Keep credit handling to provider 4xx responses. Provider-specific mid-stream |
| 104 | // error chunks are intentionally passed through because they are harder to |
| 105 | // maintain across OpenRouter/OpenAI streaming shape changes. |
nothing calls this directly
no test coverage detected