156
services/ollamaService.ts
Normal file
156
services/ollamaService.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
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<string[]> => {
|
||||
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<string> => {
|
||||
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.";
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user