diff options
| author | Goni Zahavy <[email protected]> | 2026-02-07 00:13:11 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-06 16:13:11 -0600 |
| commit | def907ae4bf228b43e0b4606f65b9cf2e03c65fc (patch) | |
| tree | 23f2486c24d55de9c596b120d0f38b25a5ff1952 /packages | |
| parent | 71930621fdfeb8f3d2b3baf956cd690cd699101a (diff) | |
| download | opencode-def907ae4bf228b43e0b4606f65b9cf2e03c65fc.tar.gz opencode-def907ae4bf228b43e0b4606f65b9cf2e03c65fc.zip | |
fix(opencode): SessionPrompt.shell() now triggers loop if messages are queued (#10987)
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/opencode/src/server/routes/session.ts | 2 | ||||
| -rw-r--r-- | packages/opencode/src/session/prompt.ts | 33 |
2 files changed, 30 insertions, 5 deletions
diff --git a/packages/opencode/src/server/routes/session.ts b/packages/opencode/src/server/routes/session.ts index 3850376bd..82e6f3121 100644 --- a/packages/opencode/src/server/routes/session.ts +++ b/packages/opencode/src/server/routes/session.ts @@ -539,7 +539,7 @@ export const SessionRoutes = lazy(() => }, auto: body.auto, }) - await SessionPrompt.loop(sessionID) + await SessionPrompt.loop({ sessionID }) return c.json(true) }, ) diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index bcfccfb3e..6643466b2 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -174,7 +174,7 @@ export namespace SessionPrompt { return message } - return loop(input.sessionID) + return loop({sessionID: input.sessionID}) }) export async function resolvePromptParts(template: string): Promise<PromptInput["parts"]> { @@ -239,6 +239,13 @@ export namespace SessionPrompt { return controller.signal } + function resume(sessionID: string) { + const s = state() + if (!s[sessionID]) return + + return s[sessionID].abort.signal + } + export function cancel(sessionID: string) { log.info("cancel", { sessionID }) const s = state() @@ -253,8 +260,14 @@ export namespace SessionPrompt { return } - export const loop = fn(Identifier.schema("session"), async (sessionID) => { - const abort = start(sessionID) + export const LoopInput = z.object({ + sessionID: Identifier.schema("session"), + resume_existing: z.boolean().optional(), + }) + export const loop = fn(LoopInput, async (input) => { + const { sessionID, resume_existing } = input + + const abort = resume_existing ? resume(sessionID) : start(sessionID) if (!abort) { return new Promise<MessageV2.WithParts>((resolve, reject) => { const callbacks = state()[sessionID].callbacks @@ -1366,7 +1379,19 @@ NOTE: At any point in time through this workflow you should feel free to ask the if (!abort) { throw new Session.BusyError(input.sessionID) } - using _ = defer(() => cancel(input.sessionID)) + + using _ = defer(() => { + // If no queued callbacks, cancel (the default) + const callbacks = state()[input.sessionID]?.callbacks ?? [] + if (callbacks.length === 0) { + cancel(input.sessionID) + } else { + // Otherwise, trigger the session loop to process queued items + loop({sessionID: input.sessionID, resume_existing: true}).catch((error) => { + log.error("session loop failed to resume after shell command", { sessionID: input.sessionID, error }) + }) + } + }) const session = await Session.get(input.sessionID) if (session.revert) { |
