Skip to content

Commit dd82205

Browse files
schwaaampclaude
andcommitted
Update admin dashboard for v3 batched AI narration diagnostics
The Narrate tab now correctly shows 'AI narration active (batched)' when the v3 pipeline runs with batch_ai mode. Handles both v2 (ai_calls count) and v3 (mode/ai_call_succeeded) diagnostic formats. Updated tooltips to reflect that observations are now AI-narrated alongside discoveries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 27cb04e commit dd82205

File tree

3 files changed

+48
-20
lines changed

3 files changed

+48
-20
lines changed

docs/planning/insight-engine-v3.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Insight Engine v3 — Dynamic Metric Discovery & Intraday Analysis
22

3-
**Status:** DEPLOYED — Phases 0-5 complete, blacklist seeded (212 entries), BH family correction live
3+
**Status:** DEPLOYED — Phases 0-5 complete, blacklist seeded (212 entries), BH family correction live, batched AI narration live (prompt v5.0)
44
**Author:** Claude Code / schwaaamp
55
**Date:** 2026-03-16
66
**Supersedes:** `pattern-spotter-v2-rewrite.md` (complete, deployed)
@@ -1591,7 +1591,13 @@ catch:
15911591
- `_shared/pattern-ranker.ts` — no changes needed
15921592
- All analyzer modules — no changes needed
15931593

1594-
**Estimated effort:** Medium — the batched prompt design and experiment matching logic are new. The narration infrastructure (imports, compliance, fallback) was built and reverted once already.
1594+
**Status: DONE (2026-03-19)**
1595+
- Batched AI narration live: single GPT-4o-mini call per pipeline run
1596+
- All discoveries and observations get plain-language titles and summaries
1597+
- OpenAI json_object wrapper format handled (extracts array from `{ "discoveries": [...] }`)
1598+
- Template fallback on AI failure — 21 vitest passing
1599+
- Admin dashboard updated to show v3 narration diagnostics (mode, patterns narrated, AI succeeded)
1600+
- Experiment matching NOT YET IMPLEMENTED — `suggested_experiment_id` still null (deferred to next iteration)
15951601

15961602
---
15971603

web/src/app/routes/admin/insights.$runId.tsx

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,16 @@ export default function InsightRunDetail() {
358358
all_candidates?: CandidateRow[];
359359
}) | undefined;
360360
const narrateDiag = diag.narrate as {
361+
// v2 fields
361362
ai_calls?: number;
362363
template_narratives?: number;
363364
model?: string;
364365
prompt_version?: string;
366+
// v3 fields (batched narration)
367+
mode?: 'batch_ai' | 'template_fallback';
368+
discoveries_narrated?: number;
369+
ai_call_succeeded?: boolean;
370+
template_fallback?: boolean;
365371
} | undefined;
366372
const persistDiag = diag.persist as Record<string, number> | undefined;
367373

