// --- // summary: self-contained HTML dashboard renderer for telemetry aggregates (no external assets or servers). // read_when: // - changing dashboard sections, styling, or the inline-data contract. // --- import type { TelemetrySummary } from "./aggregate.ts"; export interface DashboardMeta { generatedAt: number; windowDays: number; sourceDir: string; } export function renderTelemetryDashboard(summary: TelemetrySummary, meta: DashboardMeta): string { const generated = new Date(meta.generatedAt).toISOString(); const sections = [ kpis(summary), section( "compaction", "Compaction pressure", [ `
${barChart(summary.perDay, "events/day (all kinds)")}
`, `
${rows(summary.compaction.byReason.map((entry) => [entry.reason, String(entry.n)]))}
reasoncount
`, `
${rows(summary.compactionFailures.map((entry) => [entry.stage, String(entry.n), entry.topError ?? ""]))}
stagefailurestop error

emitted by the owning compaction extension; unresolved-begin counts remain the fallback signal

`, `
${rows([ ["total compactions", String(summary.compaction.total)], [ "avg summary chars", summary.compaction.avgSummaryChars === null ? "n/a" : String(summary.compaction.avgSummaryChars), ], [ "max summary chars", summary.compaction.maxSummaryChars === null ? "n/a" : String(summary.compaction.maxSummaryChars), ], ["unresolved begins (failed/aborted)", String(summary.compaction.unresolvedBegins)], [ "stalled after compaction (>10m idle)", String(summary.compaction.stalledAfterCompaction), ], ])}
metricvalue
`, ].join(""), ), section( "compaction-quality", "Compaction quality", [ `
${rows([ ["quality events", String(summary.compactionQuality.total)], [ "validation failures", `${summary.compactionQuality.validationFailures} (${summary.compactionQuality.validationFailureRatePct}%)`, ], [ "fallbacks", `${summary.compactionQuality.fallbacks} (${summary.compactionQuality.fallbackRatePct}%)`, ], [ "repairs", `${summary.compactionQuality.repairs} (${summary.compactionQuality.repairRatePct}%)`, ], [ "split turns", `${summary.compactionQuality.splitTurns} (${summary.compactionQuality.splitTurnRatePct}%)`, ], [ "verified worktree", `${summary.compactionQuality.worktreeVerified} (${summary.compactionQuality.worktreeVerifiedRatePct}%)`, ], ["message omission rate", `${summary.compactionQuality.messageOmissionRatePct}%`], ["avg compacted messages", nullable(summary.compactionQuality.avgCompactedMessages)], ["avg selected messages", nullable(summary.compactionQuality.avgSelectedMessages)], ["avg omitted messages", nullable(summary.compactionQuality.avgOmittedMessages)], ["avg continuity records", nullable(summary.compactionQuality.avgContinuityRecords)], ["avg evidence anchors", nullable(summary.compactionQuality.avgEvidenceAnchors)], ["avg duration ms", nullable(summary.compactionQuality.avgDurationMs)], ])}
metricvalue
`, `
${rows([ [ "omitted managed records", String(summary.compactionQuality.totalOmittedManagedRecords), ], ["omitted managed blocks", String(summary.compactionQuality.totalOmittedManagedBlocks)], ["redactions", String(summary.compactionQuality.totalRedactions)], ["truncated records", String(summary.compactionQuality.totalTruncatedRecords)], ["avg summary chars", nullable(summary.compactionQuality.avgSummaryChars)], ["avg input token budget", nullable(summary.compactionQuality.avgInputTokenBudget)], ["avg final token budget", nullable(summary.compactionQuality.avgFinalTokenBudget)], ])}
boundedness / safety metricvalue
`, `
${rows(summary.compactionQuality.byMode.map((entry) => [entry.mode, String(entry.n)]))}
modeevents
`, ].join(""), ), section( "recall", "Compaction recall", [ `
${rows([ ["recall calls", String(summary.recall.total)], ["hits returned", String(summary.recall.hits)], ["ranked hits", String(summary.recall.totalRankedHits)], ["zero-hit calls", `${summary.recall.zeroHit} (${summary.recall.zeroHitRatePct}%)`], [ "scope widened", `${summary.recall.scopeWidened} (${summary.recall.scopeWidenedRatePct}%)`, ], ["lineage degraded", `${summary.recall.degraded} (${summary.recall.degradedRatePct}%)`], ["source omission rate", `${summary.recall.sourceOmissionRatePct}%`], ["avg source entries", nullable(summary.recall.avgSourceEntries)], ["avg source entries omitted", nullable(summary.recall.avgSourceEntriesOmitted)], ["avg candidates", nullable(summary.recall.avgCandidates)], ["avg ranked hits", nullable(summary.recall.avgTotalHits)], ["avg page hits", nullable(summary.recall.avgHits)], ["avg expanded", nullable(summary.recall.avgExpanded)], ["avg direct refs", nullable(summary.recall.avgDirectRefs)], ["avg duration ms", nullable(summary.recall.avgDurationMs)], ])}
metricvalue
`, `
${rows(summary.recall.byMode.map((entry) => [entry.mode, String(entry.n)]))}
modecalls
`, `
${rows(summary.recall.byScope.map((entry) => [entry.scope, String(entry.n)]))}
scopecalls

