fix(ai): correct env var names and fresh session per home modal open
AI route was reading LITELLM_URL/LITELLM_KEY but env vars are named LITELLM_BASE_URL/LITELLM_API_KEY — causing 503 on every request. Home page chat now creates a fresh session each time the modal opens and resets homeSessionId on close, so conversations don't pile into the same old session. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
299e878e38
commit
1628588d5a
2 changed files with 30 additions and 33 deletions
|
|
@ -3,8 +3,8 @@ import { sql } from "@/db";
|
||||||
import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers";
|
import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers";
|
||||||
import { logAudit } from "@/lib/audit";
|
import { logAudit } from "@/lib/audit";
|
||||||
|
|
||||||
const LITELLM_URL = process.env.LITELLM_URL;
|
const LITELLM_URL = process.env.LITELLM_BASE_URL;
|
||||||
const LITELLM_KEY = process.env.LITELLM_KEY;
|
const LITELLM_KEY = process.env.LITELLM_API_KEY;
|
||||||
|
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ export default function HomePage() {
|
||||||
const [aiInput, setAiInput] = useState("");
|
const [aiInput, setAiInput] = useState("");
|
||||||
const [aiChats, setAiChats] = useState<AIChat[]>([]);
|
const [aiChats, setAiChats] = useState<AIChat[]>([]);
|
||||||
const [aiLoading, setAiLoading] = useState(false);
|
const [aiLoading, setAiLoading] = useState(false);
|
||||||
|
const [homeSessionId, setHomeSessionId] = useState<string | null>(null);
|
||||||
const [pendingCount, setPendingCount] = useState(0);
|
const [pendingCount, setPendingCount] = useState(0);
|
||||||
const [lastLogs, setLastLogs] = useState<any[]>([]);
|
const [lastLogs, setLastLogs] = useState<any[]>([]);
|
||||||
const [vaccineReminders, setVaccineReminders] = useState<any[]>([]);
|
const [vaccineReminders, setVaccineReminders] = useState<any[]>([]);
|
||||||
|
|
@ -199,56 +200,52 @@ export default function HomePage() {
|
||||||
toggleTheme();
|
toggleTheme();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Unified AI chat that saves to sessions (database)
|
// Unified AI chat — creates a fresh session per modal open, reuses it for follow-ups
|
||||||
const handleAiChat = async (question?: string) => {
|
const handleAiChat = async (question?: string) => {
|
||||||
const q = question || aiInput;
|
const q = question || aiInput;
|
||||||
if (!q.trim() || aiLoading) return;
|
if (!q.trim() || aiLoading) return;
|
||||||
setAiLoading(true);
|
setAiLoading(true);
|
||||||
setAiOpen(true);
|
setAiOpen(true);
|
||||||
|
|
||||||
const sessions = await getSessions(childId);
|
|
||||||
let currentSession: ChatSession | null = sessions[0] || null;
|
|
||||||
|
|
||||||
// Create new session if none exists
|
|
||||||
if (!currentSession) {
|
|
||||||
currentSession = await createSession(childId);
|
|
||||||
if (currentSession) {
|
|
||||||
sessions.unshift(currentSession);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentSession) {
|
|
||||||
setAiLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const userMsg: AIChat = { id: crypto.randomUUID(), role: "user", content: q, createdAt: new Date().toISOString() };
|
|
||||||
const inputVal = q.trim();
|
const inputVal = q.trim();
|
||||||
if (!question) setAiInput("");
|
if (!question) setAiInput("");
|
||||||
|
|
||||||
|
// Reuse session within same modal open, or create fresh one
|
||||||
|
let sessionId = homeSessionId;
|
||||||
|
if (!sessionId) {
|
||||||
|
const newSession = await createSession(childId);
|
||||||
|
if (!newSession) { setAiLoading(false); return; }
|
||||||
|
sessionId = newSession.id;
|
||||||
|
setHomeSessionId(sessionId);
|
||||||
|
setAiChats([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optimistically show user message
|
||||||
|
const userMsg: AIChat = { id: "tmp-" + Date.now(), role: "user", content: inputVal, createdAt: new Date().toISOString() };
|
||||||
|
setAiChats(prev => [...prev, userMsg]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Save user message to DB
|
|
||||||
await fetch("/api/chat", {
|
await fetch("/api/chat", {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ sessionId: currentSession.id, role: "user", content: inputVal }),
|
body: JSON.stringify({ sessionId, role: "user", content: inputVal }),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get AI response
|
const res = await fetch("/api/ai", {
|
||||||
const res = await fetch("/api/ai", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ messages: [{ role: "user", content: inputVal }] }) });
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ messages: [{ role: "user", content: inputVal }] }),
|
||||||
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const reply = data.reply || "Sorry, I couldn't help with that.";
|
const reply = data.reply || "Sorry, I'm having trouble connecting. Please try again.";
|
||||||
|
|
||||||
// Save AI response to DB
|
|
||||||
await fetch("/api/chat", {
|
await fetch("/api/chat", {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ sessionId: currentSession.id, role: "assistant", content: reply }),
|
body: JSON.stringify({ sessionId, role: "assistant", content: reply }),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh sessions
|
setAiChats(prev => [...prev, { id: "ai-" + Date.now(), role: "assistant", content: reply, createdAt: new Date().toISOString() }]);
|
||||||
const updatedSessions = await getSessions(childId);
|
|
||||||
setAiChats(updatedSessions[0]?.messages || []);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("AI chat error:", err);
|
console.error("AI chat error:", err);
|
||||||
}
|
}
|
||||||
|
|
@ -335,10 +332,10 @@ export default function HomePage() {
|
||||||
|
|
||||||
<LogModal type={modalType} childId={childId} onClose={() => setModalType(null)} />
|
<LogModal type={modalType} childId={childId} onClose={() => setModalType(null)} />
|
||||||
|
|
||||||
{aiOpen && aiChats.length > 0 && (
|
{aiOpen && (
|
||||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" onClick={() => setAiOpen(false)}>
|
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" onClick={() => { setAiOpen(false); setHomeSessionId(null); }}>
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-2xl p-4 w-full max-w-sm mx-4 max-h-[80vh] flex flex-col" onClick={e => e.stopPropagation()}>
|
<div className="bg-white dark:bg-gray-800 rounded-2xl p-4 w-full max-w-sm mx-4 max-h-[80vh] flex flex-col" onClick={e => e.stopPropagation()}>
|
||||||
<div className="flex justify-between items-center mb-3"><h2 className="font-bold">Ask AI</h2><button onClick={() => setAiOpen(false)}>✕</button></div>
|
<div className="flex justify-between items-center mb-3"><h2 className="font-bold">Ask AI</h2><button onClick={() => { setAiOpen(false); setHomeSessionId(null); }}>✕</button></div>
|
||||||
<div className="flex-1 overflow-y-auto space-y-3 mb-3 min-h-[250px]">
|
<div className="flex-1 overflow-y-auto space-y-3 mb-3 min-h-[250px]">
|
||||||
{aiChats.map((chat) => (<div key={chat.id} className={`max-w-[85%] p-3 rounded-xl text-sm ${chat.role === "user" ? "ml-auto bg-rose-400 text-white" : "bg-rose-50 dark:bg-gray-700"}`}>{chat.content}</div>))}
|
{aiChats.map((chat) => (<div key={chat.id} className={`max-w-[85%] p-3 rounded-xl text-sm ${chat.role === "user" ? "ml-auto bg-rose-400 text-white" : "bg-rose-50 dark:bg-gray-700"}`}>{chat.content}</div>))}
|
||||||
{aiLoading && <div className="bg-rose-50 dark:bg-gray-700 p-3 rounded-xl text-sm animate-pulse">Thinking...</div>}
|
{aiLoading && <div className="bg-rose-50 dark:bg-gray-700 p-3 rounded-xl text-sm animate-pulse">Thinking...</div>}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue