diff --git a/packages/server/src/server/agent/provider-registry.test.ts b/packages/server/src/server/agent/provider-registry.test.ts index 1575bcaaa..f2946b0dc 100644 --- a/packages/server/src/server/agent/provider-registry.test.ts +++ b/packages/server/src/server/agent/provider-registry.test.ts @@ -905,4 +905,72 @@ describe("model merging", () => { }, ]); }); + + test("built-in createClient().listModels() honors profile model replacement (issue #579)", async () => { + mockState.runtimeModels.set("claude", [ + { + provider: "claude", + id: "runtime-default", + label: "Runtime Default", + isDefault: true, + }, + ]); + + const registry = buildProviderRegistry(logger, { + providerOverrides: { + claude: { + models: [ + { + id: "profile-fast", + label: "Profile Fast", + isDefault: true, + }, + ], + }, + }, + }); + + const client = registry.claude.createClient(logger); + const models = await client.listModels({ + cwd: "/tmp/registry-models", + force: false, + }); + + expect(models.map((model) => model.id)).toEqual(["profile-fast"]); + expect(models.find((model) => model.isDefault)?.id).toBe("profile-fast"); + }); + + test("built-in createClient().listModels() honors additionalModels default (issue #579)", async () => { + mockState.runtimeModels.set("claude", [ + { + provider: "claude", + id: "runtime-default", + label: "Runtime Default", + isDefault: true, + }, + ]); + + const registry = buildProviderRegistry(logger, { + providerOverrides: { + claude: { + additionalModels: [ + { + id: "profile-default", + label: "Profile Default", + isDefault: true, + }, + ], + }, + }, + }); + + const client = registry.claude.createClient(logger); + const models = await client.listModels({ + cwd: "/tmp/registry-models", + force: false, + }); + + const defaultModel = models.find((model) => model.isDefault) ?? models[0]; + expect(defaultModel?.id).toBe("profile-default"); + }); }); diff --git a/packages/server/src/server/agent/provider-registry.ts b/packages/server/src/server/agent/provider-registry.ts index 2d913ac8c..6bbeb1fb6 100644 --- a/packages/server/src/server/agent/provider-registry.ts +++ b/packages/server/src/server/agent/provider-registry.ts @@ -308,7 +308,12 @@ function wrapSessionProvider(provider: AgentProvider, inner: AgentSession): Agen }; } -function wrapClientProvider(provider: AgentProvider, inner: AgentClient): AgentClient { +function wrapClientProvider( + provider: AgentProvider, + inner: AgentClient, + profileModels: ProviderProfileModel[], + additionalModels: ProviderProfileModel[], +): AgentClient { const listPersistedAgents = inner.listPersistedAgents?.bind(inner); return { @@ -343,7 +348,7 @@ function wrapClientProvider(provider: AgentProvider, inner: AgentClient): AgentC ), ), listModels: async (options) => - (await inner.listModels(options)).map((model) => mapModel(provider, model)), + mergeModels(provider, profileModels, additionalModels, await inner.listModels(options)), listModes: inner.listModes?.bind(inner), listPersistedAgents: listPersistedAgents ? async (options?: ListPersistedAgentsOptions) => @@ -398,7 +403,12 @@ function createResolvedProviderClient( resolved: ResolvedProvider, ): AgentClient { const inner = resolved.createBaseClient(logger); - return inner.provider === provider ? inner : wrapClientProvider(provider, inner); + const hasModelOverrides = + resolved.profileModels.length > 0 || resolved.additionalModels.length > 0; + if (inner.provider === provider && !hasModelOverrides) { + return inner; + } + return wrapClientProvider(provider, inner, resolved.profileModels, resolved.additionalModels); } function buildResolvedBuiltinProviders(