diff --git a/packages/opencode/src/acp/directory.ts b/packages/opencode/src/acp/directory.ts index 2301c8929a88..36304feed15a 100644 --- a/packages/opencode/src/acp/directory.ts +++ b/packages/opencode/src/acp/directory.ts @@ -121,6 +121,11 @@ export const loaderLayer = Layer.effect( [agent.list(), agent.defaultInfo(), command.list(), provider.defaultModel().pipe(Effect.option)], { concurrency: "unbounded" }, ) + const agentModel = defaultAgent.model + ? providers[defaultAgent.model.providerID]?.models[defaultAgent.model.modelID] + ? { providerID: defaultAgent.model.providerID, modelID: defaultAgent.model.modelID } + : undefined + : undefined return build({ directory, providers, @@ -133,7 +138,11 @@ export const loaderLayer = Layer.effect( })), defaultModeID: defaultAgent.name, commands: commands.toSorted((a, b) => a.name.localeCompare(b.name)), - ...(defaultModel._tag === "Some" ? { defaultModel: defaultModel.value } : {}), + ...(agentModel + ? { defaultModel: agentModel } + : defaultModel._tag === "Some" + ? { defaultModel: defaultModel.value } + : {}), }) }).pipe(Effect.provideService(InstanceRef, ctx)) }), diff --git a/packages/opencode/src/acp/service.ts b/packages/opencode/src/acp/service.ts index 55fbc9681df3..9188e92ac53c 100644 --- a/packages/opencode/src/acp/service.ts +++ b/packages/opencode/src/acp/service.ts @@ -748,8 +748,17 @@ async function loadDirectorySnapshot(sdk: OpencodeClient, directory: string) { ProviderV2.ID, Provider.Info > + const defaultAgent = agents.find((agent) => agent.mode === "primary" && agent.hidden !== true) + const defaultAgentModel = defaultAgent?.model + ? providers[ProviderV2.ID.make(defaultAgent.model.providerID)]?.models[ModelV2.ID.make(defaultAgent.model.modelID)] + ? { + providerID: ProviderV2.ID.make(defaultAgent.model.providerID), + modelID: ModelV2.ID.make(defaultAgent.model.modelID), + } + : undefined + : undefined const defaultModelStarted = performance.now() - const defaultModel = defaultModelFromConfig(configResponse?.data?.model, providers) + const defaultModel = defaultAgentModel ?? defaultModelFromConfig(configResponse?.data?.model, providers) ACPProfile.duration("acp.directory.defaultModel.resolve", defaultModelStarted, { configured: !!defaultModel }) const modes = agents .filter((agent) => agent.mode !== "subagent" && agent.hidden !== true) @@ -775,7 +784,7 @@ async function loadDirectorySnapshot(sdk: OpencodeClient, directory: string) { directory, providers, modes, - defaultModeID: agents.find((agent) => agent.mode === "primary" && agent.hidden !== true)?.name ?? "build", + defaultModeID: defaultAgent?.name ?? "build", commands: commands.toSorted((a, b) => a.name.localeCompare(b.name)), ...(defaultModel ? { defaultModel } : {}), }) diff --git a/packages/opencode/test/acp/service-session.test.ts b/packages/opencode/test/acp/service-session.test.ts index d784709dbb2a..2693915dfc89 100644 --- a/packages/opencode/test/acp/service-session.test.ts +++ b/packages/opencode/test/acp/service-session.test.ts @@ -731,6 +731,46 @@ describe("ACP service sessions", () => { expect(result.configOptions?.find((option) => option.id === "model")?.currentValue).toBe("test/configured-model") }) + it("prefers the default agent's assigned model over the configured model", async () => { + const sdk = { + config: { + providers: () => Promise.resolve({ data: { providers: [provider], default: { test: modelID } } }), + get: () => Promise.resolve({ data: { model: "test/configured-model" } }), + }, + app: { + agents: () => + Promise.resolve({ + data: [ + { + name: "build", + mode: "primary", + permission: [], + options: {}, + model: { providerID: "test", modelID: "second-model" }, + }, + ], + }), + skills: () => Promise.resolve({ data: [] }), + }, + command: { + list: () => Promise.resolve({ data: [] }), + }, + session: { + create: (input: { model?: { id?: string } }) => Promise.resolve({ data: { id: input.model?.id } }), + list: () => Promise.resolve({ data: [] }), + }, + mcp: { + add: () => Promise.resolve({ data: {} }), + }, + } as unknown as OpencodeClient + const service = ACPService.make({ sdk }) + + const result = await Effect.runPromise(service.newSession({ cwd: "/workspace", mcpServers: [] })) + + expect(result.sessionId).toBe("second-model") + expect(result.configOptions?.find((option) => option.id === "model")?.currentValue).toBe("test/second-model") + }) + it("does not scan last-used sessions when resolving the new session default", async () => { const historyCalls: string[] = [] const sdk = {