UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

171 lines (170 loc) 8.08 kB
import { l as normalizeOptionalString, o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js"; import { r as normalizeProviderId } from "./provider-id-DMd-TDFp.js"; import { n as buildModelCatalogRef } from "./model-catalog-refs-BdjEHOKQ.js"; import { r as normalizeConfiguredProviderCatalogModelId } from "./provider-model-id-normalization-BFjPahr6.js"; import { t as normalizeModelCatalog } from "./model-catalog-normalize-Cvl7-6m6.js"; import { n as copyRecordEntries } from "./safe-record-CjQoFebO.js"; //#region src/plugins/provider-catalog.ts function addApiKeyToProvider(provider, apiKey) { try { return { ...provider, apiKey }; } catch { return; } } /** Finds a provider catalog template entry by normalized provider and template id. */ function findCatalogTemplate(params) { return params.templateIds.map((templateId) => params.entries.find((entry) => normalizeProviderId(entry.provider) === normalizeProviderId(params.providerId) && normalizeLowercaseStringOrEmpty(entry.id) === normalizeLowercaseStringOrEmpty(templateId))).find((entry) => entry !== void 0); } /** Builds a provider catalog result for providers that share one API key. */ async function buildSingleProviderApiKeyCatalog(params) { const providerId = normalizeProviderId(params.providerId); const apiKey = params.ctx.resolveProviderApiKey(providerId).apiKey; if (!apiKey) return null; const explicitProvider = params.allowExplicitBaseUrl && params.ctx.config.models?.providers ? Object.entries(params.ctx.config.models.providers).find(([configuredProviderId]) => normalizeProviderId(configuredProviderId) === providerId)?.[1] : void 0; const explicitBaseUrl = normalizeOptionalString(explicitProvider?.baseUrl) ?? ""; return { provider: { ...await params.buildProvider(), ...explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}, apiKey } }; } /** Builds a multi-provider catalog result backed by one provider API key. */ async function buildPairedProviderApiKeyCatalog(params) { const apiKey = params.ctx.resolveProviderApiKey(normalizeProviderId(params.providerId)).apiKey; if (!apiKey) return null; const providers = await params.buildProviders(); return { providers: Object.fromEntries(copyRecordEntries(providers).flatMap(([id, provider]) => { const providerWithApiKey = addApiKeyToProvider(provider, apiKey); return providerWithApiKey ? [[id, providerWithApiKey]] : []; })) }; } function countRawManifestCatalogModels(catalog) { if (!catalog || typeof catalog !== "object") return; const models = catalog.models; return Array.isArray(models) ? models.length : void 0; } /** Reads a provider's normalized manifest default as a fully qualified model ref. */ function readManifestProviderDefaultModelRef(manifest, providerId) { const catalog = manifest?.modelCatalog?.providers?.[providerId]; const defaultModel = normalizeOptionalString(catalog?.defaultModel); return defaultModel ? buildModelCatalogRef(providerId, defaultModel) : void 0; } function cloneManifestCatalogTieredCost(tier) { return { input: tier.input, output: tier.output, cacheRead: tier.cacheRead, cacheWrite: tier.cacheWrite, range: tier.range.length === 1 ? [tier.range[0]] : [tier.range[0], tier.range[1]] }; } function cloneManifestCatalogCost(cost) { return { input: cost.input ?? 0, output: cost.output ?? 0, cacheRead: cost.cacheRead ?? 0, cacheWrite: cost.cacheWrite ?? 0, ...cost.tieredPricing ? { tieredPricing: cost.tieredPricing.map(cloneManifestCatalogTieredCost) } : {} }; } function buildManifestCatalogModelInput(model, filterDocument = false) { if (!filterDocument && model.input?.includes("document")) throw new Error(`Manifest modelCatalog row ${model.id} uses unsupported runtime input document`); return model.input?.filter((item) => item !== "document") ?? ["text"]; } function cloneManifestCatalogMediaInput(mediaInput) { if (!mediaInput?.image) return; return { image: { ...mediaInput.image } }; } function buildManifestCatalogModel(model, options = {}) { if (model.contextWindow === void 0) throw new Error(`Manifest modelCatalog row ${model.id} is missing contextWindow`); if (model.maxTokens === void 0) throw new Error(`Manifest modelCatalog row ${model.id} is missing maxTokens`); const id = options.providerId ? normalizeConfiguredProviderCatalogModelId(options.providerId, model.id, /* @__PURE__ */ new Map()) : model.id; return { id, name: model.name ?? id, ...model.api ? { api: model.api } : {}, ...model.baseUrl ? { baseUrl: model.baseUrl } : {}, reasoning: model.reasoning ?? false, input: buildManifestCatalogModelInput(model, options.filterDocument), cost: cloneManifestCatalogCost(model.cost ?? {}), contextWindow: model.contextWindow, ...model.contextTokens !== void 0 ? { contextTokens: model.contextTokens } : {}, maxTokens: model.maxTokens, ...model.thinkingLevelMap ? { thinkingLevelMap: { ...model.thinkingLevelMap } } : {}, ...model.headers ? { headers: { ...model.headers } } : {}, ...model.compat ? { compat: { ...model.compat } } : {}, ...model.mediaInput ? { mediaInput: cloneManifestCatalogMediaInput(model.mediaInput) } : {} }; } /** * Converts a plugin manifest modelCatalog provider into runtime provider config. */ function buildManifestModelProviderConfig(params) { const catalog = normalizeModelCatalog({ providers: { [params.providerId]: params.catalog } }, { ownedProviders: /* @__PURE__ */ new Set([params.providerId]) })?.providers?.[params.providerId]; if (!catalog) throw new Error(`Missing modelCatalog.providers.${params.providerId}`); if (!catalog.baseUrl) throw new Error(`Missing modelCatalog.providers.${params.providerId}.baseUrl`); const rawModelCount = countRawManifestCatalogModels(params.catalog); if (rawModelCount !== void 0 && rawModelCount !== catalog.models.length) throw new Error(`Invalid modelCatalog.providers.${params.providerId}.models`); return { baseUrl: catalog.baseUrl, ...catalog.api ? { api: catalog.api } : {}, ...catalog.headers ? { headers: { ...catalog.headers } } : {}, models: catalog.models.map((model) => buildManifestCatalogModel(model, { providerId: params.providerId })) }; } /** Builds runtime provider config from planner-normalized manifest rows. */ function buildEffectiveManifestProviderConfig(rows) { const firstRow = rows[0]; if (!firstRow?.baseUrl || !firstRow.api) return; const models = rows.flatMap((row) => !row.contextWindow || !row.maxTokens ? [] : [buildManifestCatalogModel(row, { filterDocument: true })]); return models.length > 0 ? { baseUrl: firstRow.baseUrl, api: firstRow.api, models } : void 0; } /** Projects an ordered family of manifest catalogs into static provider and model surfaces. */ function buildManifestProviderCatalogFamily(params) { const entries = params.surfaces.map((surface) => { const buildProvider = () => buildManifestModelProviderConfig({ providerId: surface.id, catalog: surface.catalog }); const provider = buildProvider(); return { id: surface.id, label: surface.label, baseUrl: provider.baseUrl, models: provider.models, buildProvider }; }); return { entries, staticDiscovery: entries.map(({ id, label, buildProvider }) => ({ id, label, docsPath: params.docsPath ?? "/providers/models", auth: [], staticCatalog: { order: "simple", run: async () => ({ provider: buildProvider() }) } })), staticCatalog: async () => ({ providers: Object.fromEntries(entries.map(({ id, buildProvider }) => [id, buildProvider()])) }), augmentModelCatalog: () => entries.flatMap(({ id: provider, models }) => models.map((entry) => ({ provider, id: entry.id, name: entry.name, reasoning: entry.reasoning, input: [...entry.input], contextWindow: entry.contextWindow }))) }; } //#endregion export { buildSingleProviderApiKeyCatalog as a, buildPairedProviderApiKeyCatalog as i, buildManifestModelProviderConfig as n, findCatalogTemplate as o, buildManifestProviderCatalogFamily as r, readManifestProviderDefaultModelRef as s, buildEffectiveManifestProviderConfig as t };