openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
291 lines (290 loc) • 12.8 kB
JavaScript
import { g as sortUniqueStrings } from "./string-normalization-WNUDCpXX.js";
import { i as normalizeProviderId } from "./provider-id-Dq06Bcx6.js";
import { n as registerPluginMetadataProcessMemoLifecycleClear } from "./plugin-metadata-lifecycle-C3dWg4tn.js";
import { n as getCachedPluginModuleLoader, s as clearNativeRequireJavaScriptModuleCache, t as createPluginModuleLoaderCache } from "./plugin-module-loader-cache-lz0qhu-X.js";
import { t as planManifestModelCatalogRows } from "./manifest-planner-BRQyTcMi.js";
import { s as loadManifestMetadataSnapshot } from "./manifest-contract-eligibility-DEeoLRlM.js";
import { i as withProfile } from "./plugin-load-profile-Dw-hJkNg.js";
import { u as resolveDiscoveredProviderPluginIds } from "./plugin-auto-enable-pAtqig-B.js";
import { n as resolvePluginProviders } from "./providers.runtime-DOSqHxyZ.js";
import path from "node:path";
//#region src/plugins/provider-discovery.runtime.ts
const providerDiscoveryModuleLoaders = createPluginModuleLoaderCache();
const providerDiscoveryModuleRoots = /* @__PURE__ */ new Map();
function resolveProviderDiscoveryDependencyRoot(rootDir) {
const extensionsDir = path.dirname(rootDir);
const distDir = path.dirname(extensionsDir);
if (path.basename(extensionsDir) === "extensions" && path.basename(distDir) === "dist") return distDir;
return rootDir;
}
function clearProviderDiscoveryModuleLoaders() {
providerDiscoveryModuleLoaders.clear();
for (const [modulePath, rootDir] of providerDiscoveryModuleRoots) clearNativeRequireJavaScriptModuleCache(modulePath, { dependencyRoot: rootDir });
providerDiscoveryModuleRoots.clear();
}
registerPluginMetadataProcessMemoLifecycleClear(clearProviderDiscoveryModuleLoaders);
function normalizeDiscoveryModule(value) {
const resolved = value && typeof value === "object" && "default" in value && value.default !== void 0 ? value.default : value;
if (Array.isArray(resolved)) return resolved;
if (resolved && typeof resolved === "object" && "id" in resolved) return [resolved];
if (value && typeof value === "object" && !Array.isArray(value)) {
const record = value;
if (Array.isArray(record.providers)) return record.providers;
if (record.provider) return [record.provider];
}
return [];
}
function loadProviderDiscoveryModule(params) {
providerDiscoveryModuleRoots.set(params.modulePath, resolveProviderDiscoveryDependencyRoot(params.rootDir));
const moduleLoader = getCachedPluginModuleLoader({
cache: providerDiscoveryModuleLoaders,
modulePath: params.modulePath,
importerUrl: import.meta.url,
loaderFilename: import.meta.url,
preferBuiltDist: true
});
return withProfile({
pluginId: params.pluginId,
source: params.modulePath
}, "provider-discovery-entry", () => moduleLoader(params.modulePath));
}
function hasLiveProviderDiscoveryHook(provider) {
return typeof provider.catalog?.run === "function" || typeof provider.discovery?.run === "function";
}
function hasProviderCatalogHook(provider) {
return hasLiveProviderDiscoveryHook(provider) || typeof provider.staticCatalog?.run === "function";
}
function hasProviderAuthEnvCredential(plugin, env) {
return [...(plugin.setup?.providers ?? []).flatMap((provider) => provider.envVars ?? []), ...Object.values(plugin.providerAuthEnvVars ?? {}).flat()].some((name) => {
const value = env[name]?.trim();
return value !== void 0 && value !== "";
});
}
function modelDefinitionCostFromManifestRow(row) {
if (!row.cost || row.cost.input === void 0 || row.cost.output === void 0 || row.cost.cacheRead === void 0 || row.cost.cacheWrite === void 0) return {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0
};
return {
input: row.cost.input,
output: row.cost.output,
cacheRead: row.cost.cacheRead,
cacheWrite: row.cost.cacheWrite,
...row.cost.tieredPricing ? { tieredPricing: row.cost.tieredPricing } : {}
};
}
function modelDefinitionFromManifestRow(row) {
const cost = modelDefinitionCostFromManifestRow(row);
if (!row.contextWindow || !row.maxTokens) return;
const input = row.input.filter((value) => value === "text" || value === "image");
return {
id: row.id,
name: row.name || row.id,
...row.api ? { api: row.api } : {},
...row.baseUrl ? { baseUrl: row.baseUrl } : {},
reasoning: row.reasoning,
input,
cost,
contextWindow: row.contextWindow,
...row.contextTokens ? { contextTokens: row.contextTokens } : {},
maxTokens: row.maxTokens,
...row.headers ? { headers: row.headers } : {},
...row.compat ? { compat: row.compat } : {},
...row.mediaInput ? { mediaInput: row.mediaInput } : {}
};
}
function providerConfigFromManifestRows(rows) {
const firstRow = rows[0];
if (!firstRow?.baseUrl || !firstRow.api) return;
const models = rows.map((row) => modelDefinitionFromManifestRow(row)).filter((model) => Boolean(model));
if (models.length === 0) return;
return {
baseUrl: firstRow?.baseUrl ?? "",
...firstRow?.api ? { api: firstRow.api } : {},
models
};
}
function resolveManifestModelCatalogProviders(pluginRecords) {
const providers = [];
for (const plugin of pluginRecords) {
if (!plugin.modelCatalog?.providers) continue;
const plan = planManifestModelCatalogRows({ registry: { plugins: [plugin] } });
for (const entry of plan.entries) {
if (entry.rows.length === 0 || entry.discovery === "runtime") continue;
const providerConfig = providerConfigFromManifestRows(entry.rows);
if (!providerConfig) continue;
providers.push({
id: entry.provider,
pluginId: plugin.id,
label: entry.provider,
auth: [],
staticCatalog: {
order: "simple",
run: async () => ({ providers: { [entry.provider]: providerConfig } })
}
});
}
}
return providers;
}
function resolveRuntimeManifestCatalogPluginIds(pluginRecords) {
const pluginIds = /* @__PURE__ */ new Set();
for (const plugin of pluginRecords) {
const ownedProviders = new Set(plugin.providers.map((provider) => normalizeProviderId(provider)));
if (Object.entries(plugin.modelCatalog?.discovery ?? {}).some(([provider, discovery]) => discovery === "runtime" && ownedProviders.has(normalizeProviderId(provider)))) pluginIds.add(plugin.id);
if (!plugin.modelCatalog?.providers) continue;
if (planManifestModelCatalogRows({ registry: { plugins: [plugin] } }).entries.some((entry) => entry.discovery === "runtime")) pluginIds.add(plugin.id);
}
return pluginIds;
}
function resolveProviderDiscoveryEntryPlugins(params) {
const metadataSnapshot = params.pluginMetadataSnapshot ?? loadManifestMetadataSnapshot({
config: params.config ?? {},
env: params.env ?? process.env,
...params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}
});
const registry = metadataSnapshot.index;
const manifestRegistry = metadataSnapshot.manifestRegistry;
const pluginIds = resolveDiscoveredProviderPluginIds({
...params,
registry,
manifestRegistry
});
const pluginIdSet = new Set(pluginIds);
const pluginRecords = manifestRegistry.plugins.filter((plugin) => pluginIdSet.has(plugin.id));
const runtimeManifestCatalogPluginIds = resolveRuntimeManifestCatalogPluginIds(pluginRecords);
const entryRecords = pluginRecords.filter((plugin) => plugin.providerDiscoverySource);
const entryPluginIds = new Set(entryRecords.map((plugin) => plugin.id));
const manifestProviders = resolveManifestModelCatalogProviders(pluginRecords);
const manifestEntryPluginIds = /* @__PURE__ */ new Set();
for (const pluginId of manifestProviders.map((provider) => provider.pluginId)) if (pluginId) {
manifestEntryPluginIds.add(pluginId);
if (!runtimeManifestCatalogPluginIds.has(pluginId)) entryPluginIds.add(pluginId);
}
const complete = entryPluginIds.size === pluginIdSet.size;
const entriesOnlyComplete = new Set([...entryPluginIds, ...manifestEntryPluginIds]).size === pluginIdSet.size;
if (entryRecords.length === 0) return {
providers: manifestProviders,
complete,
pluginRecords,
entryPluginIds,
manifestEntryPluginIds,
runtimeManifestCatalogPluginIds
};
if (params.requireCompleteDiscoveryEntryCoverage && !(params.discoveryEntriesOnly === true ? entriesOnlyComplete : complete)) return {
providers: [],
complete: false,
pluginRecords,
entryPluginIds,
manifestEntryPluginIds,
runtimeManifestCatalogPluginIds
};
const providers = [];
for (const manifest of entryRecords) try {
const moduleExport = loadProviderDiscoveryModule({
pluginId: manifest.id,
modulePath: manifest.providerDiscoverySource,
rootDir: manifest.rootDir
});
providers.push(...normalizeDiscoveryModule(moduleExport).map((provider) => Object.assign({}, provider, { pluginId: manifest.id })));
} catch {
return {
providers: manifestProviders,
complete: false,
pluginRecords,
entryPluginIds,
manifestEntryPluginIds,
runtimeManifestCatalogPluginIds
};
}
return {
providers: [...manifestProviders, ...providers],
complete,
pluginRecords,
entryPluginIds,
manifestEntryPluginIds,
runtimeManifestCatalogPluginIds
};
}
function resolveSelectiveFullPluginIds(params) {
const missingEntryCredentialPluginIds = params.entryResult.pluginRecords.filter((plugin) => !params.entryResult.entryPluginIds.has(plugin.id)).filter((plugin) => hasProviderAuthEnvCredential(plugin, params.env)).map((plugin) => plugin.id);
const runtimeManifestCatalogPluginIds = listRuntimeManifestCatalogPluginIds(params.entryResult);
return sortUniqueStrings([...missingEntryCredentialPluginIds, ...runtimeManifestCatalogPluginIds]);
}
function listRuntimeManifestCatalogPluginIds(entryResult) {
return [...entryResult.runtimeManifestCatalogPluginIds];
}
function resolveMissingEntryPluginIds(entryResult) {
return entryResult.pluginRecords.filter((plugin) => !entryResult.entryPluginIds.has(plugin.id)).map((plugin) => plugin.id);
}
function resolveRuntimeEntryProviders(entryResult) {
return entryResult.providers.filter((provider) => {
if (hasLiveProviderDiscoveryHook(provider)) return true;
return Boolean(provider.pluginId && entryResult.entryPluginIds.has(provider.pluginId) && typeof provider.staticCatalog?.run === "function");
});
}
function withoutFullLoadedPluginEntries(providers, pluginIds) {
if (pluginIds.length === 0) return providers;
const pluginIdSet = new Set(pluginIds);
return providers.filter((provider) => !provider.pluginId || !pluginIdSet.has(provider.pluginId));
}
function resolvePluginDiscoveryProvidersRuntime(params) {
const env = params.env ?? process.env;
const bundledProviderVitestCompat = params.bundledProviderVitestCompat ?? env.VITEST === "true";
const entryResult = resolveProviderDiscoveryEntryPlugins({
...params,
env
});
const entryProviders = entryResult.providers.filter(hasProviderCatalogHook);
const runtimeEntryProviders = resolveRuntimeEntryProviders(entryResult);
if (params.discoveryEntriesOnly === true) return entryProviders;
if (entryResult.providers.length > 0 && entryResult.complete && runtimeEntryProviders.length === entryResult.providers.length && entryResult.runtimeManifestCatalogPluginIds.size === 0) return runtimeEntryProviders;
if (params.onlyPluginIds === void 0 && runtimeEntryProviders.length > 0) {
const fullPluginIds = resolveSelectiveFullPluginIds({
entryResult,
env
});
const fullProviders = fullPluginIds.length > 0 ? resolvePluginProviders({
...params,
env,
bundledProviderVitestCompat,
onlyPluginIds: fullPluginIds
}) : [];
return [...withoutFullLoadedPluginEntries(runtimeEntryProviders, fullPluginIds), ...fullProviders];
}
if (runtimeEntryProviders.length > 0) {
const fullPluginIds = sortUniqueStrings([...resolveMissingEntryPluginIds(entryResult), ...listRuntimeManifestCatalogPluginIds(entryResult)]);
const fullProviders = fullPluginIds.length > 0 ? resolvePluginProviders({
...params,
env,
bundledProviderVitestCompat,
onlyPluginIds: fullPluginIds
}) : [];
return [...withoutFullLoadedPluginEntries(runtimeEntryProviders, fullPluginIds), ...fullProviders];
}
const runtimeManifestCatalogPluginIds = listRuntimeManifestCatalogPluginIds(entryResult);
if (runtimeManifestCatalogPluginIds.length > 0) return resolvePluginProviders({
...params,
env,
bundledProviderVitestCompat,
onlyPluginIds: runtimeManifestCatalogPluginIds
});
if (entryProviders.length > 0) {
const fullPluginIds = sortUniqueStrings(entryProviders.map((provider) => provider.pluginId).filter((pluginId) => typeof pluginId === "string" && pluginId !== ""));
if (fullPluginIds.length > 0) return resolvePluginProviders({
...params,
env,
bundledProviderVitestCompat,
onlyPluginIds: fullPluginIds
});
}
return resolvePluginProviders({
...params,
env,
bundledProviderVitestCompat
});
}
//#endregion
export { resolvePluginDiscoveryProvidersRuntime as n, clearProviderDiscoveryModuleLoaders as t };