openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
175 lines (174 loc) • 7.48 kB
JavaScript
import { d as modelCatalogLogicalKey, o as dedupeModelCatalogEntries, r as buildConfiguredModelCatalog } from "./model-selection-shared-BlLyx1r2.js";
import { s as compareModelCatalogEntries } from "./model-catalog-DOgUhUHe.js";
import { n as createModelVisibilityPolicy, t as RUNTIME_MODEL_VISIBILITY_NORMALIZATION } from "./model-visibility-policy-mYoB7nkk.js";
import { n as projectModelCatalogEntryForRoute, r as resolveConfiguredModelCatalogOverrides } from "./model-catalog-route-DKbERkez.js";
//#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
};
}
function sortModelCatalogEntries(entries) {
return entries.toSorted(compareModelCatalogEntries);
}
function resolveLogicalKey(entry, routePolicy) {
return routePolicy.resolveIdentity(entry)?.key ?? modelCatalogLogicalKey(entry);
}
function dedupeLogicalModelCatalogEntries(entries, routePolicy) {
const seen = /* @__PURE__ */ new Set();
return entries.filter((entry) => {
const key = resolveLogicalKey(entry, routePolicy);
if (seen.has(key)) return false;
seen.add(key);
return true;
});
}
function isPickerVisibleCatalogEntry(entry, configuredKeys, routePolicy) {
return entry.status !== "deprecated" && entry.status !== "disabled" || configuredKeys.has(resolveLogicalKey(entry, routePolicy));
}
/** 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 = (entry) => resolveLogicalKey(entry, params.routePolicy);
const projectionCatalog = params.routeVariants?.length ? params.routeVariants : params.catalog;
const routeVariantsByKey = /* @__PURE__ */ new Map();
for (const entry of projectionCatalog) {
const key = keyOf(entry);
const variants = routeVariantsByKey.get(key) ?? [];
variants.push(entry);
routeVariantsByKey.set(key, variants);
}
const variantsOf = (entry) => routeVariantsByKey.get(keyOf(entry)) ?? [entry];
const normalizePolicyKey = (key) => {
const slash = key.indexOf("/");
return slash > 0 ? keyOf({
provider: key.slice(0, slash),
id: key.slice(slash + 1)
}) : key;
};
const configuredKeys = new Set([...policy.configuredKeys].map(normalizePolicyKey));
const retainedKeys = new Set([...policy.retainedKeys].map(normalizePolicyKey));
const retained = params.catalog.filter((entry) => retainedKeys.has(keyOf(entry)));
const wildcard = policy.allowAny || policy.hasProviderWildcards;
const configuredCatalog = wildcard ? sortModelCatalogEntries(buildConfiguredModelCatalog({ cfg: params.cfg })) : [];
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 = keyOf(entry);
if (!readers.has(key)) {
const variants = variantsOf(entry);
readers.set(key, await params.prepareEntry(variants[0] ?? entry, variants));
}
}
const catalogKeys = new Set(params.catalog.map(keyOf));
const projections = /* @__PURE__ */ new Map();
return () => {
const states = new Map([...readers].map(([key, read]) => [key, read()]));
const getEntryState = (entry) => {
const state = states.get(keyOf(entry));
if (!state) throw new Error("Model catalog publication omitted prepared entry state");
return state;
};
const projectEntries = (entries) => {
return sortModelCatalogEntries(dedupeLogicalModelCatalogEntries(entries.map((entry) => {
const projection = getEntryState(entry).routeProjection;
let cached = projections.get(entry);
if (!cached) {
cached = {
overrides: resolveConfiguredModelCatalogOverrides({
cfg: params.cfg,
entry,
policy: params.routePolicy
}),
rows: /* @__PURE__ */ new Map()
};
projections.set(entry, cached);
}
const route = projection.kind === "selected" ? projection.route : projection.kind;
let row = cached.rows.get(route);
if (!row) {
row = projectModelCatalogEntryForRoute({
entry,
projection,
catalog: variantsOf(entry),
...cached.overrides ? { overrides: cached.overrides } : {}
});
cached.rows.set(route, row);
}
return row;
}), params.routePolicy));
};
if (params.view === "all") return 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(keyOf(entry)) || configuredKeys.has(keyOf(entry)));
const preferredKeys = new Set([...visible, ...retained].map(keyOf));
const preferred = [];
const routeBacked = /* @__PURE__ */ new Set();
for (const entry of params.catalog) {
const key = keyOf(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(keyOf(entry));
return (state.compatible || configured) && (!state.routeManaged || configured || routeBacked.has(entry));
});
return projectEntries([
...preferred,
...kept,
...retained,
...routeBacked
]).filter((entry) => isPickerVisibleCatalogEntry(entry, configuredKeys, params.routePolicy));
};
}
//#endregion
export { resolveLogicalModelCatalogEntryState as n, resolveLogicalVisibleModelCatalog as r, prepareLogicalVisibleModelCatalog as t };