Skip to content

Fix: populate token/model fields in native-path routing log entries#466

Merged
rockfordlhotka merged 3 commits into
mainfrom
fix/routing-log-token-attribution
Jun 9, 2026
Merged

Fix: populate token/model fields in native-path routing log entries#466
rockfordlhotka merged 3 commits into
mainfrom
fix/routing-log-token-attribution

Conversation

@rockfordlhotka

Copy link
Copy Markdown
Member

Problem

The agent's daily cost guard reported .00 cost — nothing was being priced, despite a populated pricing table.

Root cause: The native LLM path (NativeToolLoopAsync in UserMessageHandler) wrote TierRoutingEntry records with ModelId set but InputTokens/OutputTokens left null. TierRoutingAnalyzer.BuildProjectedCost skips any entry with null tokens, so every entry was unpriced → total cost collapsed to .00.

Fix

  • Add InputTokens, OutputTokens, ModelId to LoopDiagnostics so the loop runner can surface token data to callers without changing RunAsync's Task<string> return type.
  • RunNativeLoopAsync populates those fields from the FICC response.
  • RunTextBasedLoopAsync tracks lastModelId across iterations and populates the fields in its finally block alongside existing OTel recording.
  • NativeToolLoopAsync passes a LoopDiagnostics to RunAsync and uses diag.InputTokens / OutputTokens / ToolCalls / ModelId when writing the routing entry (falls back to registry.GetModelId when the response carries no model ID).

Validation

  • All 1057 RockBot.Host.Tests pass.
  • Deployed rockbot-agent:0.12.29 to the cluster; new routing-log entries now carry token + model fields and cost attribution is non-zero.

Version bumped 0.12.27 → 0.12.29.

rockfordlhotka and others added 3 commits June 9, 2026 10:24
… log entries

The native LLM path (NativeToolLoopAsync) was writing TierRoutingEntry
records with ModelId set but InputTokens/OutputTokens left null.
TierRoutingAnalyzer.BuildProjectedCost skips any entry with null tokens,
so all 15 entries were unpriced -> \.00 total cost reported.

Fix:
- Add InputTokens, OutputTokens, ModelId to LoopDiagnostics so the loop
  runner can surface token data back to callers without changing RunAsync's
  Task<string> return type.
- RunNativeLoopAsync now populates those fields from the FICC response.
- RunTextBasedLoopAsync tracks lastModelId across iterations and populates
  the fields in its finally block alongside the existing OTel recording.
- NativeToolLoopAsync creates a LoopDiagnostics, passes it to RunAsync,
  and uses diag.InputTokens / OutputTokens / ToolCalls / ModelId when
  writing the TierRoutingEntry (falls back to registry.GetModelId when the
  response carries no model ID).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Patch release for routing log token attribution fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
0.12.28 was already built/deployed without the routing-log token
attribution fix; bump to 0.12.29 so the fixed agent image has a unique,
traceable tag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rockfordlhotka rockfordlhotka merged commit 449bc82 into main Jun 9, 2026
@rockfordlhotka rockfordlhotka deleted the fix/routing-log-token-attribution branch June 9, 2026 16:20
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