import { json } from '@sveltejs/kit'; import { env } from '$env/dynamic/private'; import type { RequestHandler } from './$types'; type ChatRole = 'user' | 'assistant'; type ChatMessage = { role?: ChatRole; content?: string; }; type UnifiedState = { activeDomain?: 'fitness' | 'brain'; fitnessState?: Record; brainState?: Record; }; function recentMessages(messages: unknown): Array<{ role: ChatRole; content: string }> { if (!Array.isArray(messages)) return []; return messages .filter((message) => !!message && typeof message === 'object') .map((message) => { const item = message as ChatMessage; return { role: item.role === 'assistant' ? 'assistant' : 'user', content: typeof item.content === 'string' ? item.content : '' }; }) .filter((message) => message.content.trim()) .slice(-16); } function lastUserMessage(messages: Array<{ role: ChatRole; content: string }>): string { return [...messages].reverse().find((message) => message.role === 'user')?.content?.trim() || ''; } function isFitnessIntent(text: string): boolean { return /\b(calories?|protein|carbs?|fat|sugar|fiber|breakfast|lunch|dinner|snack|meal|food|ate|eaten|log|track|entries|macros?)\b/i.test(text) || /\bfor (breakfast|lunch|dinner|snack)\b/i.test(text) || /\bhow many calories do i have left\b/i.test(text); } function isBrainIntent(text: string): boolean { return /\b(note|notes|brain|remember|save this|save that|what do i have|what have i saved|find my|delete (?:that|this|note|item)|update (?:that|this|note)|from my notes)\b/i.test(text); } function detectDomain( messages: Array<{ role: ChatRole; content: string }>, state: UnifiedState, imageDataUrl?: string | null ): 'fitness' | 'brain' { const text = lastUserMessage(messages); if (imageDataUrl) return 'fitness'; if (!text) return state.activeDomain || 'brain'; const fitness = isFitnessIntent(text); const brain = isBrainIntent(text); if (fitness && !brain) return 'fitness'; if (brain && !fitness) return 'brain'; if (state.activeDomain === 'fitness' && !brain) return 'fitness'; if (state.activeDomain === 'brain' && !fitness) return 'brain'; return fitness ? 'fitness' : 'brain'; } export const POST: RequestHandler = async ({ request, fetch, cookies }) => { if (!cookies.get('platform_session')) { return json({ error: 'Unauthorized' }, { status: 401 }); } const { messages = [], state = {}, imageDataUrl = null, entryDate = null, action = 'chat', allowBrain = true } = await request .json() .catch(() => ({})); let brainEnabled = !!allowBrain; try { const gatewayUrl = env.GATEWAY_URL || 'http://localhost:8100'; const session = cookies.get('platform_session'); if (session) { const auth = await fetch(`${gatewayUrl}/api/auth/me`, { headers: { Cookie: `platform_session=${session}` } }); if (auth.ok) { const data = await auth.json().catch(() => null); if (data?.authenticated && data?.user?.username === 'madiha') { brainEnabled = false; } } } } catch { // keep requested allowBrain fallback } const chat = recentMessages(messages); const unifiedState: UnifiedState = state && typeof state === 'object' ? state : {}; const domain = brainEnabled ? detectDomain(chat, unifiedState, imageDataUrl) : 'fitness'; const response = await fetch(domain === 'fitness' ? '/assistant/fitness' : '/assistant/brain', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify( domain === 'fitness' ? { action, messages, draft: unifiedState.fitnessState && 'draft' in unifiedState.fitnessState ? unifiedState.fitnessState.draft : null, drafts: unifiedState.fitnessState && 'drafts' in unifiedState.fitnessState ? unifiedState.fitnessState.drafts : [], entryDate, imageDataUrl } : { messages, state: unifiedState.brainState || {} } ) }); const body = await response.json().catch(() => ({})); if (!response.ok) { return json(body, { status: response.status }); } return json({ ...body, domain, state: { activeDomain: domain, fitnessState: domain === 'fitness' ? { draft: body?.draft ?? null, drafts: Array.isArray(body?.drafts) ? body.drafts : [] } : unifiedState.fitnessState || {}, brainState: domain === 'brain' ? body?.state || {} : unifiedState.brainState || {} } }); };