import { CalendarEvent, EventCategory, AppSettings } from '../types'; import { v4 as uuidv4 } from 'uuid'; interface OllamaResponse { model: string; created_at: string; response: string; done: boolean; } export const generateOllamaResponse = async ( prompt: string, settings: AppSettings, userRole: string ): Promise<{ text: string; event?: CalendarEvent }> => { const url = `${settings.ollamaUrl}/api/generate`; const currentDate = new Date(); const systemPrompt = ` You are a mystical calendar oracle for a couple. Current Date: ${currentDate.toISOString()} User Role: ${userRole} Output JSON ONLY. If user wants an event: { "isEvent": true, "title": "string", "description": "string", "startTime": "ISO 8601 string", "endTime": "ISO 8601 string", "category": "general" | "chore" | "date" | "work" | "fun" | "magic" } If chatting: { "isEvent": false, "message": "your magical response here" } `; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: settings.ollamaModel, prompt: `${systemPrompt}\n\nUser: ${prompt}`, stream: false, format: "json" }) }); if (!response.ok) throw new Error(`Ollama Error`); const data: OllamaResponse = await response.json(); const resultText = data.response; const parsed = JSON.parse(resultText); if (parsed.isEvent) { const newEvent: CalendarEvent = { id: uuidv4(), title: parsed.title, description: parsed.description, startTime: parsed.startTime, endTime: parsed.endTime, category: parsed.category || 'general', createdBy: userRole as any }; return { text: `The stars have aligned for "${parsed.title}".`, event: newEvent }; } else { return { text: parsed.message || "The spirits are quiet." }; } } catch (error) { console.error("Ollama Error", error); return { text: "I cannot reach the local spirit realm (Ollama)." }; } }; export const analyzeScheduleAndSuggest = async ( events: CalendarEvent[], settings: AppSettings ): Promise => { if (!settings.ollamaUrl) return ["The oracle is disconnected."]; const eventsSummary = events.map(e => `- ${e.title} (${e.category}) on ${e.startTime.split('T')[0]}` ).join('\n'); const prompt = ` Analyze this couple's schedule: ${eventsSummary} Based on these events, suggest 3 specific, thoughtful, or fun additional events they should add to balance their life. Look for missing date nights, overwhelming work blocks, or chores that need doing. Return ONLY a JSON array of 3 strings. `; try { const response = await fetch(`${settings.ollamaUrl}/api/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: settings.ollamaModel, prompt: prompt, stream: false, format: "json" }) }); if (!response.ok) return ["Plan a surprise dinner!", "Go for a moonlit walk.", "Cook a meal together."]; const data = await response.json(); const parsed = JSON.parse(data.response); return Array.isArray(parsed) ? parsed : ["Plan a surprise dinner!", "Go for a moonlit walk.", "Cook a meal together."]; } catch (e) { return ["Plan a surprise dinner!", "Go for a moonlit walk.", "Cook a meal together."]; } }; export const generateDailyHoroscope = async ( momSign: string, dadSign: string, settings: AppSettings ): Promise => { if (!settings.ollamaUrl) return "Stars are silent today."; const currentDate = new Date().toDateString(); const prompt = ` Generate a very short, mystical horoscope prediction (max 10 words) for a couple with signs ${momSign} and ${dadSign} for today, ${currentDate}. Focus on their shared energy or love. Return JSON: { "prediction": "string" } `; try { const response = await fetch(`${settings.ollamaUrl}/api/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: settings.ollamaModel, prompt: prompt, stream: false, format: "json" }) }); if (!response.ok) return "Cosmic energy flows."; const data = await response.json(); const parsed = JSON.parse(data.response); return parsed.prediction || "Alignment looks favorable."; } catch (e) { console.error("Horoscope gen failed", e); return "Magic is in the air."; } };