Onboarding
This commit is contained in:
@@ -9,12 +9,13 @@ export interface OpenAiHealthIssue {
|
||||
details: string;
|
||||
}
|
||||
|
||||
export interface OpenAiHealthAnalysis {
|
||||
overallHealthScore: number;
|
||||
status: 'healthy' | 'watch' | 'critical';
|
||||
likelyIssues: OpenAiHealthIssue[];
|
||||
actionsNow: string[];
|
||||
plan7Days: string[];
|
||||
export interface OpenAiHealthAnalysis {
|
||||
overallHealthScore: number;
|
||||
status: 'healthy' | 'watch' | 'critical';
|
||||
analysisSummary?: string;
|
||||
likelyIssues: OpenAiHealthIssue[];
|
||||
actionsNow: string[];
|
||||
plan7Days: string[];
|
||||
}
|
||||
|
||||
const OPENAI_API_KEY = (process.env.EXPO_PUBLIC_OPENAI_API_KEY || '').trim();
|
||||
@@ -203,16 +204,18 @@ const buildHealthPrompt = (
|
||||
|
||||
return [
|
||||
`Analyze this plant photo for real health condition signs with focus on yellowing leaves, watering stress, pests, and light stress.`,
|
||||
`Return strict JSON only in this shape:`,
|
||||
`{"overallHealthScore":72,"status":"watch","likelyIssues":[{"title":"...","confidence":0.64,"details":"..."}],"actionsNow":["..."],"plan7Days":["..."]}`,
|
||||
`Return strict JSON only in this shape:`,
|
||||
`{"overallHealthScore":72,"status":"watch","analysisSummary":"...","likelyIssues":[{"title":"...","confidence":0.64,"details":"..."}],"actionsNow":["..."],"plan7Days":["..."]}`,
|
||||
`Rules:`,
|
||||
`- "overallHealthScore" must be an integer between 0 and 100.`,
|
||||
`- "status" must be one of: "healthy", "watch", "critical".`,
|
||||
`- "likelyIssues" must contain 1 to 4 items sorted by confidence descending.`,
|
||||
`- "analysisSummary" must be 6 to 9 precise sentences. Cover the visible condition, symptom pattern, likely root cause, urgency, what evidence is uncertain, and what the owner should monitor next.`,
|
||||
`- "likelyIssues" must contain 2 to 4 items sorted by confidence descending.`,
|
||||
`- "confidence" must be between 0 and 1.`,
|
||||
`- "title", "details", "actionsNow", and "plan7Days" must be written in ${getLanguageLabel(language)}.`,
|
||||
`- "actionsNow" should be immediate steps for the next 24 hours.`,
|
||||
`- "plan7Days" should be short actionable steps for the next week.`,
|
||||
`- "title", "details", "analysisSummary", "actionsNow", and "plan7Days" must be written in ${getLanguageLabel(language)}.`,
|
||||
`- Each issue "details" value must be 2 to 4 sentences and explain visual evidence, likely cause, and risk if untreated.`,
|
||||
`- "actionsNow" must contain 5 to 8 concrete steps for the next 24 to 48 hours.`,
|
||||
`- "plan7Days" must contain 7 to 10 day-by-day or milestone steps for the next week.`,
|
||||
`- Do not include markdown, explanations, or extra keys.`,
|
||||
...contextLines,
|
||||
].join('\n');
|
||||
@@ -229,9 +232,10 @@ const buildFallbackHealthAnalysis = (
|
||||
): OpenAiHealthAnalysis => {
|
||||
if (language === 'de') {
|
||||
return {
|
||||
overallHealthScore: 58,
|
||||
status: 'watch',
|
||||
likelyIssues: [
|
||||
overallHealthScore: 58,
|
||||
status: 'watch',
|
||||
analysisSummary: `${plantContext?.name || 'Die Pflanze'} braucht eine erneute Bewertung mit einem scharfen Foto, weil die KI-Antwort nicht stabil genug war. Behandle sie bis dahin vorsichtig als Beobachtungsfall. Vermeide radikale Standortwechsel, grosse Wassermengen und starke Duengung. Pruefe zuerst, ob die auffaelligen Blaetter weich, trocken, fleckig oder eingerollt wirken. Kontrolliere danach die oberen 3 cm Erde und achte auf stehendes Wasser im Uebertopf. Die wichtigsten sichtbaren Signale sollten bei Tageslicht erneut geprueft werden. Wenn sich Blattfarbe oder Spannung innerhalb von 48 Stunden verschlechtern, starte einen neuen Health-Scan mit einem detailreicheren Foto.`,
|
||||
likelyIssues: [
|
||||
{
|
||||
title: 'Eingeschraenkte KI-Analyse',
|
||||
confidence: 0.42,
|
||||
@@ -253,9 +257,10 @@ const buildFallbackHealthAnalysis = (
|
||||
|
||||
if (language === 'es') {
|
||||
return {
|
||||
overallHealthScore: 58,
|
||||
status: 'watch',
|
||||
likelyIssues: [
|
||||
overallHealthScore: 58,
|
||||
status: 'watch',
|
||||
analysisSummary: `${plantContext?.name || 'La planta'} necesita una nueva evaluacion con una foto mas nitida porque la respuesta de IA no fue suficientemente estable. Hasta entonces tratala como un caso de observacion. Evita cambios bruscos de ubicacion, exceso de agua y fertilizacion fuerte. Revisa si las hojas afectadas estan blandas, secas, manchadas o enrolladas. Comprueba despues los 3 cm superiores del sustrato y busca agua acumulada. Las senales visibles deben revisarse de nuevo con luz natural. Si el color o la firmeza empeoran en 48 horas, inicia otro health-scan con una foto mas detallada.`,
|
||||
likelyIssues: [
|
||||
{
|
||||
title: 'Analisis de IA limitado',
|
||||
confidence: 0.42,
|
||||
@@ -276,9 +281,10 @@ const buildFallbackHealthAnalysis = (
|
||||
}
|
||||
|
||||
return {
|
||||
overallHealthScore: 58,
|
||||
status: 'watch',
|
||||
likelyIssues: [
|
||||
overallHealthScore: 58,
|
||||
status: 'watch',
|
||||
analysisSummary: `${plantContext?.name || 'This plant'} needs another assessment with a sharper photo because the AI response was not stable enough. Until then, treat it as a watch case. Avoid major placement changes, heavy watering, or strong fertilizing. First inspect whether the unusual leaves look soft, dry, spotted, or curled. Then check the top 3 cm of soil and look for standing water in the outer pot. Re-check the visible signals in daylight before making bigger care changes. If color or leaf firmness gets worse within 48 hours, run a new health scan with a more detailed photo.`,
|
||||
likelyIssues: [
|
||||
{
|
||||
title: 'Limited AI analysis',
|
||||
confidence: 0.42,
|
||||
@@ -302,11 +308,12 @@ const normalizeHealthAnalysis = (
|
||||
raw: Record<string, unknown>,
|
||||
language: Language,
|
||||
): OpenAiHealthAnalysis | null => {
|
||||
const scoreRaw = getNumber(raw.overallHealthScore);
|
||||
const statusRaw = getString(raw.status);
|
||||
const issuesRaw = raw.likelyIssues;
|
||||
const actionsNowRaw = getStringArray(raw.actionsNow).slice(0, 6);
|
||||
const plan7DaysRaw = getStringArray(raw.plan7Days).slice(0, 7);
|
||||
const scoreRaw = getNumber(raw.overallHealthScore);
|
||||
const statusRaw = getString(raw.status);
|
||||
const analysisSummary = getString(raw.analysisSummary);
|
||||
const issuesRaw = raw.likelyIssues;
|
||||
const actionsNowRaw = getStringArray(raw.actionsNow).slice(0, 8);
|
||||
const plan7DaysRaw = getStringArray(raw.plan7Days).slice(0, 10);
|
||||
|
||||
if (scoreRaw == null || !statusRaw || !Array.isArray(issuesRaw)) {
|
||||
return null;
|
||||
@@ -340,9 +347,10 @@ const normalizeHealthAnalysis = (
|
||||
? 'La IA no pudo extraer senales de salud estables.'
|
||||
: 'AI could not extract stable health signals.';
|
||||
return {
|
||||
overallHealthScore: Math.round(clamp(scoreRaw, 0, 100)),
|
||||
status,
|
||||
likelyIssues: [
|
||||
overallHealthScore: Math.round(clamp(scoreRaw, 0, 100)),
|
||||
status,
|
||||
analysisSummary: analysisSummary || fallbackIssue,
|
||||
likelyIssues: [
|
||||
{
|
||||
title: language === 'de'
|
||||
? 'Analyse unsicher'
|
||||
@@ -363,9 +371,10 @@ const normalizeHealthAnalysis = (
|
||||
}
|
||||
|
||||
return {
|
||||
overallHealthScore: Math.round(clamp(scoreRaw, 0, 100)),
|
||||
status,
|
||||
likelyIssues,
|
||||
overallHealthScore: Math.round(clamp(scoreRaw, 0, 100)),
|
||||
status,
|
||||
analysisSummary,
|
||||
likelyIssues,
|
||||
actionsNow: actionsNowRaw,
|
||||
plan7Days: plan7DaysRaw,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user