import { NextResponse } from "next/server"; import { sql } from "@/db"; import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers"; import { logAudit } from "@/lib/audit"; const LITELLM_URL = process.env.LITELLM_BASE_URL; const LITELLM_KEY = process.env.LITELLM_API_KEY; export async function POST(request: Request) { try { // Check API key is configured if (!LITELLM_KEY) { return NextResponse.json({ error: "AI service not configured" }, { status: 503 }); } const body = await request.json(); const { messages, childId } = body; if (!messages || !Array.isArray(messages)) { return NextResponse.json({ error: "messages array required" }, { status: 400 }); } const lastUserMsg = [...messages].reverse().find(m => m.role === "user")?.content || ""; // HARD GUARDRAIL: Check for medical intent BEFORE calling LLM const intent = detectMedicalIntent(lastUserMsg); if (intent.isMedical) { // Fetch pediatrician phone const sessionToken = request.headers.get("cookie")?.match(/tia_session=([^;]+)/)?.[1] || ""; const families = await sql` SELECT pediatrician_phone FROM families WHERE id IN (SELECT family_id FROM family_members WHERE user_id IN (SELECT user_id FROM sessions WHERE session_token = ${sessionToken})) LIMIT 1 `; const pediatricianPhone = families[0]?.pediatrician_phone; const reply = [ `I can't interpret symptoms — that's a pediatrician's job, not mine.`, ``, ESCALATION_RULES[intent.category], ``, pediatricianPhone ? `Call your pediatrician now: ${pediatricianPhone}` : `Add your pediatrician's phone in Settings so I can show it here.`, ].join("\n"); // Audit log await logAudit({ action: "ai_medical_redirect", metadata: { category: intent.category, keyword: intent.matchedKeyword }, request, }); return NextResponse.json({ reply, redirected: true, category: intent.category, }); } // Get child's context let context = ""; if (childId) { const children = await sql.unsafe( `SELECT name, birth_date, sex FROM children WHERE id = $1`, [childId] ); if (children.length > 0) { const child = children[0]; const age = calculateAge(child.birth_date); context = `The child's name is ${child.name}, they are ${age} old. `; } } const systemMessage = { role: "system", content: `You are Tia, a friendly baby care assistant. STRICT RULES: - Never diagnose, interpret symptoms, or give medical advice - Never recommend medications, dosages, or treatments - If user describes symptoms, fever, rash, breathing issues — refuse and redirect to pediatrician - Provide only general educational info (developmental milestones, food intro, sleep patterns) - Always note "this is general info, not medical advice" - Keep responses under 200 words - Be warm but clinical`, }; // Call LiteLLM const response = await fetch(`${LITELLM_URL}/v1/chat/completions`, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${LITELLM_KEY}`, }, body: JSON.stringify({ model: "minimax-2.7", messages: [systemMessage, ...messages], max_tokens: 500, temperature: 0.3, }), }); if (!response.ok) { const error = await response.text(); return NextResponse.json({ error: error }, { status: response.status }); } const data = await response.json(); return NextResponse.json({ reply: data.choices?.[0]?.message?.content }); } catch (error) { console.error(error); return NextResponse.json({ error: String(error) }, { status: 500 }); } } function calculateAge(birthDate: string) { const birth = new Date(birthDate); const now = new Date(); const days = Math.floor((now.getTime() - birth.getTime()) / (1000 * 60 * 60 * 24)); const months = Math.floor(days / 30); const years = Math.floor(months / 12); if (years > 0) return `${years} year${years > 1 ? "s" : ""} old`; if (months > 0) return `${months} month${months > 1 ? "s" : ""} old`; return `${days} day${days > 1 ? "s" : ""} old`; }