Skip to content

Commit c850631

Browse files
fix(agents): avoid eager alias normalization for default models
1 parent 56633e4 commit c850631

1 file changed

Lines changed: 62 additions & 1 deletion

File tree

src/agents/model-selection.test.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,17 @@ const manifestNormalizationSnapshot = vi.hoisted(() => ({
9797
],
9898
}));
9999

100+
const providerModelNormalizationMock = vi.hoisted(() => ({
101+
normalizeProviderModelIdWithRuntime: vi.fn(() => undefined),
102+
}));
103+
100104
vi.mock("../plugins/current-plugin-metadata-snapshot.js", () => ({
101105
getCurrentPluginMetadataSnapshot: () => manifestNormalizationSnapshot,
102106
}));
103107

104108
vi.mock("./provider-model-normalization.runtime.js", () => ({
105-
normalizeProviderModelIdWithRuntime: () => undefined,
109+
normalizeProviderModelIdWithRuntime:
110+
providerModelNormalizationMock.normalizeProviderModelIdWithRuntime,
106111
}));
107112

108113
vi.mock("./model-selection-cli.js", () => ({
@@ -850,6 +855,36 @@ describe("model-selection", () => {
850855
expect(index.byAlias.get("smart")?.ref).toEqual({ provider: "openai", model: "gpt-4o" });
851856
expect(index.byKey.get(modelKey("anthropic", "claude-3-5-sonnet"))).toEqual(["fast"]);
852857
});
858+
859+
it("does not normalize configured model keys that have no alias", () => {
860+
providerModelNormalizationMock.normalizeProviderModelIdWithRuntime.mockClear();
861+
const models = Object.fromEntries(
862+
Array.from({ length: 25 }, (_, index) => [`openai/gpt-5.5-aliasless-${index}`, {}]),
863+
);
864+
const cfg: Partial<OpenClawConfig> = {
865+
agents: {
866+
defaults: {
867+
models: {
868+
...models,
869+
"openai/gpt-5.5-mini": { alias: "mini" },
870+
},
871+
},
872+
},
873+
};
874+
875+
const index = buildModelAliasIndex({
876+
cfg: cfg as OpenClawConfig,
877+
defaultProvider: "openai",
878+
});
879+
880+
expect(index.byAlias.get("mini")?.ref).toEqual({
881+
provider: "openai",
882+
model: "gpt-5.5-mini",
883+
});
884+
expect(
885+
providerModelNormalizationMock.normalizeProviderModelIdWithRuntime,
886+
).toHaveBeenCalledTimes(1);
887+
});
853888
});
854889

855890
describe("buildAllowedModelSet", () => {
@@ -1770,6 +1805,32 @@ describe("model-selection", () => {
17701805
expect(result).toEqual({ provider: "openai", model: "gpt-5.5" });
17711806
});
17721807

1808+
it("resolves provider-qualified defaults without normalizing every aliasless configured model", () => {
1809+
providerModelNormalizationMock.normalizeProviderModelIdWithRuntime.mockClear();
1810+
const models = Object.fromEntries(
1811+
Array.from({ length: 25 }, (_, index) => [`anthropic/claude-extra-${index}`, {}]),
1812+
);
1813+
const cfg = {
1814+
agents: {
1815+
defaults: {
1816+
model: { primary: "openai/gpt-5.5" },
1817+
models,
1818+
},
1819+
},
1820+
} as OpenClawConfig;
1821+
1822+
const result = resolveConfiguredModelRef({
1823+
cfg,
1824+
defaultProvider: "anthropic",
1825+
defaultModel: "claude-sonnet-4-6",
1826+
});
1827+
1828+
expect(result).toEqual({ provider: "openai", model: "gpt-5.5" });
1829+
expect(
1830+
providerModelNormalizationMock.normalizeProviderModelIdWithRuntime,
1831+
).toHaveBeenCalledTimes(1);
1832+
});
1833+
17731834
it("should use default provider/model if config is empty", () => {
17741835
const cfg: Partial<OpenClawConfig> = {};
17751836
const result = resolveConfiguredModelRef({

0 commit comments

Comments
 (0)