diff --git a/src/agents/model-catalog-scope.ts b/src/agents/model-catalog-scope.ts new file mode 100644 index 00000000000..e1c57f9e552 --- /dev/null +++ b/src/agents/model-catalog-scope.ts @@ -0,0 +1,51 @@ +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import { findNormalizedProviderValue, normalizeProviderId } from "./provider-id.js"; + +function dedupeCatalogScopeRefs(values: Array): string[] { + const refs = new Set(); + for (const value of values) { + const trimmed = value?.trim(); + if (trimmed) { + refs.add(trimmed); + } + } + return [...refs]; +} + +function providerFromModelRef(value: string | undefined): string | undefined { + const trimmed = value?.trim(); + if (!trimmed) { + return undefined; + } + const slash = trimmed.indexOf("/"); + if (slash <= 0) { + return undefined; + } + const provider = normalizeProviderId(trimmed.slice(0, slash)); + return provider || undefined; +} + +export function resolveModelCatalogScope(params: { + cfg?: OpenClawConfig; + provider: string; + model: string; +}): { providerRefs: string[]; modelRefs: string[] } { + const provider = params.provider.trim(); + const model = params.model.trim(); + const providerConfig = findNormalizedProviderValue(params.cfg?.models?.providers, provider); + return { + providerRefs: dedupeCatalogScopeRefs([provider, providerConfig?.api]), + modelRefs: dedupeCatalogScopeRefs([provider && model ? `${provider}/${model}` : model, model]), + }; +} + +export function resolveProviderDiscoveryProviderIdsForCatalogScope(params: { + providerRefs?: readonly string[]; + modelRefs?: readonly string[]; +}): string[] | undefined { + const providerIds = dedupeCatalogScopeRefs([ + ...(params.providerRefs ?? []), + ...(params.modelRefs ?? []).map(providerFromModelRef), + ]); + return providerIds.length > 0 ? providerIds : undefined; +} diff --git a/src/config/model-refs.ts b/src/config/model-refs.ts index d4e0c7e266e..ffdaa4cd66b 100644 --- a/src/config/model-refs.ts +++ b/src/config/model-refs.ts @@ -1,3 +1,4 @@ +import { normalizeProviderId } from "../agents/provider-id.js"; import { isRecord } from "../utils.js"; export type ConfiguredModelRef = { @@ -115,3 +116,19 @@ export function collectConfiguredModelRefs( ); return refs; } + +export function collectConfiguredModelRefValues( + config: unknown, + options?: { includeChannelModelOverrides?: boolean }, +): string[] { + return collectConfiguredModelRefs(config, options).map((ref) => ref.value); +} + +export function extractProviderFromModelRef(value: string): string | null { + const trimmed = value.trim(); + const slash = trimmed.indexOf("/"); + if (slash <= 0) { + return null; + } + return normalizeProviderId(trimmed.slice(0, slash)); +}