feat(routines): enrich single AI suggestions with concise context

This commit is contained in:
Piotr Oleszczyk 2026-03-04 01:22:57 +01:00
parent 083cd055fb
commit 820d58ea37
5 changed files with 113 additions and 8 deletions

View file

@ -171,6 +171,10 @@
"suggest_errorSave": "Error saving.",
"suggest_amMorning": "AM (morning)",
"suggest_pmEvening": "PM (evening)",
"suggest_summaryPrimaryGoal": "Primary goal",
"suggest_summaryConfidence": "Confidence",
"suggest_summaryConstraints": "Constraints",
"suggest_stepOptionalBadge": "optional",
"medications_title": "Medications",
"medications_count": "{count} entries",

View file

@ -171,6 +171,10 @@
"suggest_errorSave": "Błąd podczas zapisywania.",
"suggest_amMorning": "AM (rano)",
"suggest_pmEvening": "PM (wieczór)",
"suggest_summaryPrimaryGoal": "Główny cel",
"suggest_summaryConfidence": "Pewność",
"suggest_summaryConstraints": "Ograniczenia",
"suggest_stepOptionalBadge": "opcjonalny",
"medications_title": "Leki",
"medications_count": "{count} wpisów",

View file

@ -224,11 +224,20 @@ export interface SuggestedStep {
action_notes?: string;
dose?: string;
region?: string;
why_this_step?: string;
optional?: boolean;
}
export interface RoutineSuggestionSummary {
primary_goal: string;
constraints_applied: string[];
confidence: number;
}
export interface RoutineSuggestion {
steps: SuggestedStep[];
reasoning: string;
summary?: RoutineSuggestionSummary;
}
export interface DayPlan {

View file

@ -45,7 +45,7 @@
function stepMeta(step: SuggestedStep): string {
const parts: string[] = [];
if (step.dose) parts.push(step.dose);
if (step.region) parts.push(step.region);
if (step.region && step.region.toLowerCase() !== 'face') parts.push(step.region);
if (step.action_notes && !step.action_type) parts.push(step.action_notes);
return parts.join(' · ');
}
@ -209,6 +209,20 @@
</CardContent>
</Card>
{#if suggestion.summary}
<Card class="border-muted bg-muted/30">
<CardContent class="space-y-2 pt-4">
<p class="text-sm"><span class="font-medium">{m["suggest_summaryPrimaryGoal"]()}:</span> {suggestion.summary.primary_goal || '—'}</p>
<p class="text-sm"><span class="font-medium">{m["suggest_summaryConfidence"]()}:</span> {Math.round((suggestion.summary.confidence ?? 0) * 100)}%</p>
{#if suggestion.summary.constraints_applied?.length}
<p class="text-xs text-muted-foreground">
{m["suggest_summaryConstraints"]()}: {suggestion.summary.constraints_applied.join(' · ')}
</p>
{/if}
</CardContent>
</Card>
{/if}
<!-- Steps -->
<div class="space-y-2">
{#each suggestion.steps as step, i (i)}
@ -217,10 +231,18 @@
{i + 1}
</span>
<div class="min-w-0 flex-1">
<p class="text-sm font-medium">{stepLabel(step)}</p>
<div class="flex items-center gap-2">
<p class="text-sm font-medium">{stepLabel(step)}</p>
{#if step.optional}
<Badge variant="secondary">{m["suggest_stepOptionalBadge"]()}</Badge>
{/if}
</div>
{#if stepMeta(step)}
<p class="text-xs text-muted-foreground">{stepMeta(step)}</p>
{/if}
{#if step.why_this_step}
<p class="text-xs text-muted-foreground italic">{step.why_this_step}</p>
{/if}
</div>
</div>
{/each}