metadata only: no query text, recalled content, file contents, or absolute paths are persisted

`, ].join(""), ), section( "tools", "Tool calls", `
${rows(summary.toolCalls.topFailing.map((entry) => [entry.tool, String(entry.n), entry.topError ?? ""]))}
toolfailurestop error signature

${summary.toolCalls.total} calls, ${summary.toolCalls.failed} failed (${summary.toolCalls.failureRatePct}%)

`, ), section( "vault", "Prompt Vault", `
${rows([ ["queries", String(summary.vault.total)], ["failed", String(summary.vault.failed)], ])}
metricvalue
`, ), section( "skills", "Skill loads", `
${rows(summary.skills.map((entry) => [entry.skill, String(entry.n)]))}
skillloads
`, ), section( "selfdriving", "Self-driving follow-ups", `
${rows([ ["total follow-up attempts", String(summary.followUps.total)], ["sent", String(summary.followUps.sent)], ["blocked", String(summary.followUps.blocked)], ])}
metricvalue
${rows(summary.followUps.byBlockedReason.map((entry) => [entry.reason, String(entry.n)]))}
blocked reasoncount
`, ), section( "subagents", "Subagents", `
${rows(summary.subagents.byProfile.map((entry) => [entry.profile, String(entry.n), String(entry.failed)]))}
profiledispatchesfailed

${summary.subagents.total} dispatches, ${summary.subagents.failed} failed

`, ), section( "raw", "Event kinds", `
${rows(summary.perKind.map((entry) => [entry.kind, String(entry.n)]))}
kindevents
`, ), ].join("\n"); const navigation = [ "compaction", "compaction-quality", "recall", "tools", "vault", "skills", "selfdriving", "subagents", "raw", ]; return ` Pi telemetry — last ${meta.windowDays}d

Pi telemetry

window ${meta.windowDays}d · generated ${generated} · source ${escapeHtml(meta.sourceDir)} · ${escapeHtml(provenance(summary))} · mirror-only observability, not authority

${sections}
`; } function provenance(summary: TelemetrySummary): string { if (summary.totalEvents === 0) { return "no data yet — run /telemetry backfill to seed history from session JSONL"; } const live = summary.sources.find((entry) => entry.source === "live")?.n ?? 0; const backfilled = summary.sources.find((entry) => entry.source === "backfill")?.n ?? 0; return `measured live ${live} · derived from history ${backfilled}`; } function kpis(summary: TelemetrySummary): string { const entries: Array<[string, string]> = [ ["events", String(summary.totalEvents)], ["compactions", String(summary.compaction.total)], ["quality fallbacks", String(summary.compactionQuality.fallbacks)], ["recall calls", String(summary.recall.total)], ["recall zero-hit", String(summary.recall.zeroHit)], ["stalled >10m", String(summary.compaction.stalledAfterCompaction)], ["tool failures", String(summary.toolCalls.failed)], ["vault queries", String(summary.vault.total)], ["follow-ups sent", String(summary.followUps.sent)], ["follow-ups blocked", String(summary.followUps.blocked)], ["subagents", String(summary.subagents.total)], ]; return `
${entries.map(([label, value]) => `
${escapeHtml(value)}${escapeHtml(label)}
`).join("")}
`; } function nullable(value: number | null): string { return value === null ? "n/a" : String(value); } function section(id: string, title: string, body: string): string { return `

${escapeHtml(title)}

${body}
`; } function rows(entries: Array>): string { if (entries.length === 0) { return `no data in window`; } return entries .map((entry) => `${entry.map((value) => `${escapeHtml(value)}`).join("")}`) .join(""); } function barChart(perDay: Array<{ day: string; n: number }>, label: string): string { if (perDay.length === 0) return `

no data in window

`; const max = Math.max(...perDay.map((entry) => entry.n), 1); const bars = perDay .map((entry) => { const height = Math.max(4, Math.round((entry.n / max) * 100)); return `
`; }) .join(""); return `
${bars}

${escapeHtml(label)} · ${perDay.length}d covered

`; } function escapeHtml(value: string): string { return value .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); }