diff --git a/src/__tests__/background-reasoning-inventory.test.ts b/src/__tests__/background-reasoning-inventory.test.ts index 8b1c78cd9..cafb8bf61 100644 --- a/src/__tests__/background-reasoning-inventory.test.ts +++ b/src/__tests__/background-reasoning-inventory.test.ts @@ -41,6 +41,10 @@ const ADMITTED: Record = { jobs: ["daily_briefing"], why: "The daily briefing's generation and its phrasing re-roll; the JSON and grounding repairs do not reason.", }, + "app/api/insights/generate/route.ts": { + jobs: ["daily_briefing"], + why: "A briefing asked for by hand reasons like the scheduled one; its JSON and grounding repairs do not.", + }, "lib/insights/narrative/period-narrative-generate.ts": { jobs: ["period_narrative_month", "period_narrative_week"], why: "The weekly and monthly narratives' first pass; the grounding repair does not reason.", diff --git a/src/app/api/insights/generate/route.ts b/src/app/api/insights/generate/route.ts index f19736286..3668e2443 100644 --- a/src/app/api/insights/generate/route.ts +++ b/src/app/api/insights/generate/route.ts @@ -795,6 +795,9 @@ export const POST = apiHandler((request: NextRequest) => // v1.25 — honours the per-user response-timeout setting. timeoutMs: effectiveTimeoutMs, stage: "generate", + // v1.41 — a briefing asked for by hand reasons exactly like the + // scheduled one; the retries below repair a reply and do not. + reasoningJob: "daily_briefing", }); result = fallback.result; workingProviderType = fallback.workingProvider.providerType; diff --git a/src/lib/ai/coach/__tests__/contract-keys.test.ts b/src/lib/ai/coach/__tests__/contract-keys.test.ts index aa616b0f0..d5ef9ecb5 100644 --- a/src/lib/ai/coach/__tests__/contract-keys.test.ts +++ b/src/lib/ai/coach/__tests__/contract-keys.test.ts @@ -120,8 +120,9 @@ describe("v1.41 contract keys", () => { it("produces the whole catalog", () => { // Every key laid down for the release but the `change_assumption` chip - // label, which the dialog catalog's own test covers. - expect(keys.size).toBe(57); + // label, which the dialog catalog's own test covers, plus the two + // declined-proposal replies. + expect(keys.size).toBe(59); }); it.each(locales)("every catalog key resolves in %s", (locale) => { diff --git a/src/lib/ai/coach/clarify.ts b/src/lib/ai/coach/clarify.ts index 7a6014693..3b12191c9 100644 --- a/src/lib/ai/coach/clarify.ts +++ b/src/lib/ai/coach/clarify.ts @@ -48,6 +48,7 @@ import { } from "@/lib/ai/coach/types"; import { coachClarificationSchema } from "@/lib/ai/coach/stream-events"; import { + COACH_CLARIFY_UI_KEYS, COACH_FOLLOW_UP_KEYS, clarifyWindowLabelKey, coachDomainLabelKey, @@ -439,12 +440,11 @@ export const CLARIFY_DAILY_LIMIT = 3; const COMPARISON_LABEL_KEY: Readonly> = { previous_period: COACH_FOLLOW_UP_KEYS.previous_period, year_ago: COACH_FOLLOW_UP_KEYS.year_ago, - // Pending until integration copies it into the bundles. - baseline_90d: "coach.clarify.comparison.baseline90d", + baseline_90d: COACH_CLARIFY_UI_KEYS.comparisonBaseline90d, }; -/** A pending key: "Since {date}", an illness episode as an anchor. */ -const ANCHOR_ILLNESS_KEY = "coach.clarify.anchor.illness"; +/** "Since {date}", an illness episode as an anchor. */ +const ANCHOR_ILLNESS_KEY = COACH_CLARIFY_UI_KEYS.anchorIllness; /** A choice the server built from the record: an id and a catalog label. */ export interface ClarifyRecordChoice { diff --git a/src/lib/ai/coach/dialog-keys.ts b/src/lib/ai/coach/dialog-keys.ts index 6265772e2..49e74793f 100644 --- a/src/lib/ai/coach/dialog-keys.ts +++ b/src/lib/ai/coach/dialog-keys.ts @@ -247,6 +247,8 @@ export const COACH_CLARIFY_UI_KEYS = { choicesLabel: "coach.clarify.choicesLabel", freeTextHint: "coach.clarify.freeTextHint", contextHint: "coach.clarify.contextHint", + comparisonBaseline90d: "coach.clarify.comparison.baseline90d", + anchorIllness: "coach.clarify.anchor.illness", } as const; /** A window choice on a clarification card ("Last 30 days"). */ diff --git a/src/lib/ai/coach/memory/shared.ts b/src/lib/ai/coach/memory/shared.ts index a045dd1ce..9db299692 100644 --- a/src/lib/ai/coach/memory/shared.ts +++ b/src/lib/ai/coach/memory/shared.ts @@ -61,6 +61,7 @@ export const COACH_MEMORY_KEYS = { accept: "insights.coach.memory.accept", decline: "insights.coach.memory.decline", confirmed: "insights.coach.memory.confirmed", + declined: "insights.coach.memory.declined", } as const; /** A plan proposal's two replies, and the line a decision turn answers with. */ @@ -68,6 +69,7 @@ export const COACH_PLAN_KEYS = { accept: "insights.coach.plan.accept", decline: "insights.coach.plan.decline", confirmed: "insights.coach.plan.confirmed", + declined: "insights.coach.plan.declined", } as const; /** The memory list in settings, and the link to it from the Coach. */ diff --git a/src/lib/ai/coach/turn/reuse-turn.ts b/src/lib/ai/coach/turn/reuse-turn.ts index 993e3988d..69f7e5624 100644 --- a/src/lib/ai/coach/turn/reuse-turn.ts +++ b/src/lib/ai/coach/turn/reuse-turn.ts @@ -214,13 +214,10 @@ export async function runReuseTurn(args: { return new Response(stream, { status: 200, headers: SSE_HEADERS }); } -/** - * The reply a declined proposal gets. Pending keys: integration copies them - * into the bundles with the rest of this release's strings. - */ +/** The reply a declined proposal gets. */ export const COACH_DECISION_DECLINED_KEYS = { - memory: "insights.coach.memory.declined", - plan: "insights.coach.plan.declined", + memory: COACH_MEMORY_KEYS.declined, + plan: COACH_PLAN_KEYS.declined, } as const; /** The stored note and plan of a message, each held to its wire schema. */