import { apiError, apiJson } from "@/lib/api-handler"; import { resolveApiAuth } from "@/lib/api-auth"; import { getAssistantPreferences, resolveAssistantSystemPrompt } from "@/lib/assistant-preference"; import { isLlmConfigured } from "@/lib/llm"; import { listLlmModels, resolveAssistantModel } from "@/lib/llm/models"; import { clientChatInputSchema } from "@/modules/agent/messages"; import { encodeSseEvent } from "@/modules/agent/server/progress"; import { runAgentChat } from "@/modules/agent/server/run"; export async function POST(request: Request) { const auth = await resolveApiAuth(request); if (!auth?.userId) { return apiError("Unauthorized", 401); } const assistant = await getAssistantPreferences(auth.userId); if (!assistant.enabled) { return apiError("Assistant not enabled", 403); } const systemPrompt = resolveAssistantSystemPrompt(assistant.systemPrompt); let body: unknown; try { body = await request.json(); } catch { return apiError("Invalid JSON body", 400); } const parsed = clientChatInputSchema.safeParse(body); if (!parsed.success) { return apiError(parsed.error.issues[0]?.message ?? "Validation error", 400); } const modelList = await listLlmModels({ route: assistant.modelRoute }); const modelResolution = resolveAssistantModel({ requestedModel: parsed.data.model, savedModel: assistant.model, fallbackModel: modelList.fallbackModel, models: modelList.models, }); if (!modelResolution.ok) { return apiError(modelResolution.error, 400); } if (parsed.data.stream) { const stream = new ReadableStream({ async start(controller) { const encoder = new TextEncoder(); const send = (event: Parameters[0]) => { controller.enqueue(encoder.encode(encodeSseEvent(event))); }; try { const result = await runAgentChat({ messages: parsed.data.messages, request, systemPrompt, model: modelResolution.model, onProgress: send, }); send({ type: "done", message: { role: "assistant", content: result.message.content, }, toolCalls: result.toolCalls, }); } catch (err) { const message = err instanceof Error ? err.message : "Agent request failed"; send({ type: "error", message }); } finally { controller.close(); } }, }); return new Response(stream, { headers: { "Content-Type": "text/event-stream; charset=utf-8", "Cache-Control": "no-cache, no-transform", Connection: "keep-alive", }, }); } try { const result = await runAgentChat({ messages: parsed.data.messages, request, systemPrompt, model: modelResolution.model, }); return apiJson({ ...result, configured: isLlmConfigured(), provider: isLlmConfigured() ? "openai" : "mock", }); } catch (err) { const message = err instanceof Error ? err.message : "Agent request failed"; return apiError(message, 502); } }