From 615ed0ae2e926f8bc6fa484a22a77e3bdf72f178 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 7 Jan 2026 16:50:18 +0100 Subject: [PATCH] Fix compaction UX oddities when model switching (#535) --- .../coding-agent/src/core/agent-session.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/src/core/agent-session.ts b/packages/coding-agent/src/core/agent-session.ts index 9deedc53..88c66a61 100644 --- a/packages/coding-agent/src/core/agent-session.ts +++ b/packages/coding-agent/src/core/agent-session.ts @@ -1262,8 +1262,24 @@ export class AgentSession { const contextWindow = this.model?.contextWindow ?? 0; + // Skip overflow check if the message came from a different model. + // This handles the case where user switched from a smaller-context model (e.g. opus) + // to a larger-context model (e.g. codex) - the overflow error from the old model + // shouldn't trigger compaction for the new model. + const sameModel = + this.model && assistantMessage.provider === this.model.provider && assistantMessage.model === this.model.id; + + // Skip overflow check if the error is from before a compaction in the current path. + // This handles the case where an error was kept after compaction (in the "kept" region). + // The error shouldn't trigger another compaction since we already compacted. + // Example: opus fails → switch to codex → compact → switch back to opus → opus error + // is still in context but shouldn't trigger compaction again. + const compactionEntry = this.sessionManager.getBranch().find((e) => e.type === "compaction"); + const errorIsFromBeforeCompaction = + compactionEntry && assistantMessage.timestamp < new Date(compactionEntry.timestamp).getTime(); + // Case 1: Overflow - LLM returned context overflow error - if (isContextOverflow(assistantMessage, contextWindow)) { + if (sameModel && !errorIsFromBeforeCompaction && isContextOverflow(assistantMessage, contextWindow)) { // Remove the error message from agent state (it IS saved to session for history, // but we don't want it in context for the retry) const messages = this.agent.state.messages;