(req: NextRequest)
| 19 | } |
| 20 | |
| 21 | export async function POST(req: NextRequest) { |
| 22 | const { messages } = (await req.json()) as { messages: ChatCompletionMessageParam[] }; |
| 23 | |
| 24 | const apiKey = process.env.LLM_API_KEY || process.env.OPENAI_API_KEY || ""; |
| 25 | const baseURL = process.env.LLM_BASE_URL || "https://api.openai.com/v1"; |
| 26 | const model = process.env.LLM_MODEL || "gpt-5.5"; |
| 27 | |
| 28 | if (!apiKey) { |
| 29 | return new Response( |
| 30 | JSON.stringify({ error: "Set LLM_API_KEY or OPENAI_API_KEY env var" }), |
| 31 | { status: 500 }, |
| 32 | ); |
| 33 | } |
| 34 | |
| 35 | const client = new OpenAI({ apiKey, baseURL }); |
| 36 | const stream = await client.chat.completions.create({ |
| 37 | model, |
| 38 | messages: [{ role: "system" as const, content: buildSystemPrompt() }, ...messages], |
| 39 | stream: true, |
| 40 | // reasoning: { effort: "low" }, |
| 41 | }); |
| 42 | |
| 43 | const encoder = new TextEncoder(); |
| 44 | const readable = new ReadableStream({ |
| 45 | async start(controller) { |
| 46 | try { |
| 47 | for await (const chunk of stream) { |
| 48 | controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunk)}\n\n`)); |
| 49 | } |
| 50 | } finally { |
| 51 | controller.enqueue(encoder.encode("data: [DONE]\n\n")); |
| 52 | controller.close(); |
| 53 | } |
| 54 | }, |
| 55 | }); |
| 56 | |
| 57 | return new Response(readable, { headers: SSE_HEADERS }); |
| 58 | } |
nothing calls this directly
no test coverage detected