Feature request: a supported way to disable the agent_summary spinner (22.7% of requests, ~18% of weighted tokens in a subagent-heavy session)

Status Open
Reported on v2.1.233
Maintainer reply None cached
Activity 3 comments · opened Aug 15, 2026

Request

Provide a supported way to disable the agent_summary timer (the 3-5 word subagent spinner text) — an env var, a settings.json key, or coverage under an existing flag.

Version: 2.1.233 · Platform: darwin 25.6.0 · Entrypoint: cli

Why

In a subagent-heavy session it is a large, invisible share of consumption. Measured over one 4-hour session (27 subagents, 1,496 requests mapped from raw payloads captured with OTEL_LOG_RAW_API_BODIES):

| kind | calls | cache read | cache write | output | raw tokens | raw % | weighted % |
|---|---:|---:|---:|---:|---:|---:|---:|
| real agent turns | 1,076 | 193,219,620 | 5,209,321 | 825,201 | 199,321,158 | 70.4% | 72.7% |
| agent_summary | 339 | 61,560,341 | 254,270 | 21,966 | 62,757,361 | 22.2% | 18.0% |
| suggestion | 37 | 10,117,116 | 9,370 | 229 | 10,145,363 | 3.6% | 2.5% |
| task-notification | 36 | 9,583,910 | 205,636 | 45,758 | 9,835,376 | 3.5% | 3.8% |

Weighted at Opus 5 list rates (reads 0.1×, 5m writes 1.25×, 1h writes 2×, output 5×).

22.7% of all API requests in the session, producing 21,966 output tokens total (~65 per call) of cosmetic status text.

Each call re-sends the subagent's entire conversation history plus the full tool schema, on claude-opus-5, every 30 seconds per active subagent. Cost therefore scales with fan-out and wall-clock duration, not with useful work: a session with three concurrent long-running subagents pays six of these per minute.

Why gating it should be safe

The call is already architecturally decoupled from the agent it describes — from the 2.1.233 bundle:

await eW({
  promptMessages:[Sn({content:mXS(p)})],
  querySource:"agent_summary", forkLabel:"agent_summary",
  maxTurns:1, skipTranscript:true, skipCacheWrite:true,
  canUseTool: async () => ({behavior:"deny", message:"No tools needed for summary"}),
})

It forks context (forkContextMessages) rather than mutating it, denies all tools, caps at one turn, writes no cache, and is excluded from the transcript. The summary never re-enters the agent's context. Suppressing it cannot change any real turn — with it disabled, every other request in the session is byte-identical.

There is already a conditional at the call site (let Z = l ? (…) => { KEf(…) } : void 0), so a gate exists structurally; it just isn't reachable by configuration.

Suggested options, in preference order

  1. A dedicated flagCLAUDE_CODE_DISABLE_AGENT_SUMMARY=1, or a settings.json key. I checked the binary's CLAUDE_CODE_* string table for summ|spin|agent: no matches, so nothing exists today.
  2. Cover it under CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC. This call fits that category well — purely cosmetic, no effect on agent behavior. If it is already covered, documenting that would be enough and I'll close this.
  3. Make the 30s interval configurable. var fXS = 30000 is read via i.intervalMs ?? fXS, and no caller passes intervalMs — plumbing that through to config would let users trade update latency against tokens.

Secondary observation

These calls carry skipTranscript: true, so they appear in no transcript. Any transcript-based cost tooling — including users' own — silently understates real token consumption by this amount. Even were the calls kept, emitting them to the transcript (or to OTel usage metrics) would make the spend visible.

Related: #86876 (subagent resume drops injected role:"system" messages), from the same investigation.

View original on GitHub ↗

3 Comments

kcarriedo · 15 days ago

Seconding this -- the agent_summary calls are a real cost sink in subagent-heavy sessions and there's no way to opt out.

The data you shared matches what I've seen on the runner side. In sessions with 20+ subagents the summary generation is consistently in the 15-22% weighted token range. For interactive sessions where you're watching the spinner, the UX value is real. For unattended sessions running overnight or in CI, it's cost with no human watching.

A few things I'd add to the feature request:

  • An env var (CLAUDE_DISABLE_AGENT_SUMMARY=1) would be the easiest to add to automation scripts without touching settings files per project.
  • If disabling the spinner entirely isn't feasible, a token budget cap for the summary call (settings.json: agentSummaryMaxTokens: 0 to disable, some small positive number to cap) would let users trade summary quality for cost.
  • The summary content itself isn't surfaced in the API response or logs, so there's no way to even audit what's being generated. Exposing it (even just in debug mode) would help users decide whether it's worth the cost for their workflow.

The use case is exactly as described -- autonomous sessions running in a harness where the spinner text is invisible and the token cost is not.

uwuclxdy · 5 days ago
CLAUDE_CODE_FORK_SUBAGENT=0 stops the narration but also disables fork mode.

found out by deepseek, not claude (claude gave up).
resolved this for me cuz i dont use fork mode. there may be some other way to do it, but im personally good with this. sharing in case someone else wants to do the same

uwuclxdy · 5 days ago

okay update: CLAUDE_CODE_ENABLE_NARRATION=0 disables it completely. but it only works in .241 and not the current .245 (deepseek says its dead code in the new version bruh). added this to my settings.json:

"env": {
    "CLAUDE_CODE_ENABLE_NARRATION": "0",
    "CLAUDE_CODE_FORK_SUBAGENT": "0",
	"DISABLE_AUTOUPDATER": "1"
}