From 139a1c43cc4160b722b5e7cc95d4f47c90be2171 Mon Sep 17 00:00:00 2001 From: Ben Younes <2910651+ousamabenyounes@users.noreply.github.com> Date: Mon, 10 Aug 2026 19:43:53 +0000 Subject: [PATCH] fix(compaction): respect agent variant config during compaction The compaction summary message hardcoded its variant to the parent user message's variant, ignoring agent.compaction.variant even though agent.compaction.model is already honored. Resolve the variant from the compaction agent config when it is valid for the model, mirroring the existing resolution in session/prompt.ts, and fall back to the previous behavior otherwise. Closes #41578 --- packages/opencode/src/session/compaction.ts | 2 +- .../opencode/test/session/compaction.test.ts | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/session/compaction.ts b/packages/opencode/src/session/compaction.ts index 75d6374bfa54..68ec9211a138 100644 --- a/packages/opencode/src/session/compaction.ts +++ b/packages/opencode/src/session/compaction.ts @@ -397,7 +397,7 @@ const layer = Layer.effect( sessionID: input.sessionID, mode: "compaction", agent: "compaction", - variant: userMessage.model.variant, + variant: agent.variant && model.variants?.[agent.variant] ? agent.variant : userMessage.model.variant, summary: true, path: { cwd: ctx.directory, diff --git a/packages/opencode/test/session/compaction.test.ts b/packages/opencode/test/session/compaction.test.ts index 4f0981fa647e..2991ad0b240a 100644 --- a/packages/opencode/test/session/compaction.test.ts +++ b/packages/opencode/test/session/compaction.test.ts @@ -222,6 +222,15 @@ function cfg(compaction?: ConfigV1.Info["compaction"]) { return Layer.succeed(Config.Service, TestConfig.make({ get: () => Effect.succeed({ ...base, compaction }) })) } +function cfgAgent(agent?: ConfigV1.Info["agent"]) { + const base = Schema.decodeUnknownSync(ConfigV1.Info)({}) as ConfigV1.Info + return Layer.succeed(Config.Service, TestConfig.make({ get: () => Effect.succeed({ ...base, agent }) })) +} + +function modelWithVariant(name: string): Provider.Model { + return { ...createModel({ context: 100_000, output: 32_000 }), variants: { [name]: {} } } +} + const defaultProvider = wide() const compactionTestNode = LayerNode.group([ SessionCompaction.node, @@ -1660,6 +1669,40 @@ describe("session.compaction.process", () => { expect(part?.tail_start_id).toBe(keep.id) }).pipe(withCompaction({ config: cfg({ tail_turns: 2, preserve_recent_tokens: 500 }) })), ) + + itCompaction.instance( + "uses the compaction agent's configured variant for the summary message", + () => { + const variant = "no-thinking" + return Effect.gen(function* () { + const ssn = yield* SessionNs.Service + const session = yield* ssn.create({}) + const msg = yield* createUserMessage(session.id, "hello") + const msgs = yield* ssn.messages({ sessionID: session.id }) + + yield* SessionCompaction.use.process({ + parentID: msg.id, + messages: msgs, + sessionID: session.id, + auto: false, + }) + + const summary = (yield* ssn.messages({ sessionID: session.id })).find( + (item) => item.info.role === "assistant" && item.info.summary, + ) + expect(summary?.info.role).toBe("assistant") + if (summary?.info.role === "assistant") { + expect(summary.info.variant).toBe(variant) + } + }).pipe( + withCompaction({ + provider: ProviderTest.fake({ model: modelWithVariant(variant) }), + config: cfgAgent({ compaction: { variant } }), + }), + ) + }, + { git: true }, + ) }) describe("util.token.estimate", () => {