MCPcopy
hub / github.com/codeaashu/claude-code / shouldAutoCompact

Function shouldAutoCompact

src/services/compact/autoCompact.ts:160–239  ·  view source on GitHub ↗
(
  messages: Message[],
  model: string,
  querySource?: QuerySource,
  // Snip removes messages but the surviving assistant's usage still reflects
  // pre-snip context, so tokenCountWithEstimation can't see the savings.
  // Subtract the rough-delta that snip already computed.
  snipTokensFreed = 0,
)

Source from the content-addressed store, hash-verified

158}
159
160export async function shouldAutoCompact(
161 messages: Message[],
162 model: string,
163 querySource?: QuerySource,
164 // Snip removes messages but the surviving assistant's usage still reflects
165 // pre-snip context, so tokenCountWithEstimation can't see the savings.
166 // Subtract the rough-delta that snip already computed.
167 snipTokensFreed = 0,
168): Promise<boolean> {
169 // Recursion guards. session_memory and compact are forked agents that
170 // would deadlock.
171 if (querySource === 'session_memory' || querySource === 'compact') {
172 return false
173 }
174 // marble_origami is the ctx-agent — if ITS context blows up and
175 // autocompact fires, runPostCompactCleanup calls resetContextCollapse()
176 // which destroys the MAIN thread's committed log (module-level state
177 // shared across forks). Inside feature() so the string DCEs from
178 // external builds (it's in excluded-strings.txt).
179 if (feature('CONTEXT_COLLAPSE')) {
180 if (querySource === 'marble_origami') {
181 return false
182 }
183 }
184
185 if (!isAutoCompactEnabled()) {
186 return false
187 }
188
189 // Reactive-only mode: suppress proactive autocompact, let reactive compact
190 // catch the API's prompt-too-long. feature() wrapper keeps the flag string
191 // out of external builds (REACTIVE_COMPACT is ant-only).
192 // Note: returning false here also means autoCompactIfNeeded never reaches
193 // trySessionMemoryCompaction in the query loop — the /compact call site
194 // still tries session memory first. Revisit if reactive-only graduates.
195 if (feature('REACTIVE_COMPACT')) {
196 if (getFeatureValue_CACHED_MAY_BE_STALE('tengu_cobalt_raccoon', false)) {
197 return false
198 }
199 }
200
201 // Context-collapse mode: same suppression. Collapse IS the context
202 // management system when it's on — the 90% commit / 95% blocking-spawn
203 // flow owns the headroom problem. Autocompact firing at effective-13k
204 // (~93% of effective) sits right between collapse's commit-start (90%)
205 // and blocking (95%), so it would race collapse and usually win, nuking
206 // granular context that collapse was about to save. Gating here rather
207 // than in isAutoCompactEnabled() keeps reactiveCompact alive as the 413
208 // fallback (it consults isAutoCompactEnabled directly) and leaves
209 // sessionMemory + manual /compact working.
210 //
211 // Consult isContextCollapseEnabled (not the raw gate) so the
212 // CLAUDE_CONTEXT_COLLAPSE env override is honored here too. require()
213 // inside the block breaks the init-time cycle (this file exports
214 // getEffectiveContextWindowSize which collapse's index imports).
215 if (feature('CONTEXT_COLLAPSE')) {
216 /* eslint-disable @typescript-eslint/no-require-imports */
217 const { isContextCollapseEnabled } =

Callers 1

autoCompactIfNeededFunction · 0.85

Calls 8

featureFunction · 0.85
isAutoCompactEnabledFunction · 0.85
tokenCountWithEstimationFunction · 0.85
getAutoCompactThresholdFunction · 0.85
logForDebuggingFunction · 0.85

Tested by

no test coverage detected