diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index eb116f6b960f..1cb9225d0f02 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -633,7 +633,13 @@ 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).pipe(Effect.provideService(Database.Service, database))).findLast( + (m): m is SessionV1.WithParts & { info: SessionV1.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) @@ -643,7 +649,7 @@ const layer = Layer.effect( throw error } - 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 491ad06aaf47..6efddac5423b 100644 --- a/packages/opencode/test/session/prompt.test.ts +++ b/packages/opencode/test/session/prompt.test.ts @@ -2244,6 +2244,41 @@ it.instance("records aborted errors when prompt is cancelled mid-stream", () => // 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", () => @@ -2313,6 +2348,7 @@ noLLMServer.instance( }, ) + // Agent / command resolution errors noLLMServer.instance(