feat(insights): fold a confidence-gated derived signal into the daily briefing

When a derived wellness score (readiness or recovery) crosses a notability gate
— outside the green band AND confidence at least medium — the insights
generator now appends a SYSTEM CONTEXT block so the briefing can narrate the
shift observationally. Mirrors the GLP-1 plateau detector's append mechanism:
reads the one derived contract, returns null (the common case) at zero token
cost, and instructs the model to frame the signal as an observed pattern, never
a diagnosis or a dose recommendation. Add the readiness/recovery sourceMetric
enum values plus their briefing href + icon + trend-chart mappings.
This commit is contained in:
Marc-André Bombeck committed 2026-06-02 23:13:26 +02:00
1 parent 8c24f3ec2a
commit 78c8177cd3
6 files changed
+282

No files matched your search

+24
View File
@@ -11,6 +11,11 @@ import {
detectGlp1Plateau,
buildGlp1PlateauPrompt,
} from "@/lib/insights/glp1-plateau";
import {
detectDerivedBriefingSignals,
buildDerivedBriefingPrompt,
} from "@/lib/insights/derived-briefing";
import { getAgeFromDateOfBirth } from "@/lib/analytics/pulse-targets";
import {
buildUserPrompt,
type ComparisonSnapshot,
@@ -199,6 +204,10 @@ export const POST = apiHandler(async (request: NextRequest) => {
// LLM never sees the excluded blocks.
insightsExcludeMetrics: true,
locale: true,
// v1.10.0 — profile for the derived-signal briefing detector.
dateOfBirth: true,
gender: true,
heightCm: true,
},
});
@@ -397,6 +406,21 @@ export const POST = apiHandler(async (request: NextRequest) => {
if (plateauContext) {
userPrompt += buildGlp1PlateauPrompt(plateauContext, locale);
}
// v1.10.0 — fold a notable derived wellness signal (readiness / recovery
// shift, confidence-gated) into the briefing as a SYSTEM CONTEXT block.
// Reads the one derived contract; null (the common case) costs nothing.
const derivedSex =
dbUser?.gender === "MALE" || dbUser?.gender === "FEMALE"
? (dbUser.gender as "MALE" | "FEMALE")
: null;
const derivedBriefing = await detectDerivedBriefingSignals(userId, {
ageYears: getAgeFromDateOfBirth(dbUser?.dateOfBirth ?? null),
sex: derivedSex,
heightCm: dbUser?.heightCm ?? null,
});
if (derivedBriefing) {
userPrompt += buildDerivedBriefingPrompt(derivedBriefing, locale);
}
let result;
let workingProviderType: string;