diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 22fe4d81cd40..0ac920be37f2 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -691,7 +691,13 @@ export const layer = Layer.effect( }) const createUserMessage = Effect.fn("SessionPrompt.createUserMessage")(function* (input: PromptInput) { - const agentName = input.agent + const prev = input.agent + ? undefined + : (yield* MessageV2.filterCompactedEffect(input.sessionID)).findLast( + (m): m is MessageV2.WithParts & { info: MessageV2.User } => + m.info.role === "user" && !!m.info.agent, + ) + const agentName = input.agent ?? prev?.info.agent const ag = agentName ? yield* agents.get(agentName) : yield* agents.defaultInfo() if (!ag) { const available = (yield* agents.list()).filter((a) => !a.hidden).map((a) => a.name) @@ -708,7 +714,7 @@ export const layer = Layer.effect( .where(eq(SessionTable.id, input.sessionID)) .get(), ) - const model = input.model ?? ag.model ?? (yield* currentModel(input.sessionID)) + const model = input.model ?? prev?.info.model ?? ag.model ?? (yield* currentModel(input.sessionID)) const same = ag.model && model.providerID === ag.model.providerID && model.modelID === ag.model.modelID const full = !input.variant && ag.variant && same diff --git a/packages/opencode/test/session/prompt.test.ts b/packages/opencode/test/session/prompt.test.ts index 4c4647457814..ceedd1a105f7 100644 --- a/packages/opencode/test/session/prompt.test.ts +++ b/packages/opencode/test/session/prompt.test.ts @@ -2187,6 +2187,41 @@ it.instance( // Agent variant +noLLMServer.instance( + "prompt without agent and model preserves current session agent and model", + () => + Effect.gen(function* () { + const prompt = yield* SessionPrompt.Service + const sessions = yield* Session.Service + const session = yield* sessions.create({}) + + yield* prompt.prompt({ + sessionID: session.id, + agent: "build", + model: ref, + noReply: true, + parts: [{ type: "text", text: "hello" }], + }) + + const next = yield* prompt.prompt({ + sessionID: session.id, + noReply: true, + parts: [{ type: "text", text: "hello again" }], + }) + if (next.info.role !== "user") throw new Error("expected user message") + expect(next.info.agent).toBe("build") + expect(next.info.model).toEqual(ref) + + yield* sessions.remove(session.id) + }), + { + config: { + ...cfg, + default_agent: "plan", + }, + }, +) + noLLMServer.instance( "applies agent variant only when using agent model", () => @@ -2256,6 +2291,7 @@ noLLMServer.instance( }, ) + // Agent / command resolution errors noLLMServer.instance(