diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 22b1d7d99a2..0f85d44f209 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -1110,7 +1110,7 @@ const layer = Layer.effect( if ( lastAssistant?.finish && - !["tool-calls"].includes(lastAssistant.finish) && + !["tool-calls", "unknown"].includes(lastAssistant.finish) && !hasToolCalls && lastAssistant.parentID === lastUser.id ) { diff --git a/packages/opencode/test/session/prompt.test.ts b/packages/opencode/test/session/prompt.test.ts index 5a0176abc9b..da6e0f8d036 100644 --- a/packages/opencode/test/session/prompt.test.ts +++ b/packages/opencode/test/session/prompt.test.ts @@ -850,6 +850,34 @@ it.instance("loop continues when finish is tool-calls", () => }), ) +it.instance("loop continues when finish is unknown", () => + Effect.gen(function* () { + const { llm } = yield* useServerConfig(providerCfg) + const prompt = yield* SessionPrompt.Service + const sessions = yield* Session.Service + const session = yield* sessions.create({ + title: "Pinned", + permission: [{ permission: "*", pattern: "*", action: "allow" }], + }) + yield* prompt.prompt({ + sessionID: session.id, + agent: "build", + noReply: true, + parts: [{ type: "text", text: "hello" }], + }) + yield* llm.push(reply()) + yield* llm.text("second") + + const result = yield* prompt.loop({ sessionID: session.id }) + expect(yield* llm.calls).toBe(2) + expect(result.info.role).toBe("assistant") + if (result.info.role === "assistant") { + expect(result.parts.some((part) => part.type === "text" && part.text === "second")).toBe(true) + expect(result.info.finish).toBe("stop") + } + }), +) + it.instance("glob tool keeps instance context during prompt runs", () => Effect.gen(function* () { const { dir, llm } = yield* useServerConfig(providerCfg)