Skip to content

Session detail: show token breakdown, SDK file path, and zero-cost reason #12

@ttthree

Description

@ttthree

Goal

Make the Session Detail page actionable for diagnosing missing/zero token & cost data.

What to add

For every session, show:

  1. Token breakdown — input / output / cacheCreation / cacheRead and total. Per-model breakdown (modelUsage) when present.
  2. Underlying SDK source file path — where the tokens came from:
    • For `claude-code`: the `.jsonl` path under `~/.claude/projects/...` (or Mars-managed root)
    • For `codex`: the rollout `.jsonl` path
    • For `copilot-cli`: the chat session file path
    • For Eureka orchestrator: also show the Eureka session directory and which file under it provided fallback tokens (`eureka-fallback.ts` resolution)
  3. Token provenance — surface the existing `tokenProvenance` field with a human-readable label:
    • `sdk-cc-jsonl` → "Parsed from Claude Code JSONL"
    • `sdk-codex-rollout` → "Parsed from Codex rollout"
    • `sdk-shutdown` → "Parsed from Copilot CLI shutdown event"
    • `telemetry` / `telemetry-incomplete` → "From Eureka telemetry (no SDK file matched)"
    • `none` → "No token data available"
  4. Zero-cost / zero-token explanation — when both tokens and cost are zero, show a clearly labeled diagnostic:
    • Why no cost? Possible reasons (one or more):
      • Eureka entry matched but no SDK file produced tokens (`provenance=none`)
      • SDK file exists but had 0 tokens (e.g. subagent-only file, no main-thread API messages)
      • Pricing entry missing for model ``
      • Cost calculation skipped (free tier, etc.)
    • Show which one(s) apply.

Pipeline context

The new parse-then-attribute pipeline (`docs/design/DESIGN-parse-then-attribute.md`) sets these fields at:

  • Phase 1 PARSE — SDK parsers populate `tokens`, `modelUsage`, source file path (currently the file path is consumed for cursor management but not retained on `Session`).
  • Phase 3 ATTRIBUTE — `applyEurekaMeta` rekeys to Eureka session id; recently extended with `maybeUpgradeMatchedEurekaSession` to pull fallback tokens for matched sessions with weak provenance.
  • Phase 4 ORPHAN-INGEST — `ingestEurekaOrphans` synthesizes sessions from Eureka entries; sets `tokenProvenance` based on what was found.

To support this issue, we likely need to add to `Session` (or a sibling debug payload returned by `/api/session/.../messages` or a new `/api/session/.../debug`):

  • `sourcePath?: string` — primary SDK file
  • `fallbackPath?: string` — Eureka fallback file when used
  • `zeroCostReasons?: string[]` — populated when total cost is 0

UX

  • New collapsible "Provenance & Diagnostics" section in Session Detail.
  • Path values are clickable (or at least copy-friendly) — open in the macOS Finder via `file://`.
  • Use a warning chip next to `provenance=none` or zero-cost sessions.

Out of scope

  • Fixing the underlying root causes for zero-cost sessions (separate issues per cause once we can see them clearly).
  • Persisting historical provenance changes.

Why now

The reset-vs-incremental investigation (today) showed several sessions with `provenance=none` and $0 cost where the underlying SDK file actually existed in some cases. Surfacing the source path in the UI would have made that 5-minute Python diff in the dashboard, not in a notebook.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions