refactor(providers): share catalog template matcher

This commit is contained in:
Peter Steinberger
2026-03-17 04:04:12 +00:00
parent a20b64cd92
commit 0a6140acfa
4 changed files with 33 additions and 32 deletions

View File

@@ -1,4 +1,5 @@
import { normalizeModelCompat } from "../../src/agents/model-compat.js";
import { findCatalogTemplate } from "../../src/plugins/provider-catalog.js";
import type {
ProviderResolveDynamicModelContext,
ProviderRuntimeModel,
@@ -48,18 +49,4 @@ export function cloneFirstTemplateModel(params: {
return undefined;
}
export function findCatalogTemplate(params: {
entries: ReadonlyArray<{ provider: string; id: string }>;
providerId: string;
templateIds: readonly string[];
}) {
return params.templateIds
.map((templateId) =>
params.entries.find(
(entry) =>
entry.provider.toLowerCase() === params.providerId.toLowerCase() &&
entry.id.toLowerCase() === templateId.toLowerCase(),
),
)
.find((entry) => entry !== undefined);
}
export { findCatalogTemplate };

View File

@@ -1,4 +1,5 @@
import { normalizeProviderId } from "../agents/provider-id.js";
import { findCatalogTemplate } from "./provider-catalog.js";
import type {
ProviderAugmentModelCatalogContext,
ProviderBuiltInModelSuppressionContext,
@@ -9,22 +10,6 @@ const OPENAI_CODEX_PROVIDER_ID = "openai-codex";
const OPENAI_DIRECT_SPARK_MODEL_ID = "gpt-5.3-codex-spark";
const SUPPRESSED_SPARK_PROVIDERS = new Set(["openai", "azure-openai-responses"]);
function findCatalogTemplate(params: {
entries: ReadonlyArray<{ provider: string; id: string }>;
providerId: string;
templateIds: readonly string[];
}) {
return params.templateIds
.map((templateId) =>
params.entries.find(
(entry) =>
entry.provider.toLowerCase() === params.providerId.toLowerCase() &&
entry.id.toLowerCase() === templateId.toLowerCase(),
),
)
.find((entry) => entry !== undefined);
}
export function resolveBundledProviderBuiltInModelSuppression(
context: ProviderBuiltInModelSuppressionContext,
) {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { buildSingleProviderApiKeyCatalog } from "./provider-catalog.js";
import { buildSingleProviderApiKeyCatalog, findCatalogTemplate } from "./provider-catalog.js";
import type { ProviderCatalogContext } from "./types.js";
function createCatalogContext(params: {
@@ -17,6 +17,19 @@ function createCatalogContext(params: {
}
describe("buildSingleProviderApiKeyCatalog", () => {
it("matches provider templates case-insensitively", () => {
const result = findCatalogTemplate({
entries: [
{ provider: "OpenAI", id: "gpt-5.2" },
{ provider: "other", id: "fallback" },
],
providerId: "openai",
templateIds: ["missing", "GPT-5.2"],
});
expect(result).toEqual({ provider: "OpenAI", id: "gpt-5.2" });
});
it("returns null when api key is missing", async () => {
const result = await buildSingleProviderApiKeyCatalog({
ctx: createCatalogContext({}),

View File

@@ -1,6 +1,22 @@
import type { ModelProviderConfig } from "../config/types.js";
import type { ProviderCatalogContext, ProviderCatalogResult } from "./types.js";
export function findCatalogTemplate(params: {
entries: ReadonlyArray<{ provider: string; id: string }>;
providerId: string;
templateIds: readonly string[];
}) {
return params.templateIds
.map((templateId) =>
params.entries.find(
(entry) =>
entry.provider.toLowerCase() === params.providerId.toLowerCase() &&
entry.id.toLowerCase() === templateId.toLowerCase(),
),
)
.find((entry) => entry !== undefined);
}
export async function buildSingleProviderApiKeyCatalog(params: {
ctx: ProviderCatalogContext;
providerId: string;