MCPcopy Index your code
hub / github.com/claude-code-best/claude-code / shouldAutoCompact

Function shouldAutoCompact

src/services/compact/autoCompact.ts:189–268  ·  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

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

Callers 1

autoCompactIfNeededFunction · 0.85

Calls 8

isAutoCompactEnabledFunction · 0.85
isContextCollapseEnabledFunction · 0.85
tokenCountWithEstimationFunction · 0.85
getAutoCompactThresholdFunction · 0.85
logForDebuggingFunction · 0.50

Tested by

no test coverage detected