Advisor tool inflates the main session's auto-compact counter, triggering spurious compaction
Advisor tool inflates the main session's auto-compact counter, triggering spurious compaction
Summary
Calling the server-side advisor tool causes the main session's context meter to
spike far above its real value for one turn. Auto-compact appears to fire off that
inflated number, compacting a session that is not actually near its limit.
Observed behavior
On a 1M-context session (model: "Sonnet[1m]", autoCompactWindow: 900000):
- Main context reads ~30%.
advisoris called. Once it returns, the meter reads ~88%.- The meter stays at ~88%. It does not settle on its own.
- Only after I send another prompt to the main session and receive a normal
response does it drop back to ~31% — roughly the pre-call value plus normal
turn growth.
The critical part is step 3. The inflated figure is not a momentary blip during the
advisor request; it persists as the session's current context reading until the next
main-loop response overwrites it. For that entire window the session is accounted for
at the advisor's token count rather than its own.
If that window happens to put the reading over the auto-compact threshold, compaction
fires — on a session whose real context is ~31%. Recovery requires a main-loop
response, but auto-compact is evaluated before one arrives, so the user cannot avoid
it by waiting.
Expected behavior
The advisor tool's own input tokens should not count toward the main session's
context-window accounting or its auto-compact eligibility check. A session at 31%
should not be compacted.
Why this looks like accounting, not real growth
- Real context growth does not reverse on the next main-loop response; this does.
- A constant offset (e.g. an output-token reservation) would make the meter start
high and stay high; it would not spike and settle.
- The elevation occurs only on turns where advisor was invoked.
Suspected cause (unverified)
Reading the bundled CLI (v2.1.219), the auto-compact eligibility check receivescontextTokens derived from the API-reported usage object rather than from a
computed message-list total:
let oc = cIe(ks);
if (qxs({ ..., contextTokens: oc, model: ..., autoCompactWindow: ... })) ...
with usage components visible immediately below:
let bs = ks.input_tokens + (ks.cache_creation_input_tokens ?? 0) + (ks.cache_read_input_tokens ?? 0),
J = Y0(Le, xT(V.options.mainLoopModel)) - Oe;
If the advisor call — which re-sends the full transcript as its own input — has its
usage folded into the same response's usage object, contextTokens would be
inflated for that turn. That matches the observed spike-and-settle pattern.
I could not confirm from the bundle that advisor usage is actually merged into the
main response's usage; that last link is inferred from the observed behavior.
Related: advisorModel cannot select a 1M-context advisor
Separate but adjacent. Setting advisorModel: "Opus[1m]" does not yield a 1M-context
advisor. The resolved value has the suffix stripped unconditionally:
let r = Wu(vi(e)); // iEo()
function Wu(e){ return e.replace(/\[(1|2)m\]/gi,"") }
function Wb(e){ return /\[1m\]/i.test(e) } // 1M detection reads that suffix
vi() preserves [1m] while resolving the alias, but the enclosing Wu() removes
it, so "Opus[1m]" and "Opus" are equivalent and the advisor runs at 200k. On a
1M main session this also means the advisor can exceed its own window on long
transcripts.
If this is intentional, it would help to document it — the setting silently accepts
a [1m] alias that has no effect.
Environment
- Claude Code 2.1.219, WSL2 (Linux 6.18.33.2-microsoft-standard-WSL2)
model:Sonnet[1m]advisorModel:Opus[1m]autoCompactWindow: 900000,autoCompactEnabled: trueCLAUDE_CODE_MAX_OUTPUT_TOKENS: 65536
Impact
On long sessions the main context is compacted without cause, losing detail
mid-task. There is no setting that avoids it: the advisor re-sends the transcript by
design, the auto-compact trigger fraction is served remotely
(tengu_amber_moleskin), and autoCompactWindow is capped at 1e6 — below the
observed spike size. The only workaround is to disable the advisor.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