Skip to content

fix(agent): show real token counts in subagent progress - #49

Closed
savass33 wants to merge 1 commit into
mainfrom
fix/subagent-token-progress
Closed

fix(agent): show real token counts in subagent progress#49
savass33 wants to merge 1 commit into
mainfrom
fix/subagent-token-progress

Conversation

@savass33

@savass33 savass33 commented Sep 9, 2026

Copy link
Copy Markdown

Summary

Fixes subagent progress showing tool calls but zero tokens (BUG-1 from review).

Root cause

Streaming providers (Verboo/OpenAI shim) emit message_start with zeroed usage; the real usage arrives in message_delta, which mutates the last yielded message in place — after the consumer already read it. The subagent ProgressTracker therefore counted tool calls (from content.tool_use) but kept tokens at 0.

Changes

  • LocalAgentTask.tsx: add syncProgressUsageFromMessages() — re-derives token counters from accumulated assistant messages (input cumulative/latest-wins, output summed per request). The accumulated references are exactly what message_delta mutates in place, so this converges to real usage.
  • agentToolUtils.ts / AgentTool.tsx: apply the recompute in runAsyncAgentLifecycle, sync path, and backgrounded path — both per-message and after the loop ends (so the final notification carries real totals).
  • BackgroundTask.tsx: show · N tokens · N tools in the background tasks list for local_agent rows (previously only description + status).
  • AgentTool.tsx: log when a model override is ignored in coordinator mode instead of silently swallowing it; fix indentation in the backgrounded error block.
  • LocalAgentTask.tsx: sanitize angle brackets in the task notification summary so a model-supplied description can't break the <summary> envelope.
  • Test: tokenProgress.test.ts — regression test simulating the shim timing (zeroed usage at yield, in-place mutation after) and asserting token convergence.

Validation

  • bun test on related suites: 6 pass
  • bun run build: OK
  • Live test against Verboo router: task_progress events now show tools=2 tokens=11118 (previously tokens=0)

Streaming providers (Verboo/OpenAI shim) emit message_start with zeroed
usage; the real usage arrives in message_delta, which mutates the last
yielded message in place after the consumer already read it. Subagent
progress therefore counted tool calls but kept tokens at 0.

- Add syncProgressUsageFromMessages() to re-derive token counters from
  accumulated assistant messages (input cumulative, output summed)
- Apply it in runAsyncAgentLifecycle, sync and backgrounded AgentTool
  paths, both per-message and after the loop ends
- Show tokens/tools in the background tasks list (local_agent rows)
- Log when a model override is ignored in coordinator mode instead of
  silently swallowing it
- Fix indentation in the backgrounded error block
- Sanitize description angle brackets in task notification summary
- Add regression test for token convergence after in-place usage mutation
@savass33

savass33 commented Sep 9, 2026

Copy link
Copy Markdown
Author

Fechando em favor do #51.

O bug de token já foi corrigido no main em 7d5b362 (v0.15.21), por outra arquitetura: o ProgressTracker agora guarda messages: Map<uuid, Message> e getTrackerUsage() calcula na leitura via agentUsageFromMessages(). Mesma sacada deste PR — as referências acumuladas são o que o message_delta muta in-place — só que como leitura preguiçosa em vez de recomputo eager, e com dedupe por uuid que a versão daqui não tinha.

Mergear este PR seria pior que não mergear: o git faz auto-merge do LocalAgentTask.tsx sem conflito, e o resultado escreve em campos que não existem mais no tracker:

LocalAgentTask.tsx(102,11): error TS2339: Property 'latestInputTokens' does not exist on type 'ProgressTracker'.
LocalAgentTask.tsx(103,11): error TS2339: Property 'cumulativeOutputTokens' does not exist on type 'ProgressTracker'.

E o conserto óbvio (readicionar os campos pra calar o TS) faria os writes virarem no-op silencioso, com o PR parecendo aplicado.

O #51 parte do main atual e traz o que continua válido: sanitização de <> no envelope da notificação (com teste), tokens/tools na lista de background tasks, e o log do model override em coordinator mode. A parte de UI foi refeita anexando os slots do React Compiler em 92..97 em vez de inserir no meio da faixa — a versão daqui deslocava só localmente e passava a colidir com os slots 32..39 que o case "in_process_teammate" ainda lê.

@savass33 savass33 closed this Sep 9, 2026
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