Skip to content

fix(v1): fall back to provider usage for dashboard token counts - #1627

Merged
mikasenghaas merged 1 commit into
feat/nano-as-v1from
fix/dashboard-token-usage-fallback
Jun 11, 2026
Merged

fix(v1): fall back to provider usage for dashboard token counts#1627
mikasenghaas merged 1 commit into
feat/nano-as-v1from
fix/dashboard-token-usage-fallback

Conversation

@mikasenghaas

@mikasenghaas mikasenghaas commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

  • The --rich eval dashboard showed 0/0 tokens per rollout for endpoints that don't return token ids (e.g. plain OpenAI completions through an inference gateway): _tokens derived its counts from the branch's token-id lengths, which are empty there.
  • Carry the response's usage onto the assistant MessageNode as a transient (exclude=True) sidecar — same pattern as the multimodal sidecar, never written to wire / results.jsonl.
  • Add Branch.num_prompt_tokens / num_completion_tokens (usage-based) and have _tokens fall back to them when token ids are absent. Semantics preserved: input = the final turn's prompt tokens (full final context), output = the sum of completion tokens across every turn.
  • The renderer path (token ids present) is unchanged — token-id counts take precedence; usage is only the fallback.
  • Regression from feat: delta-native message-graph trajectory #1606 (delta-native message graph), which switched _tokens off response.usage onto token-id lengths.

Verification

Synthetic OpenAI-style trace (usage reported, response.tokens=None) driven through the real add_turn_tokens:

  • Before: 0/0 tokens
  • After: 100/20 tokens — input = final turn's usage.prompt_tokens, output = summed usage.completion_tokens

ruff check and ruff format --check pass on the three changed files.

Note

Fall back to provider usage for token counts in dashboard when token IDs are unavailable

  • Adds a usage field to MessageNode in graph.py to store provider-reported token usage for assistant responses (excluded from serialization); populates it in add_turn.
  • Adds num_prompt_tokens and num_completion_tokens properties to Branch in trace.py that derive counts from provider usage when token IDs are absent.
  • Updates the _tokens helper in dashboard.py to prefer token-ID-derived counts but fall back to provider usage, returning an empty string when both are missing.

Macroscope summarized 76d9e9c.


Note

Low Risk
Display-only fallback in the live dashboard; usage is excluded from persistence and token-id counts still win when present.

Overview
Fixes the --rich eval dashboard showing 0/0 tokens when the inference endpoint returns provider usage but no token ids (e.g. plain OpenAI completions).

MessageNode now keeps a transient usage sidecar (same pattern as multimodal data, exclude=True), set in add_turn from response.usage. Branch adds num_prompt_tokens (last assistant turn’s reported prompt) and num_completion_tokens (sum across turns). _tokens prefers existing token-id-based prompt_len / completion_len, falls back to those usage properties, and omits the token column when both are zero.

The renderer path with token ids is unchanged; usage is display-only and not persisted to wire / results.jsonl.

Reviewed by Cursor Bugbot for commit 76d9e9c. Bugbot is set up for automated code reviews on this repo. Configure here.

The --rich dashboard's per-rollout "X/Y tokens" was derived from the branch's
token-id lengths, which are 0 for endpoints that don't return token ids (e.g.
plain OpenAI completions) — so eval rows showed "0/0 tokens".

Carry the response's usage onto the assistant node (transient, excluded from
wire/disk, like the multimodal sidecar) and fall back to it when token ids are
absent: input = final turn's usage.prompt_tokens, output = sum of
usage.completion_tokens across turns. The renderer path (token ids present) is
unchanged. Regression from #1606, which switched _tokens off response.usage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mikasenghaas
mikasenghaas marked this pull request as ready for review June 11, 2026 07:45
@mikasenghaas
mikasenghaas merged commit 955b6cd into feat/nano-as-v1 Jun 11, 2026
4 checks passed
@macroscopeapp

macroscopeapp Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

This is a self-contained display fix that adds fallback token counts for the dashboard when endpoints don't return token IDs. The new field is explicitly excluded from serialization (transient), and the logic changes are limited to UI display code with no impact on core runtime behavior.

You can customize Macroscope's approvability policy. Learn more.

pull Bot pushed a commit to Stars1233/verifiers that referenced this pull request Jun 23, 2026
…eIntellect-ai#1627)

The --rich dashboard's per-rollout "X/Y tokens" was derived from the branch's
token-id lengths, which are 0 for endpoints that don't return token ids (e.g.
plain OpenAI completions) — so eval rows showed "0/0 tokens".

Carry the response's usage onto the assistant node (transient, excluded from
wire/disk, like the multimodal sidecar) and fall back to it when token ids are
absent: input = final turn's usage.prompt_tokens, output = sum of
usage.completion_tokens across turns. The renderer path (token ids present) is
unchanged. Regression from PrimeIntellect-ai#1606, which switched _tokens off response.usage.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant