From 87f21a301dc9d7c1ecc1c643fece783ab96b07ac Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 27 Aug 2026 23:01:57 -0400 Subject: [PATCH] fix(core): forward plugin interrupt options (#45632) --- .changeset/plugin-interrupt-options.md | 5 +++++ packages/core/src/plugin/runtime.ts | 2 +- packages/core/test/plugin.test.ts | 30 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .changeset/plugin-interrupt-options.md diff --git a/.changeset/plugin-interrupt-options.md b/.changeset/plugin-interrupt-options.md new file mode 100644 index 00000000000..bf2eeb3e006 --- /dev/null +++ b/.changeset/plugin-interrupt-options.md @@ -0,0 +1,5 @@ +--- +"@opencode-ai/core": patch +--- + +Forward plugin Session interrupt options so continuation requests reach the Session service. diff --git a/packages/core/src/plugin/runtime.ts b/packages/core/src/plugin/runtime.ts index 1cce9e44dfa..688076a7aba 100644 --- a/packages/core/src/plugin/runtime.ts +++ b/packages/core/src/plugin/runtime.ts @@ -76,7 +76,7 @@ export const layerWithCell = (cell: Cell) => resume: (sessionID) => require(cell, (runtime) => runtime.session.resume(sessionID)), switchAgent: (input) => require(cell, (runtime) => runtime.session.switchAgent(input)), switchModel: (input) => require(cell, (runtime) => runtime.session.switchModel(input)), - interrupt: (sessionID) => require(cell, (runtime) => runtime.session.interrupt(sessionID)), + interrupt: (sessionID, options) => require(cell, (runtime) => runtime.session.interrupt(sessionID, options)), synthetic: (input) => require(cell, (runtime) => runtime.session.synthetic(input)), wait: (sessionID) => require(cell, (runtime) => runtime.session.wait(sessionID)), context: (sessionID) => require(cell, (runtime) => runtime.session.context(sessionID)), diff --git a/packages/core/test/plugin.test.ts b/packages/core/test/plugin.test.ts index d3248304eb7..14549f234b2 100644 --- a/packages/core/test/plugin.test.ts +++ b/packages/core/test/plugin.test.ts @@ -113,6 +113,36 @@ describe("Plugin", () => { }), ) + it.effect("forwards session interrupt options through the runtime cell", () => + Effect.gen(function* () { + const plugins = yield* Plugin.Service + const fallback = yield* PluginRuntime.Service + const cell = PluginRuntime.makeCell() + const sessionID = Session.ID.create() + const calls: Array<{ sessionID: Session.ID; options: { continue?: boolean } | undefined }> = [] + cell.runtime = { + ...fallback, + session: { + ...fallback.session, + interrupt: (id, options) => + Effect.sync(() => { + calls.push({ sessionID: id, options }) + return true + }), + }, + } + const runtime = yield* PluginRuntime.Service.pipe(Effect.provide(PluginRuntime.layerWithCell(cell))) + const host = yield* PluginHost.make(plugins).pipe(Effect.provideService(PluginRuntime.Service, runtime)) + + expect(yield* runtime.session.interrupt(sessionID)).toBe(true) + expect(yield* host.session.interrupt({ sessionID, continue: true })).toEqual({ interrupted: true }) + expect(calls).toEqual([ + { sessionID, options: undefined }, + { sessionID, options: { continue: true } }, + ]) + }), + ) + it.effect("registers and removes scoped VCS providers", () => Effect.gen(function* () { const plugins = yield* Plugin.Service