























@@ -25,21 +25,37 @@ let readCachedAgentModelCatalogMock: ReturnType<typeof vi.fn>;
2525let writeCachedAgentModelCatalogMock: ReturnType<typeof vi.fn>;
26262727vi.mock("./model-suppression.runtime.js", () => ({
28-shouldSuppressBuiltInModel: (params: { provider?: string; id?: string }) =>
29-isSuppressedModel(params.provider, params.id),
30-buildShouldSuppressBuiltInModel: () => (params: { provider?: string; id?: string }) =>
31-isSuppressedModel(params.provider, params.id),
28+shouldSuppressBuiltInModel: (params: { provider?: string; id?: string; baseUrl?: string }) =>
29+isSuppressedModel(params.provider, params.id, params.baseUrl),
30+buildShouldSuppressBuiltInModel:
31+() => (params: { provider?: string; id?: string; baseUrl?: string }) =>
32+isSuppressedModel(params.provider, params.id, params.baseUrl),
3233}));
333434-function isSuppressedModel(provider?: string, id?: string): boolean {
35+function isDirectOpenAiBaseUrl(baseUrl?: string): boolean {
36+const trimmed = baseUrl?.trim();
37+if (!trimmed) {
38+return true;
39+}
40+try {
41+return new URL(trimmed).hostname.toLowerCase().replace(/\.+$/, "") === "api.openai.com";
42+} catch {
43+return false;
44+}
45+}
46+47+function isSuppressedModel(provider?: string, id?: string, baseUrl?: string): boolean {
3548const modelId = id?.trim().toLowerCase();
3649if (!modelId) {
3750return false;
3851}
39-return (
40-(provider === "openai" || provider === "azure-openai-responses" || provider === "openai") &&
41-modelId === "gpt-5.3-codex-spark"
42-);
52+if (modelId !== "gpt-5.3-codex-spark") {
53+return false;
54+}
55+if (provider === "azure-openai-responses") {
56+return true;
57+}
58+return provider === "openai" && isDirectOpenAiBaseUrl(baseUrl);
4359}
44604561function mockCatalogImportFailThenRecover() {
@@ -1310,6 +1326,31 @@ describe("loadModelCatalog", () => {
13101326expectNoCatalogEntry(result, "openai", "gpt-5.3-codex-spark");
13111327});
131213281329+it("keeps custom endpoint gpt-5.3-codex-spark rows in the catalog", async () => {
1330+mockAgentDiscoveryModels([
1331+{
1332+id: "gpt-5.3-codex-spark",
1333+provider: "openai",
1334+baseUrl: "https://api.openai.com/v1",
1335+name: "GPT-5.3 Codex Spark",
1336+contextWindow: 128000,
1337+input: ["text"],
1338+},
1339+{
1340+id: "gpt-5.3-codex-spark",
1341+provider: "openai",
1342+baseUrl: "https://proxy.example.com/v1",
1343+name: "GPT-5.3 Codex Spark Proxy",
1344+contextWindow: 128000,
1345+input: ["text"],
1346+},
1347+]);
1348+1349+const result = await loadModelCatalog({ config: {} as OpenClawConfig });
1350+const entry = requireCatalogEntry(result, "openai", "gpt-5.3-codex-spark");
1351+expect(entry.name).toBe("GPT-5.3 Codex Spark Proxy");
1352+});
1353+13131354it("keeps available openai 5.1/5.2/5.3 built-ins in the catalog", async () => {
13141355mockAgentDiscoveryModels([
13151356{
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。