fix: normalize catalog provider ids for probe model selection

This commit is contained in:
Tak Hoffman
2026-03-27 20:56:23 -05:00
parent e890cde041
commit 50c87c4682
2 changed files with 51 additions and 3 deletions

View File

@@ -1,10 +1,12 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { AuthProfileStore } from "../../agents/auth-profiles.js";
import { OLLAMA_LOCAL_AUTH_MARKER } from "../../agents/model-auth-markers.js";
import type { ModelCatalogEntry } from "../../agents/model-catalog.js";
import type { OpenClawConfig } from "../../config/config.js";
let mockStore: AuthProfileStore;
let mockAllowedProfiles: string[];
const loadModelCatalogMock = vi.fn<() => Promise<ModelCatalogEntry[]>>(async () => []);
const resolveAuthProfileOrderMock = vi.fn(() => mockAllowedProfiles);
const resolveAuthProfileEligibilityMock = vi.fn(() => ({
@@ -14,7 +16,7 @@ const resolveAuthProfileEligibilityMock = vi.fn(() => ({
const resolveSecretRefStringMock = vi.fn(async () => "resolved-secret");
vi.mock("../../agents/model-catalog.js", () => ({
loadModelCatalog: vi.fn(async () => []),
loadModelCatalog: loadModelCatalogMock,
}));
vi.mock("../../secrets/resolve.js", () => ({
resolveSecretRefString: resolveSecretRefStringMock,
@@ -130,6 +132,8 @@ describe("buildProbeTargets reason codes", () => {
},
};
mockAllowedProfiles = [];
loadModelCatalogMock.mockReset();
loadModelCatalogMock.mockResolvedValue([]);
resolveAuthProfileOrderMock.mockClear();
resolveAuthProfileEligibilityMock.mockClear();
resolveSecretRefStringMock.mockReset();
@@ -217,4 +221,48 @@ describe("buildProbeTargets reason codes", () => {
);
});
});
it("matches canonical providers against alias-valued catalog probe models", async () => {
mockStore = {
version: 1,
profiles: {},
order: {},
};
loadModelCatalogMock.mockResolvedValueOnce([
{ provider: "z.ai", id: "glm-4.7", name: "GLM-4.7" },
]);
const plan = await buildProbeTargets({
cfg: {
models: {
providers: {
zai: {
baseUrl: "https://api.z.ai/v1",
api: "openai-responses",
apiKey: "sk-zai-test", // pragma: allowlist secret
models: [],
},
},
},
} as OpenClawConfig,
providers: ["zai"],
modelCandidates: [],
options: {
timeoutMs: 5_000,
concurrency: 1,
maxTokens: 16,
},
});
expect(plan.results).toEqual([]);
expect(plan.targets).toHaveLength(1);
expect(plan.targets[0]).toEqual(
expect.objectContaining({
provider: "zai",
model: { provider: "zai", model: "glm-4.7" },
source: "models.json",
label: "models.json",
}),
);
});
});

View File

@@ -147,9 +147,9 @@ function selectProbeModel(params: {
if (direct && direct.length > 0) {
return { provider, model: direct[0] };
}
const fromCatalog = catalog.find((entry) => entry.provider === provider);
const fromCatalog = catalog.find((entry) => normalizeProviderId(entry.provider) === provider);
if (fromCatalog) {
return { provider: fromCatalog.provider, model: fromCatalog.id };
return { provider, model: fromCatalog.id };
}
return null;
}