fix: keep manifest suppression on static model lists

This commit is contained in:
Shakker
2026-04-27 17:01:06 +01:00
parent 13feb1b284
commit c896d42cc4
3 changed files with 86 additions and 5 deletions

View File

@@ -4,10 +4,9 @@ import { resolveProviderBuiltInModelSuppression } from "../plugins/provider-runt
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { normalizeProviderId } from "./provider-id.js";
function resolveBuiltInModelSuppression(params: {
function resolveBuiltInModelSuppressionFromManifest(params: {
provider?: string | null;
id?: string | null;
baseUrl?: string | null;
config?: OpenClawConfig;
}) {
const provider = normalizeProviderId(params.provider ?? "");
@@ -15,15 +14,29 @@ function resolveBuiltInModelSuppression(params: {
if (!provider || !modelId) {
return undefined;
}
const manifestResult = resolveManifestBuiltInModelSuppression({
return resolveManifestBuiltInModelSuppression({
provider,
id: modelId,
...(params.config ? { config: params.config } : {}),
env: process.env,
});
}
function resolveBuiltInModelSuppression(params: {
provider?: string | null;
id?: string | null;
baseUrl?: string | null;
config?: OpenClawConfig;
}) {
const manifestResult = resolveBuiltInModelSuppressionFromManifest(params);
if (manifestResult?.suppress) {
return manifestResult;
}
const provider = normalizeProviderId(params.provider ?? "");
const modelId = normalizeLowercaseStringOrEmpty(params.id);
if (!provider || !modelId) {
return undefined;
}
return resolveProviderBuiltInModelSuppression({
...(params.config ? { config: params.config } : {}),
env: process.env,
@@ -37,6 +50,14 @@ function resolveBuiltInModelSuppression(params: {
});
}
export function shouldSuppressBuiltInModelFromManifest(params: {
provider?: string | null;
id?: string | null;
config?: OpenClawConfig;
}) {
return resolveBuiltInModelSuppressionFromManifest(params)?.suppress ?? false;
}
export function shouldSuppressBuiltInModel(params: {
provider?: string | null;
id?: string | null;

View File

@@ -6,6 +6,7 @@ const mocks = vi.hoisted(() => ({
shouldSuppressBuiltInModel: vi.fn(() => {
throw new Error("runtime model suppression should be skipped");
}),
shouldSuppressBuiltInModelFromManifest: vi.fn(() => false),
loadProviderCatalogModelsForList: vi.fn().mockResolvedValue([
{
id: "gpt-5.5",
@@ -21,6 +22,7 @@ const mocks = vi.hoisted(() => ({
vi.mock("../../agents/model-suppression.js", () => ({
shouldSuppressBuiltInModel: mocks.shouldSuppressBuiltInModel,
shouldSuppressBuiltInModelFromManifest: mocks.shouldSuppressBuiltInModelFromManifest,
}));
vi.mock("./list.provider-catalog.js", () => ({
@@ -76,6 +78,14 @@ describe("appendProviderCatalogRows", () => {
});
expect(mocks.shouldSuppressBuiltInModel).not.toHaveBeenCalled();
expect(mocks.shouldSuppressBuiltInModelFromManifest).toHaveBeenCalledWith({
provider: "codex",
id: "gpt-5.5",
config: {
agents: { defaults: { model: { primary: "codex/gpt-5.5" } } },
models: { providers: {} },
},
});
expect(rows).toMatchObject([
{
key: "codex/gpt-5.5",
@@ -84,4 +94,47 @@ describe("appendProviderCatalogRows", () => {
},
]);
});
it("applies manifest suppression when runtime model-suppression hooks are skipped", async () => {
mocks.loadProviderCatalogModelsForList.mockResolvedValueOnce([
{
id: "gpt-5.3-codex-spark",
name: "GPT-5.3 Codex Spark",
provider: "openai",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
input: ["text", "image"],
},
]);
mocks.shouldSuppressBuiltInModelFromManifest.mockReturnValueOnce(true);
const rows: ModelRow[] = [];
await appendProviderCatalogRows({
rows,
seenKeys: new Set(),
context: {
cfg: {
agents: { defaults: { model: { primary: "openai/gpt-5.5" } } },
models: { providers: {} },
},
agentDir: "/tmp/openclaw-agent",
authStore: { version: 1, profiles: {}, order: {} },
configuredByKey: new Map(),
discoveredKeys: new Set(),
filter: { provider: "openai", local: false },
skipRuntimeModelSuppression: true,
},
});
expect(mocks.shouldSuppressBuiltInModel).not.toHaveBeenCalled();
expect(mocks.shouldSuppressBuiltInModelFromManifest).toHaveBeenCalledWith({
provider: "openai",
id: "gpt-5.3-codex-spark",
config: {
agents: { defaults: { model: { primary: "openai/gpt-5.5" } } },
models: { providers: {} },
},
});
expect(rows).toEqual([]);
});
});

View File

@@ -7,7 +7,10 @@ import {
resolveAwsSdkEnvVarName,
resolveEnvApiKey,
} from "../../agents/model-auth.js";
import { shouldSuppressBuiltInModel } from "../../agents/model-suppression.js";
import {
shouldSuppressBuiltInModel,
shouldSuppressBuiltInModelFromManifest,
} from "../../agents/model-suppression.js";
import { normalizeProviderId } from "../../agents/provider-id.js";
import type { ModelDefinitionConfig, ModelProviderConfig } from "../../config/types.models.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
@@ -137,7 +140,11 @@ function shouldSuppressListModel(params: {
context: RowBuilderContext;
}): boolean {
if (params.context.skipRuntimeModelSuppression) {
return false;
return shouldSuppressBuiltInModelFromManifest({
provider: params.model.provider,
id: params.model.id,
config: params.context.cfg,
});
}
return shouldSuppressBuiltInModel({
provider: params.model.provider,