UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

771 lines (770 loc) 35.1 kB
import { d as asPositiveSafeInteger } from "./number-coercion-CLj0HTDM.js"; import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js"; import { m as resolveAgentWorkspaceDir, u as resolveAgentDir, y as resolveDefaultAgentId } from "./agent-scope-config-DcbEhP0R.js"; import { r as normalizeProviderId } from "./provider-id-DMd-TDFp.js"; import "./session-key-BnWWjqNc.js"; import { n as resolveDefaultAgentWorkspaceDir } from "./workspace-default-DPT1Dhad.js"; import { r as resolveMergedModelProviderConfig, t as createModelProviderRouteOverrideResolver } from "./model-provider-config-DX4Bzd5F.js"; import { c as stripSelfProviderModelPrefix } from "./provider-model-id-normalization-BFjPahr6.js"; import "./model-ref-shared-Dz7QU0Lx.js"; import { t as modelKey } from "./model-key-CMdQNkZf.js"; import { l as getRuntimeConfigSourceSnapshot } from "./runtime-snapshot-BaQikjTR.js"; import { d as modelCatalogLogicalKey, o as dedupeModelCatalogEntries } from "./model-selection-shared-BlLyx1r2.js"; import { r as DEFAULT_PROVIDER } from "./defaults-CdX9UGcX.js"; import { t as splitTrailingAuthProfile } from "./model-ref-profile-BIKs-96s.js"; import { o as resolveAgentEffectiveModelPrimary } from "./agent-scope-DbtJyKUL.js"; import { n as isManifestPluginAvailableForControlPlane } from "./manifest-contract-eligibility-BbV7X6pV.js"; import { f as hasAuthoredProviderRequestParams } from "./openai-routing-Ex_3E9TF.js"; import { i as resolveModelCatalogIdentityKey, n as openAIModelCatalogRoutePolicy } from "./openai-model-routes-Bte2KVl5.js"; import "./config-Cs0XXL3x.js"; import { u as getActivePluginRegistry } from "./runtime-BL4wZfTq.js"; import { i as isUserModelAuthProfileId } from "./profile-usage-stats-dkZh2v8y.js"; import { a as listUserProfileAuthLinks } from "./user-model-accounts-BMkC9h8s.js"; import { t as resolveAgentHarnessPolicy } from "./policy-D9i1QMuw.js"; import { O as materializePersonalAuthProfile } from "./store-F1B2duCT.js"; import { r as loadManifestModelCatalog } from "./model-catalog-DOgUhUHe.js"; import { n as publishedModelCatalogOwnerMatchesAgent } from "./prepared-model-catalog-owner-Ce5GdRSZ.js"; import "./workspace-ConDEamr.js"; import { t as augmentModelCatalogWithAgentHarness } from "./model-catalog-BPCzXkGj.js"; import { t as isPreparedModelCatalogFull } from "./prepared-model-runtime.full-catalog-CFj7JJlS.js"; import { a as resolveExternalCliAuthScopeFromConfig } from "./external-cli-discovery-CbeZXk1q.js"; import { m as preparedModelRuntimeConfigsMatch } from "./prepared-model-runtime-DgNj94yb.js"; import { n as createModelAuthAvailabilityResolver, t as applyCliRuntimeModelAuthAvailability } from "./model-auth-availability-CRH5-dWY.js"; import { i as resolveGatewayModelThinkingProfile } from "./session-utils-model-BYAclq2V.js"; import { t as projectWorkerPlacementAgentRuntime } from "./placement-session-runtime-Cts2P0Rr.js"; import { t as resolveFastModeState } from "./fast-mode-CTXu8q8K.js"; import { n as createModelVisibilityPolicy, t as RUNTIME_MODEL_VISIBILITY_NORMALIZATION } from "./model-visibility-policy-mYoB7nkk.js"; import { t as resolveConfiguredModelEntries } from "./configured-model-entries-CV1BLgOW.js"; import { n as readPreparedCatalog, t as loadDeferredCatalog } from "./server-model-catalog-auth-d5Ty5VGR.js"; import { n as loadPreparedModelCatalogSnapshotForBrowse, r as modelCatalogBrowseRequiresFullDiscovery, t as buildProviderConfigModelCatalogForBrowse } from "./model-catalog-browse-DzKrbDYm.js"; import { n as projectModelCatalogEntryForRoute, r as resolveConfiguredModelCatalogOverrides, t as findModelCatalogRouteDonor } from "./model-catalog-route-DKbERkez.js"; import { n as resolveLogicalModelCatalogEntryState, t as prepareLogicalVisibleModelCatalog } from "./model-catalog-visibility-D9ic3uaR.js"; import { t as resolveModelProviderCapabilities } from "./model-provider-capabilities-DoGihhvt.js"; //#region src/agents/harness/model-catalog-readiness.ts /** Applies native account observations to catalog metadata, never to execution auth. */ function createAgentHarnessCatalogEvaluator(params) { const isCurrent = () => params.isCurrent?.() ?? params.observationConfig === void 0; return (entry, host) => { const runtime = resolveAgentHarnessPolicy({ provider: entry.provider, modelId: entry.id, modelApi: entry.api, modelBaseUrl: entry.baseUrl, config: params.config, agentId: params.agentId }).runtime; if (runtime === "auto" || runtime === "openclaw") return host; const provider = normalizeProviderId(entry.provider); const configured = resolveMergedModelProviderConfig(params.config, provider); const modelKey = (id) => stripSelfProviderModelPrefix(provider, splitTrailingAuthProfile(id).model.trim()).trim(); if (params.preferredProfileId || params.pinnedProfileId || host.selectedAuthMode && (host.evidence !== "runtime" || entry.nativeRuntime !== runtime) || configured?.api || configured?.baseUrl || configured?.apiKey || configured?.auth || configured?.models?.some((model) => modelKey(model.id) === modelKey(entry.id) && (model.api || model.baseUrl)) || Object.keys(params.config.auth?.order ?? {}).some((id) => normalizeProviderId(id) === provider) || Object.values(params.config.auth?.profiles ?? {}).some((profile) => normalizeProviderId(profile.provider) === provider) || createModelProviderRouteOverrideResolver({ authoredConfig: params.config, provider })(entry.id) === "present" || hasAuthoredProviderRequestParams({ config: params.config, provider, modelId: entry.id, agentId: params.agentId })) return host; const resolveRegistry = () => params.observationConfig ? params.pluginRegistry : params.pluginRegistry ?? getActivePluginRegistry(); const registry = resolveRegistry(); const harness = registry?.agentHarnesses.find((registration) => registration.harness.id === runtime)?.harness; if (!harness?.readModelCatalogReadiness && entry.nativeRuntime !== runtime) return host; let ready = false; try { ready = isCurrent() && harness?.authBootstrap === "harness" && harness.supports({ provider, modelId: entry.id, requestedRuntime: runtime, modelProvider: { preparedAuth: { source: "harness" } } }).supported && harness.readModelCatalogReadiness?.({ config: params.observationConfig ?? params.config, agentId: params.agentId, agentDir: params.agentDir, workspaceDir: params.workspaceDir, provider, modelId: entry.id }) !== void 0 && isCurrent() && resolveRegistry() === registry; } catch {} return { availability: ready, routeResolution: null }; }; } //#endregion //#region src/gateway/server-methods/models-list-auth-resolver.ts function listEnabledSyntheticAuthProviderRefs(metadataSnapshot, config) { return metadataSnapshot.plugins.filter((plugin) => isManifestPluginAvailableForControlPlane({ snapshot: metadataSnapshot, plugin, config })).flatMap((plugin) => plugin.syntheticAuthRefs ?? []); } function createModelsListAuthResolver(params) { const agentDir = resolveAgentDir(params.cfg, params.agentId); return createModelAuthAvailabilityResolver({ cfg: params.cfg, authStore: params.preparedAuthStore, agentDir, workspaceDir: params.workspaceDir, env: process.env, metadataSnapshot: params.metadataSnapshot, preparedRuntimeAuthModes: params.preparedRuntimeAuthModes, preparedRuntimeAuthMaterializations: params.preparedRuntimeAuthMaterializations, preparedSyntheticAuthComplete: params.preparedSyntheticAuthComplete, skipSetupProviderFallback: true, syntheticAuthProviderRefs: listEnabledSyntheticAuthProviderRefs(params.metadataSnapshot, params.cfg), externalCliProviderIds: resolveExternalCliAuthScopeFromConfig(params.cfg)?.providerIds ?? [], preparedRuntimeAuthStore: params.preparedAuthStore, routeResolverFactory: params.routeResolverFactory }); } function createModelsListEntryEvaluator(params) { const pending = /* @__PURE__ */ new Map(); return (entry, routeVariants = [entry]) => { const identity = openAIModelCatalogRoutePolicy.resolveIdentity(entry); const cacheKey = resolveModelCatalogIdentityKey(entry); const cached = pending.get(cacheKey); if (cached) return cached; const next = Promise.resolve().then(() => { const defaultProfileId = params.preferredProfilesByProvider?.get(normalizeProviderId(entry.provider)); const preferredProfileId = params.preferredProfileId ?? defaultProfileId; const pinnedProfileId = params.pinnedProfileId ?? defaultProfileId; const evaluation = params.authResolver.evaluateModelAuth(entry.provider, { modelId: identity?.id ?? entry.id, ...normalizeProviderId(entry.provider) === "openai" ? {} : { api: entry.api, baseUrl: entry.baseUrl }, ...preferredProfileId ? { preferredProfileId } : {}, ...pinnedProfileId ? { pinnedProfileId } : {}, observedRoutes: routeVariants.map((variant) => ({ api: variant.api, baseUrl: variant.baseUrl })) }); const resolved = applyCliRuntimeModelAuthAvailability({ authResolver: params.authResolver, evaluation, cfg: params.cfg, agentId: params.agentId, metadataSnapshot: params.metadataSnapshot, provider: entry.provider, modelId: entry.id, preferredProfileId, pinnedProfileId }); const provider = normalizeProviderId(entry.provider); return params.providerOutcomes?.some((outcome) => outcome.status === "auth-rejected" && outcome.rejectionScope !== "catalog" && normalizeProviderId(outcome.provider) === provider && (outcome.profileId === void 0 || outcome.profileId === resolved.selectedProfileId)) ? { ...resolved, availability: false, unavailableReason: "auth-failed", unavailableUntil: void 0 } : resolved; }); pending.set(cacheKey, next); return next; }; } /** Builds requester/session auth views without changing shared catalog or credential snapshots. */ function createModelsListAuthProjection(params) { const metadataSnapshot = params.metadataSnapshot; const workspaceDir = params.workspaceDir ?? resolveAgentWorkspaceDir(params.cfg, params.agentId) ?? resolveDefaultAgentWorkspaceDir(); let authStore = params.preparedAuthStore; const preferredProfilesByProvider = /* @__PURE__ */ new Map(); const personalProviders = /* @__PURE__ */ new Set(); if (params.preferredProfileId && isUserModelAuthProfileId(params.preferredProfileId)) { authStore = materializePersonalAuthProfile(authStore, params.preferredProfileId); const provider = authStore.profiles[params.preferredProfileId]?.provider; if (provider) personalProviders.add(normalizeProviderId(provider)); } else if (!params.preferredProfileId && params.requesterProfileId) for (const link of listUserProfileAuthLinks(params.requesterProfileId)) { const selected = isUserModelAuthProfileId(link.authProfileId) ? materializePersonalAuthProfile(authStore, link.authProfileId) : authStore; const provider = selected.profiles[link.authProfileId]?.provider ?? params.cfg.auth?.profiles?.[link.authProfileId]?.provider; if (!provider || normalizeProviderId(provider) !== link.provider) continue; authStore = selected; preferredProfilesByProvider.set(link.provider, link.authProfileId); if (isUserModelAuthProfileId(link.authProfileId)) personalProviders.add(link.provider); } const personalStaticEntries = personalProviders.size ? [...params.snapshot.staticEntries ?? [], ...loadManifestModelCatalog({ config: params.cfg, metadataSnapshot })].filter((entry) => personalProviders.has(normalizeProviderId(entry.provider))) : []; const snapshot = personalStaticEntries.length ? { ...params.snapshot, entries: dedupeModelCatalogEntries([...params.snapshot.entries, ...personalStaticEntries]), routeVariants: [...params.snapshot.routeVariants.length ? params.snapshot.routeVariants : params.snapshot.entries, ...personalStaticEntries] } : params.snapshot; const nativeEvaluator = createAgentHarnessCatalogEvaluator({ config: params.cfg, agentId: params.agentId, agentDir: params.agentDir ?? resolveAgentDir(params.cfg, params.agentId), workspaceDir, preferredProfileId: params.preferredProfileId, pinnedProfileId: params.pinnedProfileId, pluginRegistry: params.pluginRegistry, isCurrent: params.isCurrent, observationConfig: params.observationConfig }); const evaluateNative = (entry, host) => preferredProfilesByProvider.has(normalizeProviderId(entry.provider)) ? host : nativeEvaluator(entry, host); const authResolver = createModelsListAuthResolver({ cfg: params.cfg, agentId: params.agentId, metadataSnapshot, preparedAuthStore: authStore, preparedRuntimeAuthModes: params.preparedRuntimeAuthModes, preparedRuntimeAuthMaterializations: params.preparedRuntimeAuthMaterializations, preparedSyntheticAuthComplete: params.preparedSyntheticAuthComplete ?? isPreparedModelCatalogFull(params.snapshot), workspaceDir, routeResolverFactory: params.routeResolverFactory }); const evaluateStoredEntry = createModelsListEntryEvaluator({ cfg: params.cfg, agentId: params.agentId, authResolver, metadataSnapshot, providerOutcomes: params.snapshot.providerOutcomes, preferredProfilesByProvider, ...params.preferredProfileId ? { preferredProfileId: params.preferredProfileId } : {}, ...params.pinnedProfileId ? { pinnedProfileId: params.pinnedProfileId } : {} }); return { evaluateEntry: Boolean(params.preferredProfileId && isUserModelAuthProfileId(params.preferredProfileId) && !authStore.profiles[params.preferredProfileId]) ? async () => ({ availability: false, unavailableReason: "missing-auth", routeResolution: null }) : evaluateStoredEntry, evaluateNative, snapshot, metadataSnapshot, authStore, authModes: params.preparedRuntimeAuthModes, authMaterializations: params.preparedRuntimeAuthMaterializations, pluginRegistry: params.pluginRegistry, isCurrent: params.isCurrent ?? (() => params.observationConfig === void 0), observationConfig: params.observationConfig }; } //#endregion //#region src/gateway/server-methods/models-list-configured-static.ts /** Configured dynamic-catalog providers that omit explicit model inventory. */ function listConfiguredRuntimeDiscoveryProviderIds(cfg, metadataSnapshot) { const ids = /* @__PURE__ */ new Set(); const providers = cfg.models?.providers; if (!providers || typeof providers !== "object" || !metadataSnapshot) return ids; const dynamicProviders = /* @__PURE__ */ new Set(); for (const plugin of metadataSnapshot.plugins) for (const [providerRaw, mode] of Object.entries(plugin.modelCatalog?.discovery ?? {})) { const providerId = normalizeProviderId(providerRaw); if (providerId && (mode === "runtime" || mode === "refreshable")) dynamicProviders.add(providerId); } for (const [providerRaw, provider] of Object.entries(providers)) { const providerId = normalizeProviderId(providerRaw); if (providerId && dynamicProviders.has(providerId) && !Array.isArray(provider?.models)) ids.add(providerId); } return ids; } function resolveProviderConfigInventoryEntries(params) { const canonicalByKey = /* @__PURE__ */ new Map(); for (const entry of params.canonicalEntries) { const key = resolveModelCatalogIdentityKey(entry); if (!canonicalByKey.has(key)) canonicalByKey.set(key, entry); } const seen = /* @__PURE__ */ new Set(); const inventory = []; for (const authoredEntry of params.authoredEntries) { const key = resolveModelCatalogIdentityKey(authoredEntry); if (seen.has(key)) continue; seen.add(key); inventory.push(canonicalByKey.get(key) ?? authoredEntry); } if (params.discoveryOnlyProviderIds) for (const canonicalEntry of params.canonicalEntries) { const key = resolveModelCatalogIdentityKey(canonicalEntry); if (seen.has(key)) continue; if (!params.discoveryOnlyProviderIds.has(normalizeProviderId(canonicalEntry.provider))) continue; seen.add(key); inventory.push(canonicalEntry); } return inventory; } function includeConfiguredStaticCatalogEntries(params) { if (!params.enabled || !params.snapshot.staticEntries?.length) return [...params.snapshot.entries]; const policy = createModelVisibilityPolicy({ cfg: params.cfg, catalog: [...params.snapshot.entries], defaultProvider: DEFAULT_PROVIDER, defaultModel: params.defaultModel, agentId: params.agentId, ...RUNTIME_MODEL_VISIBILITY_NORMALIZATION, manifestPlugins: params.metadataSnapshot }); const configuredKeys = new Set([...policy.configuredKeys].map((key) => { const separator = key.indexOf("/"); return separator > 0 ? resolveModelCatalogIdentityKey({ provider: key.slice(0, separator), id: key.slice(separator + 1) }) : key; })); const catalog = [...params.snapshot.entries]; const seen = new Set(catalog.map(resolveModelCatalogIdentityKey)); for (const entry of params.snapshot.staticEntries) { const key = resolveModelCatalogIdentityKey(entry); if (!seen.has(key) && configuredKeys.has(key)) { seen.add(key); catalog.push(entry); } } return catalog; } //#endregion //#region src/gateway/server-methods/models-list-harness-catalog.ts async function prepareModelsListHarnessCatalog(params) { const defaultModel = resolveAgentEffectiveModelPrimary(params.cfg, params.agentId); const snapshot = params.allowHarnessDiscovery ? await augmentModelCatalogWithAgentHarness({ cfg: params.cfg, agentId: params.agentId, agentDir: params.agentDir ?? resolveAgentDir(params.cfg, params.agentId), workspaceDir: params.workspaceDir, defaultProvider: DEFAULT_PROVIDER, defaultModel, snapshot: params.snapshot, pluginRegistry: params.pluginRegistry, isCurrent: params.isCurrent, observationConfig: params.observationConfig, onError: params.onError }) : params.snapshot; return { snapshot, defaultModel, catalog: includeConfiguredStaticCatalogEntries({ ...params, snapshot, defaultModel, enabled: params.view === "configured" }) }; } //#endregion //#region src/gateway/server-methods/models-list-public-projection.ts /** Keeps concrete route, auth, cost, and provider parameters out of public model rows. */ function buildPublicModelProjection(entry) { const contextWindow = asPositiveSafeInteger(entry.contextWindow); return { id: entry.id, name: entry.name, provider: entry.provider, ...entry.alias ? { alias: entry.alias } : {}, ...contextWindow ? { contextWindow } : {}, ...entry.contextWindows ? { contextWindows: entry.contextWindows } : {}, ...entry.contextWindowDefault ? { contextWindowDefault: entry.contextWindowDefault } : {}, ...typeof entry.reasoning === "boolean" ? { reasoning: entry.reasoning } : {}, ...typeof entry.compat?.supportsTools === "boolean" ? { supportsTools: entry.compat.supportsTools } : {} }; } function projectProviderCatalogOutcomes(outcomes) { return outcomes?.map(({ provider, profileId, status }) => ({ provider, ...profileId ? { profileId } : {}, status })); } function resolveModelChoiceAgentRuntime(params) { const harnessPolicy = resolveAgentHarnessPolicy({ provider: params.entry.provider, modelId: params.entry.id, modelApi: params.entry.api, modelBaseUrl: params.entry.baseUrl, config: params.cfg, agentId: params.agentId }); if (harnessPolicy.runtime === "auto") return; return projectWorkerPlacementAgentRuntime({ id: harnessPolicy.runtime, source: harnessPolicy.runtimeSource ?? "implicit" }); } //#endregion //#region src/gateway/server-methods/models-list-result.ts let loggedSlowModelsListCatalog = false; function resolveModelsListView(params) { const view = params.view; return view === "configured" || view === "provider-config" || view === "all" ? view : "default"; } /** Builds one per-agent, snapshot-scoped route projection for Gateway thinking metadata. */ function createGatewayAgentModelCatalogProjector(params) { const authProjection = createModelsListAuthProjection(params); const { evaluateEntry, evaluateNative, snapshot } = authProjection; const projectionCatalog = snapshot.routeVariants.length > 0 ? snapshot.routeVariants : snapshot.entries; const routeVariantsByKey = /* @__PURE__ */ new Map(); for (const entry of projectionCatalog) { const key = resolveModelCatalogIdentityKey(entry); const variants = routeVariantsByKey.get(key) ?? []; variants.push(entry); routeVariantsByKey.set(key, variants); } const resolveRouteVariants = (entry) => routeVariantsByKey.get(resolveModelCatalogIdentityKey(entry)) ?? [entry]; const logicalEntries = []; const logicalEntryKeys = /* @__PURE__ */ new Set(); for (const entry of snapshot.entries) { const key = resolveModelCatalogIdentityKey(entry); if (!logicalEntryKeys.has(key)) { logicalEntryKeys.add(key); logicalEntries.push(entry); } } let projectedCatalog; return { ...authProjection, projectCatalog: () => projectedCatalog ??= Promise.all(logicalEntries.map(async (entry) => { const routeVariants = resolveRouteVariants(entry); const evaluation = evaluateNative(entry, await evaluateEntry(entry, routeVariants)); const state = resolveLogicalModelCatalogEntryState({ evaluation, routePolicy: openAIModelCatalogRoutePolicy }); const overrides = resolveConfiguredModelCatalogOverrides({ cfg: params.cfg, entry, policy: openAIModelCatalogRoutePolicy }); const projected = projectModelCatalogEntryForRoute({ entry, projection: state.routeProjection, catalog: routeVariants, ...overrides ? { overrides } : {} }); if (state.routeProjection.kind !== "selected") return projected; const donor = findModelCatalogRouteDonor({ entry, route: state.routeProjection.route, policy: openAIModelCatalogRoutePolicy, catalog: routeVariants }); if (donor && Object.hasOwn(donor, "compat")) projected.compat = donor.compat; if (donor && Object.hasOwn(donor, "params")) projected.params = donor.params; return projected; })) }; } function createPublicModelsListProjector(params) { const prepared = /* @__PURE__ */ new WeakMap(); return (entry, evaluation) => { let preparedEntry = prepared.get(entry); if (!preparedEntry) { const configuredEntry = params.configuredEntriesByKey.get(modelKey(entry.provider, entry.id)); const alias = configuredEntry?.aliases.at(-1); const publicEntry = configuredEntry?.aliasDisabled ? Object.assign({}, entry, { alias: void 0 }) : alias && alias !== entry.alias ? Object.assign({}, entry, { alias }) : entry; const capabilityProvider = params.apiKeyCapabilities?.resolveProvider(entry.provider); const agentRuntime = resolveModelChoiceAgentRuntime({ cfg: params.cfg, agentId: params.agentId, entry }); const thinkingProfile = typeof publicEntry.reasoning !== "boolean" ? void 0 : resolveGatewayModelThinkingProfile({ cfg: params.cfg, agentId: params.agentId, provider: entry.provider, model: entry.id, modelCatalog: params.thinkingCatalog, configuredReasoning: publicEntry.configuredReasoning ?? publicEntry.reasoning, thinkingPolicyProvider: publicEntry.thinkingPolicyProvider }); const fastModeState = resolveFastModeState({ cfg: params.cfg, agentId: params.agentId, provider: entry.provider, model: entry.id }); preparedEntry = { ...buildPublicModelProjection(publicEntry), ...configuredEntry?.tags.size ? { tags: [...configuredEntry.tags] } : {}, ...agentRuntime ? { agentRuntime } : {}, ...thinkingProfile, ...fastModeState.source === "default" ? {} : { effectiveFastMode: fastModeState.mode }, ...capabilityProvider && params.apiKeyCapabilities?.providers.has(capabilityProvider) ? { apiKeySupported: params.apiKeyCapabilities.providers.get(capabilityProvider) === true } : {}, ...params.includeInput && entry.input?.length ? { input: entry.input } : {} }; prepared.set(entry, preparedEntry); } const projectedAvailability = params.preserveUnknownAvailability ? evaluation.availability : evaluation.availability ?? false; return Object.assign({}, preparedEntry, projectedAvailability === void 0 ? {} : { available: projectedAvailability }, projectedAvailability === false && evaluation.unavailableReason ? { unavailableReason: evaluation.unavailableReason, ...evaluation.unavailableUntil !== void 0 ? { unavailableUntil: evaluation.unavailableUntil } : {} } : {}); }; } function apiKeyProviderCapabilities(params) { const { capabilities, resolveProvider } = resolveModelProviderCapabilities({ config: params.cfg, metadataSnapshot: params.metadataSnapshot, workspaceDir: params.workspaceDir }); return { providers: new Map(capabilities.map(({ provider, apiKeySupported }) => [provider, apiKeySupported])), resolveProvider }; } async function buildModelsListResult(params) { return (await prepareModelsListResult(params)).read(); } /** Prepares catalog work once; the returned reader revalidates native readiness without I/O. */ async function prepareModelsListResult(params) { const initialConfig = params.context.getRuntimeConfig(); const initialAgentId = normalizeAgentId(params.agentId ?? resolveDefaultAgentId(initialConfig)); const view = resolveModelsListView(params.params); const preparedOnly = params.params.preparedOnly === true; const refresh = params.params.refresh === true; const preloadedCatalog = params.preloadedCatalog?.agentId === initialAgentId && preparedModelRuntimeConfigsMatch(params.preloadedCatalog.config, initialConfig) ? params.preloadedCatalog : void 0; let loadedSnapshot; let loadedReadOnly = true; let usedPreloadedCatalog = false; let catalogTimedOut = false; const handleCatalogTimeout = (timeoutMs) => { catalogTimedOut = true; if (loggedSlowModelsListCatalog) return; loggedSlowModelsListCatalog = true; params.context.logGateway.warn(`models.list catalog load exceeded ${timeoutMs}ms; using the prepared catalog when available`); }; let snapshot = await loadPreparedModelCatalogSnapshotForBrowse({ cfg: initialConfig, agentId: initialAgentId, view, preparedOnly, refresh, loadCatalog: async (loadParams) => { loadedReadOnly = loadParams.readOnly ?? true; if (preloadedCatalog && (loadedReadOnly || params.preloadedOnly && isPreparedModelCatalogFull(preloadedCatalog.snapshot))) { usedPreloadedCatalog = true; return preloadedCatalog.snapshot; } if (params.preloadedOnly) return { entries: [], routeVariants: [] }; loadedSnapshot = await loadDeferredCatalog(params.context, initialAgentId, { readOnly: loadedReadOnly, refreshAuth: refresh && loadedReadOnly, ...!preparedOnly ? { refreshFullCatalog: refresh ? true : "stale" } : {} }); return loadedSnapshot; }, onTimeout: handleCatalogTimeout }); if (loadedSnapshot && loadedReadOnly && !preparedOnly && modelCatalogBrowseRequiresFullDiscovery({ cfg: loadedSnapshot.config, agentId: loadedSnapshot.agentId, view })) { const escalationAgentId = loadedSnapshot.agentId; let escalationTimedOut = false; let fullSnapshot; const escalatedCatalog = await loadPreparedModelCatalogSnapshotForBrowse({ cfg: loadedSnapshot.config, agentId: escalationAgentId, view, refresh, loadCatalog: async ({ readOnly }) => { fullSnapshot = await loadDeferredCatalog(params.context, escalationAgentId, { readOnly, refreshAuth: refresh && readOnly, refreshFullCatalog: refresh ? true : "stale" }); return fullSnapshot; }, timeoutFullDiscovery: true, onTimeout: (timeoutMs) => { escalationTimedOut = true; handleCatalogTimeout(timeoutMs); } }); if (!escalationTimedOut && fullSnapshot) { if (!publishedModelCatalogOwnerMatchesAgent(fullSnapshot, escalationAgentId)) return { read: () => ({ models: [] }), isCurrent: () => true }; loadedSnapshot = fullSnapshot; snapshot = escalatedCatalog; } } if (loadedSnapshot && params.agentId !== void 0 && !publishedModelCatalogOwnerMatchesAgent(loadedSnapshot, initialAgentId)) return { read: () => ({ models: [] }), isCurrent: () => true }; const ownerSnapshot = loadedSnapshot ?? (preloadedCatalog && params.catalogProjector ? void 0 : await readPreparedCatalog(params.context, initialAgentId)); if (catalogTimedOut && ownerSnapshot) snapshot = ownerSnapshot; const cfg = ownerSnapshot?.config ?? initialConfig; const agentId = ownerSnapshot?.agentId ?? initialAgentId; const workspaceDir = ownerSnapshot?.workspaceDir ?? resolveAgentWorkspaceDir(cfg, agentId) ?? resolveDefaultAgentWorkspaceDir(); const preparedProjectionOwner = ownerSnapshot ?? params.catalogProjector; const metadataSnapshot = preparedProjectionOwner?.metadataSnapshot; const preparedAuthStore = ownerSnapshot?.authStore ?? params.catalogProjector?.authStore; const preparedPluginRegistry = preparedProjectionOwner?.pluginRegistry; const preparedOwnerIsCurrent = preparedProjectionOwner?.isCurrent; const isCurrent = () => params.context.getRuntimeConfig() === initialConfig && preparedOwnerIsCurrent?.() === true; if (!metadataSnapshot || !preparedAuthStore) throw new Error("Gateway model catalog owner omitted prepared metadata or auth state"); const preparedCatalog = await prepareModelsListHarnessCatalog({ cfg, agentId, agentDir: ownerSnapshot?.agentDir, workspaceDir, snapshot, view, metadataSnapshot, pluginRegistry: preparedPluginRegistry, isCurrent, observationConfig: preparedProjectionOwner?.observationConfig, allowHarnessDiscovery: params.preloadedOnly !== true && !preparedOnly, onError: (error) => params.context.logGateway.debug(`models.list continuing without harness catalog: ${String(error)}`) }); snapshot = preparedCatalog.snapshot; const { defaultModel } = preparedCatalog; const preparedRuntimeAuthModes = preparedProjectionOwner?.authModes; const preparedRuntimeAuthMaterializations = preparedProjectionOwner?.authMaterializations; const projector = (usedPreloadedCatalog ? params.catalogProjector : void 0) ?? createGatewayAgentModelCatalogProjector({ cfg, agentId, agentDir: ownerSnapshot?.agentDir, workspaceDir, snapshot: { ...snapshot, entries: preparedCatalog.catalog }, metadataSnapshot, preparedAuthStore, preparedRuntimeAuthModes, preparedRuntimeAuthMaterializations, preparedSyntheticAuthComplete: ownerSnapshot?.catalogComplete === true, requesterProfileId: view === "provider-config" ? void 0 : params.requesterProfileId, routeResolverFactory: params.routeResolverFactory, pluginRegistry: preparedPluginRegistry, isCurrent, observationConfig: preparedProjectionOwner?.observationConfig }); const catalog = dedupeModelCatalogEntries([...preparedCatalog.catalog, ...projector.snapshot.entries]); const evaluateNative = (entry, host) => { const native = projector.evaluateNative(entry, host); return native !== host && params.context.getRuntimeConfig() !== initialConfig ? { ...native, availability: false } : native; }; const { routeVariants, providerOutcomes } = projector.snapshot; const publicProviderOutcomes = projectProviderCatalogOutcomes(providerOutcomes); const outcomeProjection = publicProviderOutcomes?.length ? { providerOutcomes: publicProviderOutcomes } : {}; const capableProviders = params.params.includeProviderCapabilities === true ? apiKeyProviderCapabilities({ cfg, metadataSnapshot, workspaceDir }) : void 0; const configuredEntriesByKey = resolveConfiguredModelEntries({ cfg, agentId, defaultModel, ...RUNTIME_MODEL_VISIBILITY_NORMALIZATION, manifestPlugins: metadataSnapshot }).byKey; if (view === "provider-config") { const sourceConfig = getRuntimeConfigSourceSnapshot() ?? cfg; const inventoryProjector = createGatewayAgentModelCatalogProjector({ cfg, agentId, snapshot: { entries: resolveProviderConfigInventoryEntries({ authoredEntries: buildProviderConfigModelCatalogForBrowse({ cfg: sourceConfig, workspaceDir }), canonicalEntries: catalog, discoveryOnlyProviderIds: listConfiguredRuntimeDiscoveryProviderIds(sourceConfig, metadataSnapshot) }), routeVariants, ...providerOutcomes?.length ? { providerOutcomes } : {} }, metadataSnapshot, preparedAuthStore, preparedRuntimeAuthModes, preparedRuntimeAuthMaterializations, pluginRegistry: preparedPluginRegistry, isCurrent, observationConfig: preparedProjectionOwner?.observationConfig, ...params.routeResolverFactory ? { routeResolverFactory: params.routeResolverFactory } : {} }); const inventory = await inventoryProjector.projectCatalog(); const entries = await Promise.all(inventory.map(async (entry) => ({ entry, host: await inventoryProjector.evaluateEntry(entry) }))); const projectPublic = createPublicModelsListProjector({ thinkingCatalog: catalog, cfg, agentId, configuredEntriesByKey, includeInput: true, preserveUnknownAvailability: true, ...capableProviders ? { apiKeyCapabilities: capableProviders } : {} }); return { isCurrent, read: () => ({ models: entries.map(({ entry, host }) => projectPublic(entry, evaluateNative(entry, host))), ...outcomeProjection }) }; } const visibilityPolicy = createModelVisibilityPolicy({ cfg, catalog, defaultProvider: DEFAULT_PROVIDER, defaultModel, agentId, ...RUNTIME_MODEL_VISIBILITY_NORMALIZATION, manifestPlugins: metadataSnapshot }); const { evaluateEntry } = projector; const evaluationKey = (entry) => openAIModelCatalogRoutePolicy.resolveIdentity(entry)?.key ?? modelCatalogLogicalKey(entry); const evaluations = /* @__PURE__ */ new Map(); const readCatalog = await prepareLogicalVisibleModelCatalog({ cfg, catalog, defaultProvider: DEFAULT_PROVIDER, defaultModel, agentId, workspaceDir, view, policy: visibilityPolicy, routePolicy: openAIModelCatalogRoutePolicy, routeVariants, prepareEntry: async (entry, variants) => { const host = await evaluateEntry(entry, variants); return () => { const evaluation = evaluateNative(entry, host); evaluations.set(evaluationKey(entry), evaluation); const syntheticLocal = !(evaluation.routeResolution !== null) && normalizeProviderId(entry.provider) !== "openai" && evaluation.availability === void 0 && evaluation.evidence === "synthetic"; return resolveLogicalModelCatalogEntryState({ evaluation, authBacked: evaluation.availability === true || syntheticLocal, routePolicy: openAIModelCatalogRoutePolicy }); }; } }); const projectPublic = createPublicModelsListProjector({ thinkingCatalog: catalog, cfg, agentId, configuredEntriesByKey, ...capableProviders ? { apiKeyCapabilities: capableProviders } : {} }); return { isCurrent, read: () => ({ models: readCatalog().map((entry) => { const evaluation = evaluations.get(evaluationKey(entry)); if (!evaluation) throw new Error("Model catalog publication omitted prepared auth evaluation"); return projectPublic(entry, evaluation); }), ...outcomeProjection }) }; } //#endregion export { createGatewayAgentModelCatalogProjector as n, prepareModelsListResult as r, buildModelsListResult as t };