diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts index 40f33b3a1a309..265ca24c4236c 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts @@ -6077,7 +6077,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { ? [event.providerTurn.tokenUsage.autoCompactThreshold] : [], ), - [150_000, 150_000, 150_000, 150_000], + [117_000, 117_000, 117_000, 117_000], ); }).pipe( Effect.provide( @@ -6088,10 +6088,10 @@ describe("ClaudeAdapterV2 background wake turns", () => { it.effect.each([ { autoCompactWindow: "", model: "claude-sonnet-4-6", threshold: undefined }, - { autoCompactWindow: "150000", model: "claude-sonnet-4-6", threshold: 150_000 }, + { autoCompactWindow: "150000", model: "claude-sonnet-4-6", threshold: 117_000 }, { autoCompactWindow: "200000", model: "claude-sonnet-4-6", threshold: undefined }, { autoCompactWindow: "650000", model: "claude-sonnet-4-6", threshold: undefined }, - { autoCompactWindow: "650000", model: "uncatalogued-model", threshold: 650_000 }, + { autoCompactWindow: "650000", model: "uncatalogued-model", threshold: 617_000 }, ])( "ignores stale snapshots after compaction and reports threshold $autoCompactWindow for $model", ({ autoCompactWindow, model, threshold }) => diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts index f42f37d1ab1b1..aeb4e5f58234d 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts @@ -231,10 +231,14 @@ function claudePromptCacheTtlMs( } // Claude caps the window at the model's context, so a setting at or above it never applies. +// Below that, Claude compacts 33,000 tokens short of the window: Claude Code 2.1.305's +// getContextUsage reports a 150,000 window as a 117,000 threshold, for every catalog model. +const CLAUDE_AUTO_COMPACT_RESERVE_TOKENS = 33_000; + function claudeAutoCompactThreshold(autoCompactWindow: string, maxTokens: number | null) { - const threshold = Number(autoCompactWindow); - return threshold > 0 && (maxTokens === null || threshold < maxTokens) - ? { autoCompactThreshold: threshold } + const windowTokens = Number(autoCompactWindow); + return windowTokens > 0 && (maxTokens === null || windowTokens < maxTokens) + ? { autoCompactThreshold: windowTokens - CLAUDE_AUTO_COMPACT_RESERVE_TOKENS } : {}; }