Skip to content

Commit ec1a940

Browse files
committed
fix(agents): preserve built-in model refs for subagents
1 parent 92c59f3 commit ec1a940

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

src/agents/model-selection.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2938,6 +2938,27 @@ describe("resolveSubagentSpawnModelSelection", () => {
29382938
).toBe("openai/gpt-5.4");
29392939
});
29402940

2941+
it("keeps exact built-in provider/model overrides before slash-form aliases", () => {
2942+
const cfg = {
2943+
agents: {
2944+
defaults: {
2945+
model: { primary: "anthropic/claude-sonnet-4-6" },
2946+
models: {
2947+
"openrouter/openai/gpt-5.4": { alias: "openai/gpt-5.4" },
2948+
},
2949+
},
2950+
},
2951+
} as OpenClawConfig;
2952+
2953+
expect(
2954+
resolveSubagentSpawnModelSelection({
2955+
cfg,
2956+
agentId: "main",
2957+
modelOverride: "openai/gpt-5.4",
2958+
}),
2959+
).toBe("openai/gpt-5.4");
2960+
});
2961+
29412962
it("resolves slash-form alias overrides before provider/model passthrough", () => {
29422963
const cfg = {
29432964
agents: {

src/agents/model-selection.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ export {
9090
};
9191
export { isCliProvider } from "./model-selection-cli.js";
9292

93+
const BUILT_IN_EXACT_REF_PROVIDER_IDS = new Set([
94+
"anthropic",
95+
"azure-openai",
96+
"google",
97+
"google-vertex",
98+
"mistral",
99+
"openai",
100+
]);
101+
93102
function normalizePersistedDefaultProvider(value: unknown): string {
94103
return normalizeOptionalString(value) ?? DEFAULT_PROVIDER;
95104
}
@@ -341,12 +350,18 @@ export function resolveSubagentConfiguredModelSelection(params: {
341350
* a fully qualified `provider/model` string. If the value is already qualified
342351
* or not a known alias, returns it unchanged.
343352
*/
344-
function hasExactConfiguredProviderModelRef(cfg: OpenClawConfig, raw: string): boolean {
353+
function hasExactKnownProviderModelRef(cfg: OpenClawConfig, raw: string): boolean {
345354
if (!hasExplicitProviderModelRef(raw)) {
346355
return false;
347356
}
348357
const providerRaw = raw.slice(0, raw.indexOf("/")).trim();
349-
if (!providerRaw || !cfg.models?.providers) {
358+
if (!providerRaw) {
359+
return false;
360+
}
361+
if (BUILT_IN_EXACT_REF_PROVIDER_IDS.has(normalizeProviderId(providerRaw))) {
362+
return true;
363+
}
364+
if (!cfg.models?.providers) {
350365
return false;
351366
}
352367
const providerKey = normalizeLowercaseStringOrEmpty(providerRaw);
@@ -360,7 +375,7 @@ function resolveModelThroughAliases(
360375
aliasIndex: ModelAliasIndex,
361376
cfg: OpenClawConfig,
362377
): string {
363-
if (hasExactConfiguredProviderModelRef(cfg, value)) {
378+
if (hasExactKnownProviderModelRef(cfg, value)) {
364379
return value;
365380
}
366381
const aliasKey = normalizeLowercaseStringOrEmpty(value);

0 commit comments

Comments
 (0)