From 7921ffc8e6f1f25a78eba3708390b4877b0a5e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 10 May 2026 19:20:50 +0200 Subject: [PATCH] fix(insights): wire generate route to strict prompt so dailyBriefing emits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The /api/insights/generate route was still calling the legacy getInsightsSystemPrompt that returns the v1.4.5 {changed, stable, drivers, …} shape and never asks the model for a dailyBriefing block. GROUND RULE 8 (emit dailyBriefing when the snapshot has signal) lives on getStrictInsightsSystemPrompt in src/lib/ai/prompts/insight- generator.ts; the route never adopted it. Re-runs from the hero strip therefore stored a payload with no briefing, the use-insights-advisor lift saw null, and the briefing card painted its empty state forever. Switch the route to getStrictInsightsSystemPrompt(locale). Existing strict-shape tolerance is unchanged: insightResultSchema.safeParse falls through to the raw parsed body on shape mismatch, and aiInsightResponseSchema's passthrough() keeps any custom keys for forward compat. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/app/api/insights/generate/route.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/api/insights/generate/route.ts b/src/app/api/insights/generate/route.ts index 7ce2885f7..428b4bcda 100644 --- a/src/app/api/insights/generate/route.ts +++ b/src/app/api/insights/generate/route.ts @@ -3,10 +3,10 @@ import { auditLog } from "@/lib/auth/audit"; import { apiSuccess, apiError, getClientIp } from "@/lib/api-response"; import { extractFeatures } from "@/lib/insights/features"; import { - getInsightsSystemPrompt, buildUserPrompt, type ComparisonSnapshot, } from "@/lib/insights/prompt"; +import { getStrictInsightsSystemPrompt } from "@/lib/ai/prompts/insight-generator"; import { summarize, type DataPoint } from "@/lib/analytics/trends"; import { resolveDashboardLayout, @@ -281,7 +281,18 @@ export const POST = apiHandler(async (request: NextRequest) => { userId, providers: chain, params: { - systemPrompt: getInsightsSystemPrompt(locale), + // The strict prompt (PROMPT_VERSION 4.20.x) carries GROUND RULE 8 + // — emit a top-level `dailyBriefing` block when the snapshot has + // analysable signal — plus the trendAnnotations / weeklyReport / + // storyboardAnnotations rules. The legacy `getInsightsSystemPrompt` + // returned the v1.4.5 `{changed, stable, drivers, …}` shape and + // never asked the model for dailyBriefing, so the hero strip's + // "Re-run analysis" button kept producing a payload with no + // briefing block (Issue 1, v1.4.20 post-deploy). The route already + // tolerates the strict shape via `insightResultSchema.safeParse`'s + // soft fallback to `parsed` and `passthrough()` on the strict + // schema, so switching the prompt does not break legacy callers. + systemPrompt: getStrictInsightsSystemPrompt(locale), userPrompt, temperature: 0.3, maxTokens: 1500,