Skip to content

fix(agent-sessions): normalise GenAI usage, cost, TTFT and agent name at ingest - #1123

Closed
JeremyFunk wants to merge 19 commits into
mainfrom
fix/agent-sessions-usage-keys
Closed

JeremyFunk wants to merge 19 commits into
mainfrom
fix/agent-sessions-usage-keys

fix(agent-sessions): rebuild ai_trace_index_mv on the canonical usage…

8db109d
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review completed Sep 29, 2026 in 5m 18s

Confidence 3/5 · 1 issue to address

Confidence 3/5 · needs attention
The ingest restatement and the migration are view-only and well tested, but the read path now mis-carves spans that were stamped before the deploy.
quality 88/100 · 1 warning · 1 note · tests covered · risk medium

Ingest now restates every AI span's usage, cost, TTFT and agent name under one canonical gen_ai.* key, and the index view, integrations and detail page stop asking the vendor/provider usage convention. The migration and local-schema step only recreate the view, but the live read path will mis-count spans already in traces until they age out.

  • canonical.rs restates usage, cost, TTFT and agent name under canonical gen_ai.* keys at ingest.
  • ai_trace_index_mv, spanTokenBuckets and the integrations drop the vendor/provider usage conventions.
  • openrouter is judged cache-inclusive, claude_agent_sdk cache-exclusive; anthropic takes the nesting default.
  • Local schema v26 recreates the view, keeping existing rows' v25 values.

Findings

Warning · F1 · Detail page under-counts tokens for spans ingested before the deploy

correctness · packages/agent-sessions/src/session-summary.ts:466

spanTokenBuckets now carves both cache buckets out of the prompt figure unconditionally, which is only correct once ingest has folded them in. Spans already in traces were stamped by the old gateway, so a Claude Code (claude_agent_sdk) span still carries Anthropic's exclusive gen_ai.usage.input_tokens: for raw input_tokens: 5000 with cache_read: 1000 the detail page and get_agent_session show 5000 instead of 6000, because the 1000 is subtracted from a figure that never held it. The index rows keep their v25 Tokens, so for the 30-day window the list and the detail page disagree — the opposite of what the change sets out to fix.

The pre-deploy rows are indistinguishable from restated ones at read time, so either state the dip in migration 0035 and the `local-schema-history` v26 entry (they only mention the index's stale values), or have `canonical::normalize` leave a marker the readers can test before carving.
Note · F2 · local-0025-to-0026 step ships the bump generator's TODO scaffolding

maintainability · apps/cli/src/server/local-store-migrations/steps.ts:1118-1121

The row is complete — beforeBootstrap, plan, verifies and dispositions are all filled — but the appended comment still tells the next reader the row is unfinished and that "the v26 physical verify fails an unfinished row". Every earlier step in this file carries no such block.

	{
		// Only the view's SELECT changes; existing index rows keep their v25 values.
		id: "local-0025-to-0026-ai-trace-index-usage-keys",
		from: 25,
		to: 26,
What was checked
  • Migration 0035 and step v25→v26 recreate the view only, no row rewritten (steps.ts:1128).
  • No readers of the removed exports remain (genAiUsageConvention, GENAI_LEGACY_ALIASES).
  • The detail-page SQL still projects the canonical keys its mapper reads (ai-sessions.ts:1357).

8db109d · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple to ask about one.

Annotations

Check warning on line 466 in packages/agent-sessions/src/session-summary.ts

See this annotation in the file changed.

@maple-review-bot maple-review-bot / Maple / review

correctness: Detail page under-counts tokens for spans ingested before the deploy

`spanTokenBuckets` now carves both cache buckets out of the prompt figure unconditionally, which is only correct once ingest has folded them in. Spans already in `traces` were stamped by the old gateway, so a Claude Code (`claude_agent_sdk`) span still carries Anthropic's exclusive `gen_ai.usage.input_tokens`: for raw `input_tokens: 5000` with `cache_read: 1000` the detail page and `get_agent_session` show 5000 instead of 6000, because the 1000 is subtracted from a figure that never held it. The index rows keep their v25 `Tokens`, so for the 30-day window the list and the detail page disagree — the opposite of what the change sets out to fix.

Check notice on line 1121 in apps/cli/src/server/local-store-migrations/steps.ts

See this annotation in the file changed.

@maple-review-bot maple-review-bot / Maple / review

maintainability: `local-0025-to-0026` step ships the bump generator's TODO scaffolding

The row is complete — `beforeBootstrap`, `plan`, `verifies` and `dispositions` are all filled — but the appended comment still tells the next reader the row is unfinished and that "the v26 physical verify fails an unfinished row". Every earlier step in this file carries no such block.