UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

173 lines (172 loc) • 8.24 kB
import { t as dedupeByKey } from "./dedupe-by-key-DnqEVrst.mjs"; import { o as dedupeModelCatalogEntries } from "./model-selection-shared-DcM6hdAC.mjs"; import { a as resolveModelCatalogIdentityKey, t as createModelCatalogIdentityKeyResolver } from "./openai-model-routes-C1mdGNT1.mjs"; import { n as compareModelCatalogEntries, r as orderModelCatalogForPicker } from "./model-catalog-order-DbO0IMct.mjs"; import { t as createModelCatalogView } from "./model-catalog-view-DRZItIR3.mjs"; import { n as createModelVisibilityPolicy, t as RUNTIME_MODEL_VISIBILITY_NORMALIZATION } from "./model-visibility-policy-CJ73IRCN.mjs"; //#region src/agents/model-catalog-visibility.ts /** Maps one shared auth evaluation into logical catalog selection state. */ function resolveLogicalModelCatalogEntryState(params) { const routeManaged = params.evaluation.routeResolution !== null; const selectedRoute = params.evaluation.selectedRoute; const routeProjection = !routeManaged ? { kind: "unmanaged" } : selectedRoute ? { kind: "selected", route: selectedRoute, policy: params.routePolicy } : { kind: "unresolved", policy: params.routePolicy }; return { authBacked: params.authBacked ?? params.evaluation.availability === true, compatible: params.evaluation.routeResolution?.kind !== "incompatible", routeManaged, routeProjection, ...params.evaluation.runtimeAuth ? { nativeRuntime: params.evaluation.runtimeAuth.id } : {} }; } function sortModelCatalogEntries(entries) { return entries.toSorted(compareModelCatalogEntries); } /** Resolves logical rows while keeping provider-owned physical route precedence. */ async function resolveLogicalVisibleModelCatalog(params) { return (await prepareLogicalVisibleModelCatalog({ ...params, prepareEntry: async (entry, variants) => { const state = await params.evaluateEntry(entry, variants); return () => state; } }))(); } /** Prepare host facts once; observe revocable state only in the synchronous publication. */ async function prepareLogicalVisibleModelCatalog(params) { const policy = params.policy ?? createModelVisibilityPolicy({ cfg: params.cfg, catalog: params.catalog, defaultProvider: params.defaultProvider, defaultModel: params.defaultModel, agentId: params.agentId, ...RUNTIME_MODEL_VISIBILITY_NORMALIZATION }); const keyOf = createModelCatalogIdentityKeyResolver(); const catalogView = createModelCatalogView({ cfg: params.cfg, catalog: params.catalog, routeVariants: params.routeVariants?.length ? params.routeVariants : params.catalog, routePolicy: params.routePolicy, keyOf }); const { configuredKeys, retainedKeys } = policy; const retainedKey = params.retainedModel ? keyOf({ provider: params.retainedModel.provider, id: params.retainedModel.model }) : void 0; const retained = params.catalog.filter((entry) => retainedKeys.has(keyOf(entry)) || keyOf(entry) === retainedKey); const wildcard = policy.allowAny || policy.hasProviderWildcards; const configuredCatalog = wildcard ? sortModelCatalogEntries([...policy.configuredCatalog]) : []; const candidates = params.view === "all" ? params.catalog : [ ...wildcard ? params.catalog : [], ...configuredCatalog, ...policy.allowedCatalog, ...retained ]; const readers = /* @__PURE__ */ new Map(); for (const entry of candidates) { const key = resolveModelCatalogIdentityKey(entry); if (!readers.has(key)) { const variants = catalogView.variantsOf(entry, key) ?? [entry]; readers.set(key, await params.prepareEntry(variants[0] ?? entry, variants)); } } const { buildManifestBuiltInModelSuppressionResolver } = await import("./manifest-model-suppression-BsRhVrh9.mjs"); const suppression = buildManifestBuiltInModelSuppressionResolver({ config: params.cfg, workspaceDir: params.workspaceDir, metadataSnapshot: params.metadataSnapshot }); const catalogKeys = new Set(params.catalog.map(createModelCatalogIdentityKeyResolver())); let previousStates; let previousCatalog; return () => { const states = new Map([...readers].map(([key, read]) => [key, read()])); const retainedStates = previousStates; if (params.isCurrent?.() && previousCatalog && retainedStates && [...states].every(([key, state]) => { const previous = retainedStates.get(key); const route = state.routeProjection; const previousRoute = previous?.routeProjection; return previous !== void 0 && previous.authBacked === state.authBacked && previous.compatible === state.compatible && previous.routeManaged === state.routeManaged && previous.nativeRuntime === state.nativeRuntime && previousRoute?.kind === route.kind && (route.kind === "unmanaged" || previousRoute.kind !== "unmanaged" && previousRoute.policy === route.policy) && (route.kind !== "selected" || previousRoute.kind === "selected" && previousRoute.route === route.route); })) return [...previousCatalog]; const publish = (catalog) => { if (!params.isCurrent?.()) { previousStates = void 0; previousCatalog = void 0; return catalog; } previousStates = new Map([...states].map(([key, state]) => [key, { ...state, routeProjection: { ...state.routeProjection } }])); previousCatalog = [...catalog]; return catalog; }; const publicationKeyOf = createModelCatalogIdentityKeyResolver(); const getEntryState = (entry) => { const state = states.get(publicationKeyOf(entry)); if (!state) throw new Error("Model catalog publication omitted prepared entry state"); return state; }; const projectEntries = (entries) => { const projected = entries.flatMap((entry) => { const state = getEntryState(entry); const row = catalogView.readProjection(entry, state.routeProjection, publicationKeyOf(entry)).entry; if (!state.nativeRuntime && suppression({ provider: row.provider, id: row.id, api: row.api, baseUrl: row.baseUrl })?.retirement) return []; return [row]; }); return orderModelCatalogForPicker(dedupeByKey(projected, publicationKeyOf), params.selectedModel ?? params.retainedModel); }; if (params.view === "all") return publish(projectEntries(params.catalog)); const defaultVisibleCatalog = wildcard ? sortModelCatalogEntries(dedupeModelCatalogEntries([...configuredCatalog, ...params.catalog.filter((entry) => getEntryState(entry).authBacked)])) : []; const visible = sortModelCatalogEntries(dedupeModelCatalogEntries(policy.visibleCatalog({ catalog: params.catalog, defaultVisibleCatalog, view: params.view }))).filter((entry) => catalogKeys.has(publicationKeyOf(entry)) || configuredKeys.has(publicationKeyOf(entry))); const preferredKeys = new Set([...visible, ...retained].map(publicationKeyOf)); const preferred = []; const routeBacked = /* @__PURE__ */ new Set(); for (const entry of params.catalog) { const key = publicationKeyOf(entry); const preferredKey = preferredKeys.has(key); const wildcardRoute = policy.allowAny || policy.hasProviderWildcards && policy.allowsByWildcard({ provider: entry.provider, model: entry.id }); if (!preferredKey && !wildcardRoute) continue; const state = getEntryState(entry); if (!state.compatible && !configuredKeys.has(key)) continue; if (preferredKey && state.routeProjection.kind === "selected" && params.routePolicy.matchesRoute(entry, state.routeProjection.route)) preferred.push(entry); if (wildcardRoute && state.routeManaged && state.authBacked) routeBacked.add(entry); } const kept = visible.filter((entry) => { const state = getEntryState(entry); const configured = configuredKeys.has(publicationKeyOf(entry)); return (state.compatible || configured) && (!state.routeManaged || configured || routeBacked.has(entry)); }); return publish(projectEntries([ ...preferred, ...kept, ...retained, ...routeBacked ]).filter((entry) => (params.view === "configured" || policy.allows({ provider: entry.provider, model: entry.id })) && (publicationKeyOf(entry) === retainedKey || entry.status !== "deprecated" && entry.status !== "disabled" || configuredKeys.has(publicationKeyOf(entry))))); }; } //#endregion export { resolveLogicalModelCatalogEntryState as n, resolveLogicalVisibleModelCatalog as r, prepareLogicalVisibleModelCatalog as t };