openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
355 lines (354 loc) • 21.3 kB
JavaScript
import { r as normalizeProviderId } from "./provider-id-BIyeXQag.mjs";
import { n as withPluginRuntimeGenerationScope } from "./generation-scope-CmJ9AjVM.mjs";
import { t as dedupeByKey } from "./dedupe-by-key-DnqEVrst.mjs";
import { t as createModelCatalogIdentityKeyResolver } from "./openai-model-routes-DsXHQaeh.mjs";
import { A as getPreparedRuntimeAuthMaterializations } from "./runtime-snapshots-sMjDPg8h.mjs";
import { h as runtimeAuthMetadataState } from "./runtime-snapshot-owner-Cqkq90PM.mjs";
import { n as modelCatalogRouteVariantKey, r as modelCatalogRowToEntry, t as enrichHarnessRows } from "./model-catalog-entry-DsPyrdmX.mjs";
import { n as compareModelCatalogEntries } from "./model-catalog-order-CppoLIkR.mjs";
import { c as hasSamePreparedModelCatalogAuth, i as getPreparedModelFullCatalogAuth, n as copyPreparedModelFullCatalogAuth, t as bindPreparedModelRuntimeAuth, u as setPreparedModelFullCatalogAuth } from "./prepared-model-runtime-auth-DqGuKVvM.mjs";
import { a as resolvePreparedProviderStaticConfigs } from "./provider-discovery-DLUGKsDn.mjs";
import { p as prepareModelCatalogThinkingPolicies } from "./thinking-DeQ8EFQz.mjs";
import { M as discoverModels, _ as prepareConfiguredModelAliases, g as completeConfiguredRuntimeModels, n as buildPreparedPluginModelCatalog, t as acquirePreparedMediaCapabilityProviders } from "./prepared-model-runtime.plugin-generation-CE5Etj1d.mjs";
import { i as AuthStorage } from "./model-registry-DaJd04jB.mjs";
import { r as loadBundledProviderStaticCatalogContextModels, s as createPreparedConfiguredRuntimeModelLookup } from "./model.static-catalog-XFzYY8WN.mjs";
import { isDeepStrictEqual } from "node:util";
//#region src/agents/prepared-model-runtime.full-catalog.ts
const fullModelCatalogSnapshots = /* @__PURE__ */ new WeakSet();
function catalogPublicationContent(catalog) {
const { pendingProviders: _pending, refreshFailed: _failed, ...inventory } = catalog;
const byProvider = (rows = []) => rows.toSorted((left, right) => left.provider.localeCompare(right.provider));
const byRuntime = (scopes) => scopes && Object.fromEntries(Object.entries(scopes).map(([runtime, rows]) => [runtime, byProvider(rows)]));
const auth = getPreparedModelFullCatalogAuth(catalog);
return {
...inventory,
entries: byProvider(catalog.entries),
routeVariants: byProvider(catalog.routeVariants),
staticEntries: byProvider(catalog.staticEntries),
providerOutcomes: byProvider(catalog.providerOutcomes),
nativeProviderOutcomes: byRuntime(catalog.nativeProviderOutcomes),
nativeHostRows: byRuntime(catalog.nativeHostRows),
authoritative: catalog.authoritative !== false,
full: isPreparedModelCatalogFull(catalog),
auth: auth && {
modes: auth.authModes,
labels: auth.providerAuthLabels,
metadata: runtimeAuthMetadataState(auth.authStore)
}
};
}
/** Keep inventory identity stable across renewals while adopting the latest private auth. */
function retainPreparedModelCatalogPublication(catalog, previous) {
if (!catalog || !previous || !isDeepStrictEqual(catalogPublicationContent(catalog), catalogPublicationContent(previous))) return catalog;
copyPreparedModelFullCatalogAuth(catalog, previous);
return previous;
}
/** Builds complete inventory before generation-specific runtime capability projection. */
async function prepareFullCatalogFacts(agentFacts, pluginGeneration, catalogMode, catalogSource, options = {}) {
const prepare = async () => {
const { env, input, templateAuthStorage } = agentFacts;
const { pluginMetadataSnapshot, preparedStaticProviderCatalog } = pluginGeneration;
const observedProviders = new Set(catalogSource.providerOutcomes?.map(({ provider }) => normalizeProviderId(provider)));
const templateModelRegistry = discoverModels(templateAuthStorage, input.agentDir, {
config: input.config,
...input.workspaceDir ? { workspaceDir: input.workspaceDir } : {},
pluginMetadataSnapshot,
...catalogMode === "static" ? { normalizeModels: false } : {},
includePluginCatalogs: true,
modelsJsonContents: catalogSource.modelsJsonContents,
pluginCatalogs: catalogSource.pluginCatalogs,
staticProviderConfigs: Object.fromEntries(Object.entries(resolvePreparedProviderStaticConfigs(preparedStaticProviderCatalog)).filter(([provider]) => !observedProviders.has(normalizeProviderId(provider))))
});
const modelCatalog = await buildPreparedPluginModelCatalog({
...options,
agentFacts,
catalogMode,
modelRegistry: templateModelRegistry,
providerOutcomes: catalogSource.providerOutcomes,
pluginGeneration
});
const providerStaticModels = input.config.models?.mode === "replace" ? [] : pluginGeneration.providerStaticModels ?? await loadBundledProviderStaticCatalogContextModels({
cfg: input.config,
env,
metadataSnapshot: pluginMetadataSnapshot,
registeredProviders: pluginGeneration.pluginRegistry?.providers,
providerIds: options.providerIds,
...preparedStaticProviderCatalog ? { preparedStaticProviderCatalog } : {},
...input.workspaceDir ? { workspaceDir: input.workspaceDir } : {}
});
const configuredRuntimeModels = completeConfiguredRuntimeModels(agentFacts, pluginGeneration, templateModelRegistry);
const providerOutcomes = catalogSource.providerOutcomes ?? [];
const completeModelCatalog = {
...modelCatalog,
staticEntries: input.config.models?.mode === "replace" ? [] : dedupeByKey(providerStaticModels, createModelCatalogIdentityKeyResolver()).map(modelCatalogRowToEntry),
...providerOutcomes.length > 0 ? { providerOutcomes } : {}
};
if (catalogMode === "live") fullModelCatalogSnapshots.add(completeModelCatalog);
return {
templateModelRegistry,
modelCatalog: completeModelCatalog,
configuredRuntimeModels,
inlineProviderModels: pluginGeneration.inlineProviderModels
};
};
return pluginGeneration.pluginRegistry ? withPluginRuntimeGenerationScope({
metadataSnapshot: pluginGeneration.pluginMetadataSnapshot,
pluginRegistry: pluginGeneration.pluginRegistry
}, prepare) : prepare();
}
function mergePreparedNativeCatalog(native, providers) {
const keyOf = createModelCatalogIdentityKeyResolver();
return {
...providers,
nativeProviderOutcomes: native.nativeProviderOutcomes,
nativeHostRows: native.nativeHostRows,
entries: dedupeByKey([...native.entries.filter((entry) => entry.nativeRuntime), ...[...providers.entries, ...providers.routeVariants].filter((entry) => !entry.nativeRuntime)], keyOf),
routeVariants: dedupeByKey([...native.routeVariants.filter((entry) => entry.nativeRuntime), ...providers.routeVariants.filter((entry) => !entry.nativeRuntime)], (entry) => modelCatalogRouteVariantKey(entry, keyOf(entry)))
};
}
function filterNativeModelCatalogScopes(scopes, includesProvider) {
return scopes && Object.fromEntries(Object.entries(scopes).map(([runtime, rows]) => [runtime, rows.filter(({ provider }) => includesProvider(provider))]));
}
function filterPreparedProviderCatalog(catalog, includesProvider) {
return {
...catalog,
entries: catalog.entries.filter((entry) => includesProvider(entry.provider)),
routeVariants: catalog.routeVariants.filter((entry) => includesProvider(entry.provider)),
staticEntries: catalog.staticEntries?.filter((entry) => includesProvider(entry.provider)),
providerOutcomes: catalog.providerOutcomes?.filter((outcome) => includesProvider(outcome.provider)),
nativeProviderOutcomes: filterNativeModelCatalogScopes(catalog.nativeProviderOutcomes, includesProvider),
nativeHostRows: filterNativeModelCatalogScopes(catalog.nativeHostRows, includesProvider)
};
}
function selectPreparedModelCatalogInventory(inventory, includesProvider) {
return {
...inventory,
catalog: filterPreparedProviderCatalog(inventory.catalog, includesProvider),
runtimeModels: new Map([...inventory.runtimeModels].filter(([provider]) => includesProvider(provider))),
providers: new Map([...inventory.providers].filter(([provider]) => includesProvider(provider))),
discoveryOrigins: inventory.discoveryOrigins.filter(({ provider }) => includesProvider(provider))
};
}
function mergePreparedModelCatalogInventory(previous, discovered, providers, normalize) {
const retained = previous && selectPreparedModelCatalogInventory(previous, (provider) => !providers.has(normalize(provider)));
const catalog = discovered.catalog;
const before = retained?.catalog;
const outcomes = [...before?.providerOutcomes ?? [], ...catalog.providerOutcomes ?? []];
return {
...discovered,
catalog: {
...catalog,
entries: [...before?.entries ?? [], ...catalog.entries],
routeVariants: [...before?.routeVariants ?? [], ...catalog.routeVariants],
staticEntries: [...before?.staticEntries ?? [], ...catalog.staticEntries ?? []],
providerOutcomes: outcomes,
authoritative: outcomes.every((outcome) => outcome.status === "ready")
},
runtimeModels: new Map([...retained?.runtimeModels ?? [], ...discovered.runtimeModels]),
providers: new Map([...retained?.providers ?? [], ...discovered.providers]),
discoveryOrigins: [...retained?.discoveryOrigins ?? [], ...discovered.discoveryOrigins]
};
}
function prepareModelCatalogPublication(discovered, runtimeModels, inventory, auth, normalizeProvider, hookRows) {
const catalog = {
...discovered,
entries: dedupeByKey([...discovered.entries, ...discovered.routeVariants].filter((entry) => !entry.nativeRuntime), createModelCatalogIdentityKeyResolver()),
routeVariants: discovered.routeVariants.filter((entry) => !entry.nativeRuntime)
};
setPreparedModelFullCatalogAuth(catalog, auth);
const failed = catalog.providerOutcomes?.filter((outcome) => outcome.status !== "ready") ?? [];
const discoveryOrigins = (catalog.providerOutcomes ?? []).filter((outcome) => outcome.status === "ready").map(({ provider, profileId }) => ({
provider: normalizeProvider(provider),
profileId
}));
const identityKey = createModelCatalogIdentityKeyResolver();
const rowKey = (entry) => modelCatalogRouteVariantKey(entry, identityKey({
provider: normalizeProvider(entry.provider),
id: entry.id
}));
const acceptedRows = /* @__PURE__ */ new Map();
for (const [owner, keys] of hookRows) {
const provider = normalizeProvider(owner);
const accepted = acceptedRows.get(provider) ?? /* @__PURE__ */ new Set();
for (const key of keys) accepted.add(key);
acceptedRows.set(provider, accepted);
}
const outcomeProviders = new Set(catalog.providerOutcomes?.map((outcome) => normalizeProvider(outcome.provider)));
const legacyRows = /* @__PURE__ */ new Map();
for (const entry of [...catalog.entries, ...catalog.routeVariants]) {
const provider = normalizeProvider(entry.provider);
const key = rowKey(entry);
if (outcomeProviders.has(provider) || !acceptedRows.get(provider)?.has(key)) continue;
const keys = legacyRows.get(provider) ?? /* @__PURE__ */ new Set();
keys.add(key);
legacyRows.set(provider, keys);
}
if (failed.length === 0) return {
catalog,
discoveryOrigins,
runtimeModels,
legacyRows
};
const previous = inventory?.catalog;
const previousAuth = previous && getPreparedModelFullCatalogAuth(previous);
const previousLegacyRows = /* @__PURE__ */ new Map();
for (const entry of [...previous?.entries ?? [], ...previous?.routeVariants ?? []]) {
const provider = normalizeProvider(entry.provider);
const key = rowKey(entry);
if (!entry.nativeRuntime && inventory?.providers.get(provider)?.legacyRows?.has(key)) {
const keys = previousLegacyRows.get(provider) ?? /* @__PURE__ */ new Set();
keys.add(key);
previousLegacyRows.set(provider, keys);
}
}
const starterProviders = new Set(failed.map(({ provider }) => normalizeProvider(provider)).filter((provider) => !discoveryOrigins.some((origin) => origin.provider === provider)));
const starters = (catalog.staticEntries ?? []).filter((entry) => !entry.nativeRuntime && starterProviders.has(normalizeProvider(entry.provider)));
const retainedProviders = new Set(failed.flatMap((outcome) => {
const provider = normalizeProvider(outcome.provider);
const previousOrigins = inventory?.discoveryOrigins.filter((candidate) => normalizeProvider(candidate.provider) === provider);
const hasLegacyInventory = Boolean(previousLegacyRows.get(provider)?.size);
if (discoveryOrigins.some((origin) => origin.provider === provider) || !previousOrigins?.length && !hasLegacyInventory || !previousAuth || !previousAuth.credentials || !auth.credentials || outcome.profileId !== void 0 && !previousOrigins?.some((candidate) => candidate.profileId === outcome.profileId) || previousAuth.authModes[provider] !== auth.authModes[provider]) return [];
return hasSamePreparedModelCatalogAuth(previousAuth, auth, (candidate) => normalizeProvider(candidate) === provider) ? [provider] : [];
}));
const discoveredRetainedProviders = new Set([...retainedProviders].filter((provider) => inventory?.discoveryOrigins.some((origin) => normalizeProvider(origin.provider) === provider)));
for (const [provider, keys] of previousLegacyRows) if (retainedProviders.has(provider) && !discoveredRetainedProviders.has(provider)) legacyRows.set(provider, keys);
const retain = (current, retained, key = createModelCatalogIdentityKeyResolver()) => dedupeByKey([
...current.filter((entry) => !discoveredRetainedProviders.has(normalizeProvider(entry.provider)) && !(retainedProviders.has(normalizeProvider(entry.provider)) && legacyRows.get(normalizeProvider(entry.provider))?.has(rowKey(entry)))),
...starters.filter((entry) => !retainedProviders.has(normalizeProvider(entry.provider))),
...retained.filter((entry) => !entry.nativeRuntime && retainedProviders.has(normalizeProvider(entry.provider)) && (discoveredRetainedProviders.has(normalizeProvider(entry.provider)) || legacyRows.get(normalizeProvider(entry.provider))?.has(rowKey(entry))))
], key).toSorted(compareModelCatalogEntries);
const routeKeyOf = createModelCatalogIdentityKeyResolver();
const published = {
...catalog,
entries: retain(catalog.entries, previous?.entries ?? []),
routeVariants: retain(catalog.routeVariants, previous?.routeVariants ?? [], (entry) => JSON.stringify([
routeKeyOf(entry),
entry.api,
entry.baseUrl,
entry.nativeRuntime
])),
authoritative: false
};
setPreparedModelFullCatalogAuth(published, auth);
const publishedRuntimeModels = new Map([...runtimeModels].filter(([provider]) => !discoveredRetainedProviders.has(normalizeProvider(provider))));
for (const [provider, models] of inventory?.runtimeModels ?? []) {
const normalized = normalizeProvider(provider);
if (discoveredRetainedProviders.has(normalized)) publishedRuntimeModels.set(provider, models);
else if (retainedProviders.has(normalized)) publishedRuntimeModels.set(provider, dedupeByKey([...(publishedRuntimeModels.get(provider) ?? []).filter((model) => !legacyRows.get(normalized)?.has(rowKey(modelCatalogRowToEntry(model)))), ...models.filter((model) => legacyRows.get(normalized)?.has(rowKey(modelCatalogRowToEntry(model))))], (model) => rowKey(modelCatalogRowToEntry(model))));
}
return {
catalog: published,
runtimeModels: publishedRuntimeModels,
legacyRows,
discoveryOrigins: [...discoveryOrigins, ...(inventory?.discoveryOrigins ?? []).filter((origin) => retainedProviders.has(normalizeProvider(origin.provider)))]
};
}
/** Reprojects retained inventory without carrying capabilities from a retired runtime. */
function materializePreparedModelCatalog(snapshot, runtimeCapabilityModels, configuredStaticEntries = []) {
const materialized = { ...snapshot };
const sourceEntries = snapshot.entries;
const identityKey = createModelCatalogIdentityKeyResolver();
const hostRows = enrichHarnessRows(Object.values(snapshot.nativeHostRows ?? {}).flat(), snapshot);
const runtimeByKey = new Map(runtimeCapabilityModels.map(({ provider, modelId, model }) => [identityKey({
provider,
id: modelId
}), modelCatalogRowToEntry(model)]));
const project = (entries) => entries.map((entry) => {
const runtime = runtimeByKey.get(identityKey(entry));
if (!runtime) return entry;
const thinkingPolicyProvider = runtime.provider;
if (entry.configuredReasoning !== void 0) return {
...entry,
thinkingPolicyProvider
};
const params = runtime.params || entry.params ? {
...runtime.params,
...entry.params
} : void 0;
const compat = runtime.compat || entry.compat ? {
...runtime.compat,
...entry.compat
} : void 0;
return {
...entry,
thinkingPolicyProvider,
...runtime.reasoning !== void 0 ? { reasoning: runtime.reasoning } : {},
...params ? { params } : {},
...compat ? { compat } : {}
};
});
materialized.entries = project(hostRows.length ? dedupeByKey([
...sourceEntries.filter((entry) => entry.nativeRuntime),
...hostRows,
...sourceEntries
], identityKey) : sourceEntries);
materialized.routeVariants = project(hostRows.length ? dedupeByKey([...hostRows, ...snapshot.routeVariants], (entry) => modelCatalogRouteVariantKey(entry, identityKey(entry))) : snapshot.routeVariants);
if (snapshot.staticEntries || configuredStaticEntries.length > 0) materialized.staticEntries = project(dedupeByKey([...configuredStaticEntries, ...snapshot.staticEntries ?? []], identityKey));
if (isPreparedModelCatalogFull(snapshot)) markPreparedModelCatalogFull(materialized);
copyPreparedModelFullCatalogAuth(snapshot, materialized);
return materialized;
}
/** Reports whether a catalog came from the complete prepared-catalog build path. */
const isPreparedModelCatalogFull = (snapshot) => fullModelCatalogSnapshots.has(snapshot);
/** Restores process-local provenance after a complete catalog crosses a worker boundary. */
function markPreparedModelCatalogFull(snapshot) {
fullModelCatalogSnapshots.add(snapshot);
return snapshot;
}
function createPreparedModelRuntimeSnapshot(catalogOwner, agentFacts, pluginGeneration, catalogFacts, catalogAccess, publishedConfig = agentFacts.input.config) {
const { credentials, input } = agentFacts;
const { mediaCapabilityProviders, mediaCapabilityProviderSource, messageToolCatalog, pluginMetadataSnapshot, pluginRegistry } = pluginGeneration;
const { configuredRuntimeModels, inlineProviderModels, templateModelRegistry } = catalogFacts;
const modelCatalog = materializePreparedModelCatalog(catalogFacts.modelCatalog, agentFacts.runtimeCapabilityModels, input.config.models?.mode === "replace" ? [] : configuredRuntimeModels.map(({ model }) => modelCatalogRowToEntry(model)));
prepareModelCatalogThinkingPolicies({
catalog: modelCatalog,
metadataSnapshot: pluginMetadataSnapshot,
providers: pluginRegistry?.providers
});
const createStores = () => {
const authStorage = AuthStorage.inMemory(credentials);
return {
authStorage,
modelRegistry: templateModelRegistry.fork(authStorage)
};
};
const snapshot = Object.freeze({
catalogOwner,
...input.agentId ? { agentId: input.agentId } : {},
agentDir: input.agentDir,
activeProjectKeys: [],
...input.inheritedAuthDir ? { inheritedAuthDir: input.inheritedAuthDir } : {},
...input.workspaceDir ? { workspaceDir: input.workspaceDir } : {},
config: publishedConfig,
observationConfig: input.config,
isCurrent: catalogAccess.isCurrent,
authModes: catalogAccess.initialAuth.authModes,
metadataSnapshot: pluginMetadataSnapshot,
allowGatewaySubagentBinding: input.allowGatewaySubagentBinding === true,
...pluginRegistry ? { pluginRegistry } : {},
...messageToolCatalog ? { messageToolCatalog } : {},
...mediaCapabilityProviders ? { mediaCapabilityProviders } : {},
...mediaCapabilityProviderSource && mediaCapabilityProviders ? { acquireMediaCapabilityProviders: () => acquirePreparedMediaCapabilityProviders(mediaCapabilityProviderSource, mediaCapabilityProviders, pluginRegistry ?? mediaCapabilityProviderSource.registry) } : {},
modelCatalog: catalogAccess.withRefreshStatus(modelCatalog),
readFullModelCatalog: catalogAccess.readFullModelCatalog,
refreshExpiredModelCatalog: catalogAccess.refreshExpiredModelCatalog,
readPublishedModels: catalogAccess.readPublishedModels,
loadFullModelCatalog: catalogAccess.loadFullModelCatalog,
loadNativeModelCatalog: catalogAccess.loadNativeModelCatalog,
configuredRuntimeModels,
configuredModelAliases: prepareConfiguredModelAliases(agentFacts, pluginGeneration, templateModelRegistry, configuredRuntimeModels),
findConfiguredRuntimeModel: createPreparedConfiguredRuntimeModelLookup(configuredRuntimeModels, pluginMetadataSnapshot),
inlineProviderModels,
createStores,
routeModelResolutionMemo: /* @__PURE__ */ new Map()
});
bindPreparedModelRuntimeAuth(snapshot, {
labels: catalogAccess.initialAuth.providerAuthLabels,
store: catalogAccess.initialAuth.authStore,
load: catalogAccess.loadAuth,
materializations: Object.freeze([...getPreparedRuntimeAuthMaterializations(input.agentDir)])
});
return snapshot;
}
//#endregion
export { markPreparedModelCatalogFull as a, mergePreparedNativeCatalog as c, retainPreparedModelCatalogPublication as d, selectPreparedModelCatalogInventory as f, isPreparedModelCatalogFull as i, prepareFullCatalogFacts as l, filterNativeModelCatalogScopes as n, materializePreparedModelCatalog as o, filterPreparedProviderCatalog as r, mergePreparedModelCatalogInventory as s, createPreparedModelRuntimeSnapshot as t, prepareModelCatalogPublication as u };