diff --git a/packages/opencode/src/session/processor.ts b/packages/opencode/src/session/processor.ts index 21f9329c6fce..fbadb628ca8b 100644 --- a/packages/opencode/src/session/processor.ts +++ b/packages/opencode/src/session/processor.ts @@ -524,6 +524,15 @@ export const layer: Layer.Layer< slog.error("process", { error: errorMessage(e), stack: e instanceof Error ? e.stack : undefined }) const error = parse(e) if (MessageV2.ContextOverflowError.isInstance(error)) { + if ((yield* config.get()).compaction?.auto === false) { + ctx.assistantMessage.error = error + yield* bus.publish(Session.Event.Error, { + sessionID: ctx.sessionID, + error: ctx.assistantMessage.error, + }) + yield* status.set(ctx.sessionID, { type: "idle" }) + return + } ctx.needsCompaction = true yield* bus.publish(Session.Event.Error, { sessionID: ctx.sessionID, error }) return diff --git a/packages/opencode/test/session/processor-effect.test.ts b/packages/opencode/test/session/processor-effect.test.ts index 74ce913077d3..8b0264b85573 100644 --- a/packages/opencode/test/session/processor-effect.test.ts +++ b/packages/opencode/test/session/processor-effect.test.ts @@ -644,6 +644,55 @@ it.live("session.processor effect tests compact on structured context overflow", ), ) +it.live("session.processor effect tests stop on structured context overflow when compaction.auto is false", () => + provideTmpdirServer( + ({ dir, llm }) => + Effect.gen(function* () { + const { processors, session, provider } = yield* boot() + + yield* llm.error(400, { type: "error", error: { code: "context_length_exceeded" } }) + + const chat = yield* session.create({}) + const parent = yield* user(chat.id, "stop json") + const msg = yield* assistant(chat.id, parent.id, path.resolve(dir)) + const mdl = yield* provider.getModel(ref.providerID, ref.modelID) + const handle = yield* processors.create({ + assistantMessage: msg, + sessionID: chat.id, + model: mdl, + }) + + const value = yield* handle.process({ + user: { + id: parent.id, + sessionID: chat.id, + role: "user", + time: parent.time, + agent: parent.agent, + model: { providerID: ref.providerID, modelID: ref.modelID }, + } satisfies MessageV2.User, + sessionID: chat.id, + model: mdl, + agent: agent(), + system: [], + messages: [{ role: "user", content: "stop json" }], + tools: {}, + }) + + expect(value).toBe("stop") + expect(yield* llm.calls).toBe(1) + expect(handle.message.error?.name).toBe("ContextOverflowError") + }), + { + git: true, + config: (url) => ({ + ...providerCfg(url), + compaction: { auto: false }, + }), + }, + ), +) + it.live("session.processor effect tests mark pending tools as aborted on cleanup", () => provideTmpdirServer( ({ dir, llm }) =>