SubagentStop hook payload should include token usage data

Resolved 💬 5 comments Opened Apr 12, 2026 by pguerette-999 Closed Jun 4, 2026

Summary

The SubagentStop hook event fires for /btw (aside question) subagents but the payload does not include any token usage data. The transcript file is also not written (skipTranscript:true in runForkedAgent), leaving no programmatic path to capture per-call token counts for /btw invocations.

Current payload

{
  "session_id": "...",
  "agent_id": "...",
  "agent_type": "",
  "agent_transcript_path": "...agent-xxx.jsonl",
  "last_assistant_message": "...",
  "hook_event_name": "SubagentStop",
  "stop_hook_active": false
}

What's missing

Token usage fields — the same data that appears in the debug log:

Forked agent [side_question] finished: 4 messages,
  totalUsage: input=253 output=11 cacheRead=17873 cacheCreate=7

Evidence the data exists internally

  • --debug "api" logs the full totalUsage for /btw calls (confirmed CC v2.1.104)
  • OpenTelemetry claude_code.api_request events include input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, cost_usd for every API call including /btw
  • The data is available at the point SubagentStop fires — it just isn't included in the hook payload

Requested change

Add token usage fields to the SubagentStop payload:

{
  "input_tokens": 253,
  "output_tokens": 11,
  "cache_read_input_tokens": 17873,
  "cache_creation_input_tokens": 7,
  "model": "claude-opus-4-6",
  "cost_usd": 0.027707
}

This would also benefit normal subagent hooks — currently SubagentStop requires reading the transcript JSONL to get token data, which adds I/O and complexity.

Context

Building a FinOps cost monitoring tool that tracks per-session and per-subagent costs via Stop/SubagentStop hooks. /btw costs (~$0.01-0.04 per invocation) are currently invisible without an OTel workaround.

Workaround

We currently use OTel (OTEL_LOGS_EXPORTER=otlp) pointed at a local HTTP receiver to capture /btw token data, matching events by session.id + absence of prompt.id. This works but requires running additional infrastructure.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