Skip to content

Commit 5a5c8bf

Browse files
committed
fix(models): keep bundled provider catalog when configured base URL is blank
A models.providers.<id> entry with a blank baseUrl ("") erased the bundled provider catalog from the generated model registry. The empty base URL flowed into provider discovery and the catalog merge, where it overrode the bundled transport URL; the resulting provider then failed isWritableProviderConfig and was dropped from models.json entirely. For Google this meant gemini-2.5-flash and gemini-flash-latest stopped resolving on the embedded runtime with model_not_found, even though the bundled Google catalog and forward-compat resolver know those ids. This hit users in merge mode whose config was partially written by a plugin. Strip blank provider base URLs before discovery and merge so a blank value means "use the provider default" instead of clobbering it. Fixes #91270
1 parent 5c53918 commit 5a5c8bf

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

src/agents/models-config.plan.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,11 @@ export async function resolveProvidersForModelsJsonWithDeps(
107107
resolveImplicitProviders?: ResolveImplicitProvidersForModelsJson;
108108
},
109109
): Promise<Record<string, ProviderConfig>> {
110-
const { cfg, agentDir, env } = params;
111-
const explicitProviders = cfg.models?.providers ?? {};
110+
const { agentDir, env } = params;
111+
const explicitProviders = stripBlankProviderBaseUrls(params.cfg.models?.providers ?? {});
112+
const cfg = params.cfg.models?.providers
113+
? { ...params.cfg, models: { ...params.cfg.models, providers: explicitProviders } }
114+
: params.cfg;
112115
const resolveImplicitProvidersImpl = deps?.resolveImplicitProviders ?? resolveImplicitProviders;
113116
const implicitProviders = await resolveImplicitProvidersImpl({
114117
agentDir,
@@ -133,6 +136,23 @@ export async function resolveProvidersForModelsJsonWithDeps(
133136
});
134137
}
135138

139+
function stripBlankProviderBaseUrls(
140+
providers: Record<string, ProviderConfig>,
141+
): Record<string, ProviderConfig> {
142+
let mutated = false;
143+
const next: Record<string, ProviderConfig> = {};
144+
for (const [key, provider] of Object.entries(providers)) {
145+
if (typeof provider?.baseUrl === "string" && provider.baseUrl.trim() === "") {
146+
const { baseUrl: _blank, ...rest } = provider;
147+
next[key] = rest as ProviderConfig;
148+
mutated = true;
149+
continue;
150+
}
151+
next[key] = provider;
152+
}
153+
return mutated ? next : providers;
154+
}
155+
136156
function resolveProvidersForMode(params: {
137157
mode: NonNullable<ModelsConfig["mode"]>;
138158
existingParsed: unknown;

0 commit comments

Comments
 (0)