@@ -1265,36 +1271,58 @@ export default function InsightRunDetail() {
12651271
<div>
12661272
<StepHeader
12671273
title="Narrate"
1268-
description="Generates user-facing titles and summaries. AI narration via GPT-4o-mini for discoveries, templates for observations."
1274+
description="Generates plain-language titles and summaries via a single batched GPT-4o-mini call for all discoveries and observations. Falls back to templates if AI call fails."
12691275
inputLabel={`Input: ${discoveriesCount + observationsCount} classified patterns from Filter`}
12701276
outputLabel={`Output: narrated patterns to Persist`}
12711277
/>
12721278

12731279
{/* AI Status Banner */}
12741280
{(() => {
1275-
const aiCalls = narrateDiag?.ai_calls ?? 0;
1276-
const isAiDisabled = aiCalls === 0;
1281+
// Support both v2 (ai_calls) and v3 (mode/ai_call_succeeded) diagnostics
1282+
const isV3 = narrateDiag?.mode != null;
1283+
const aiActive = isV3
1284+
? narrateDiag?.ai_call_succeeded === true
1285+
: (narrateDiag?.ai_calls ?? 0) > 0;
1286+
const narratedCount = isV3
1287+
? narrateDiag?.discoveries_narrated ?? 0
1288+
: narrateDiag?.ai_calls ?? 0;
1289+
const templateCount = isV3
1290+
? (narrateDiag?.template_fallback ? narrateDiag?.discoveries_narrated ?? 0 : 0)
1291+
: narrateDiag?.template_narratives ?? 0;
1292+
12771293
return (
12781294
<>
12791295
<div style={{
12801296
padding: "12px 16px",
12811297
borderRadius: "8px",
12821298
marginBottom: "16px",
1283-
background: isAiDisabled ? "rgba(234, 179, 8, 0.1)" : "rgba(34, 197, 94, 0.1)",
1284-
border: `1px solid ${isAiDisabled ? "var(--warning)" : "var(--success)"}`,
1285-
color: isAiDisabled ? "var(--warning)" : "var(--success)",
1299+
background: aiActive ? "rgba(34, 197, 94, 0.1)" : "rgba(234, 179, 8, 0.1)",
1300+
border: `1px solid ${aiActive ? "var(--success)" : "var(--warning)"}`,
1301+
color: aiActive ? "var(--success)" : "var(--warning)",
12861302
fontSize: "13px",
12871303
fontWeight: 500,
12881304
}}>
1289-
{isAiDisabled
1290-
? "AI NARRATION DISABLED \u2014 using template narratives for all patterns"
1291-
: `AI narration active \u2014 ${aiCalls} AI call${aiCalls !== 1 ? "s" : ""} made`}
1305+
{aiActive
1306+
? `AI narration active (batched) \u2014 ${narratedCount} pattern${narratedCount !== 1 ? "s" : ""} narrated`
1307+
: narrateDiag?.template_fallback
1308+
? "AI narration failed \u2014 using template fallback for all patterns"
1309+
: "AI narration disabled \u2014 using template narratives for all patterns"}
12921310
</div>
12931311

12941312
<div style={{ marginBottom: "20px", padding: "16px", background: "var(--bg-primary)", borderRadius: "8px" }}>
12951313
<div style={{ display: "flex", gap: "24px", flexWrap: "wrap" }}>
1296-
<StatChip label="AI Calls" value={aiCalls} />
1297-
<StatChip label="Template Narratives" value={narrateDiag?.template_narratives} />
1314+
{isV3 ? (
1315+
<>
1316+
<StatChip label="Mode" value={narrateDiag?.mode === 'batch_ai' ? 'Batched AI' : 'Template'} />
1317+
<StatChip label="Patterns Narrated" value={narratedCount} />
1318+
<StatChip label="AI Succeeded" value={aiActive ? 'Yes' : 'No'} />
1319+
</>
1320+
) : (
1321+
<>
1322+
<StatChip label="AI Calls" value={narrateDiag?.ai_calls ?? 0} />
1323+
<StatChip label="Template Narratives" value={templateCount} />
1324+
</>
1325+
)}
12981326
{narrateDiag?.model && (
12991327
<div>
13001328
<span style={{ color: "var(--text-dimmed)", fontSize: "12px" }}>Model</span>
@@ -1317,12 +1345,6 @@ export default function InsightRunDetail() {
13171345
{!narrateDiag && (
13181346
<div className="empty-state">No narrate diagnostics available (pipeline may have exited early)</div>
13191347
)}
1320-
1321-
{narrateDiag && aiCalls === 0 && (
1322-
<div style={{ fontSize: "13px", color: "var(--text-dimmed)", fontStyle: "italic" }}>
1323-
When AI narration is re-enabled: per-discovery narrative quality, token usage, latency per call
1324-
</div>
1325-
)}
13261348
</>
13271349
);
13281350
})()}

web/src/app/routes/admin/insights.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ export default function InsightsDashboard() {
341341
<th title="Total rows fetched across all 6 source tables (daily_summary, sleep_sessions, activities, glucose_data, glucose_alarms, intraday_data). Needs >= 14 to proceed.">Data Rows</th>
342342
<th title="Pattern candidates before BH correction → after. The arrow shows how many survived the Benjamini-Hochberg false discovery rate filter (alpha=0.10).">Candidates</th>
343343
<th title="Strong patterns (p < 0.05, |effect size| > 0.3) actually inserted into user_discoveries. Limited to 3 active + 2 per week.">Discoveries</th>
344-
<th title="Weaker patterns inserted as observations. Limited to 5 active + 3 per week. Use template narratives (no AI call).">Observations</th>
344+
<th title="Weaker patterns inserted as observations. Narrated by the same batched AI call as discoveries.">Observations</th>
345345
<th title="Data points outside plausibility bounds (e.g., HR > 220 bpm) that were excluded from analysis and flagged as data quality issues.">Outliers</th>
346346
<th title="Wall-clock time for the entire pipeline (fetch through persist) for this user.">Duration</th>
347347
<th title="Pipeline exit reason: 'success' = produced candidates, 'insufficient_data' = < 14 rows, 'no_candidates' = 0 passed significance test, 'no_bh_survivors' = all removed by BH correction, 'error' = exception thrown.">Status</th>

0 commit comments

Comments
 (0)