openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
157 lines (156 loc) • 8.96 kB
JavaScript
import { c as normalizeOptionalLowercaseString, l as normalizeOptionalString, o as normalizeLowercaseStringOrEmpty } from "./string-coerce-6kR-86XC.mjs";
import { c as isRecord } from "./record-coerce-TIsquoVR.mjs";
import { r as normalizeProviderId } from "./provider-id-BIyeXQag.mjs";
import { t as collectManifestModelIdNormalizationPolicies } from "./provider-model-id-normalization-B6VV6-sc.mjs";
import { n as MANIFEST_KEY } from "./legacy-names-DvDqYAnZ.mjs";
import { t as official_external_provider_catalog_default } from "./official-external-provider-catalog-BPRfPeaX.mjs";
import { t as normalizeManifestProviderRequestProvider } from "./plugin-provider-request-policy-BTFcZHnv.mjs";
//#region src/plugins/official-external-provider-endpoints.ts
/**
* Provider endpoint metadata for officially externalized provider plugins.
*
* Endpoint classification (SSRF, attribution, payload-compat policy) keys off
* base URLs and must keep working when the owning plugin is not installed:
* dist packages exclude externalized plugins, so their manifests are invisible
* to bundled discovery. Only the repo-bundled catalog JSON feeds this table;
* hosted marketplace feeds must never influence endpoint classification.
* Kept separate from official-external-plugin-catalog.ts so provider
* transports do not pull the ClawHub install/marketplace module graph.
*/
/**
* Lists manifest-shaped catalog metadata blocks that declare provider endpoints.
*
* The catalog mirrors manifests faithfully, including endpoint classes core
* does not (yet) recognize (e.g. deepinfra-native, gmi-native). The endpoint
* reader filters unknown classes exactly as it does for installed manifests,
* so they stay inert instead of complicating the mirror contract.
*/
function listOfficialExternalProviderEndpointManifests() {
const entries = official_external_provider_catalog_default.entries;
if (!Array.isArray(entries)) return [];
const manifests = [];
for (const entry of entries) {
if (!isRecord(entry)) continue;
const manifest = entry[MANIFEST_KEY];
if (isRecord(manifest) && Array.isArray(manifest.providerEndpoints)) manifests.push(manifest);
}
return manifests;
}
//#endregion
//#region src/plugins/setup-descriptors.ts
/** Lists setup provider ids and auth aliases owned by one plugin manifest. */
function listSetupProviderIds(record) {
const providerIds = record.setup?.providers?.map((entry) => entry.id) ?? record.providers;
const normalizedProviderIds = new Set(providerIds.map(normalizeProviderId));
const aliases = Object.entries(record.providerAuthAliases ?? {}).filter(([, target]) => typeof target === "string" && normalizedProviderIds.has(normalizeProviderId(target))).map(([alias]) => alias);
return [...providerIds, ...aliases];
}
/** Lists setup CLI backend ids from setup metadata or manifest contribution ids. */
function listSetupCliBackendIds(record) {
return record.setup?.cliBackends ?? record.cliBackends;
}
//#endregion
//#region src/plugins/plugin-metadata-provider-facts.ts
const PROVIDER_ENDPOINT_CLASSES = new Set("anthropic-public cerebras-native chutes-native deepseek-native github-copilot-native groq-native meta-native mistral-public minimax-native moonshot-native modelstudio-native nvidia-native openai-public openai opencode-native opencode-go-native azure-openai openrouter xai-native xiaomi-native zai-native google-generative-ai google-vertex".split(" "));
function normalizeProviderHosts(value) {
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string").map((entry) => entry.trim().toLowerCase()).filter(Boolean) : [];
}
function normalizePluginProviderBaseUrl(value) {
const trimmed = normalizeOptionalString(value);
const schemeless = trimmed && /^[a-z0-9.[\]-]+(?::\d+)?(?:[/?#].*)?$/i.test(trimmed);
const url = trimmed ? URL.parse(schemeless ? `https://${trimmed}` : trimmed) : null;
if (!url || url.protocol !== "http:" && url.protocol !== "https:") return;
url.hash = "";
url.search = "";
return normalizeOptionalLowercaseString(url.toString().replace(/\/+$/, ""));
}
function hostMatchesSuffix(host, suffix) {
if (!suffix) return false;
return suffix.startsWith(".") || suffix.startsWith("-") ? host.endsWith(suffix) : host === suffix || host.endsWith(`.${suffix}`);
}
/** Shares declared endpoint matching between request classification and catalog eligibility. */
function matchesPluginProviderEndpoint(endpoint, params) {
return (endpoint.hosts ?? []).includes(params.host) || (endpoint.hostSuffixes ?? []).some((suffix) => hostMatchesSuffix(params.host, suffix)) || Boolean(params.normalizedBaseUrl && (endpoint.baseUrls ?? []).some((baseUrl) => baseUrl === params.normalizedBaseUrl || normalizePluginProviderBaseUrl(baseUrl) === params.normalizedBaseUrl));
}
function prepareProviderEndpoints(value) {
if (!Array.isArray(value)) return [];
const endpoints = [];
for (const endpoint of value) {
if (!isRecord(endpoint)) continue;
const endpointClass = normalizeOptionalString(endpoint.endpointClass);
if (!endpointClass || !PROVIDER_ENDPOINT_CLASSES.has(endpointClass)) continue;
const googleVertexRegion = normalizeOptionalString(endpoint.googleVertexRegion);
const googleVertexRegionHostSuffix = normalizeOptionalString(endpoint.googleVertexRegionHostSuffix)?.toLowerCase();
endpoints.push({
endpointClass,
hosts: normalizeProviderHosts(endpoint.hosts),
hostSuffixes: normalizeProviderHosts(endpoint.hostSuffixes),
baseUrls: normalizeProviderHosts(endpoint.baseUrls).map(normalizePluginProviderBaseUrl).filter((baseUrl) => baseUrl !== void 0),
...googleVertexRegion ? { googleVertexRegion } : {},
...googleVertexRegionHostSuffix ? { googleVertexRegionHostSuffix } : {}
});
}
return endpoints;
}
const PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY = {
config: 0,
bundled: 1,
global: 2,
workspace: 3
};
/** Prepares package alias candidates without capturing current workspace trust. */
function buildPluginMetadataProviderAuthAliases(plugins) {
const aliases = /* @__PURE__ */ new Map();
let order = 0;
for (const plugin of plugins) {
const entries = [...Object.entries(plugin.providerAuthAliases ?? {}).toSorted(([left], [right]) => left.localeCompare(right)), ...(plugin.providerAuthChoices ?? []).flatMap((choice) => (choice.deprecatedChoiceIds ?? []).map((alias) => [alias, choice.provider]))];
for (const [rawAlias, rawTarget] of entries) {
const alias = normalizeProviderId(rawAlias);
const target = normalizeProviderId(typeof rawTarget === "string" ? rawTarget : rawTarget.provider);
if (!alias || !target) continue;
const candidates = aliases.get(alias) ?? [];
candidates.push({
plugin,
target,
...typeof rawTarget === "string" ? {} : { baseUrls: rawTarget.baseUrls },
order: order++
});
aliases.set(alias, candidates);
}
}
for (const candidates of aliases.values()) candidates.sort((left, right) => (PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY[left.plugin.origin] ?? Number.MAX_SAFE_INTEGER) - (PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY[right.plugin.origin] ?? Number.MAX_SAFE_INTEGER));
return aliases;
}
function buildPluginMetadataProviderFacts(plugins) {
const providerEndpoints = plugins.flatMap((plugin) => prepareProviderEndpoints(plugin.providerEndpoints));
const providerRequests = /* @__PURE__ */ new Map();
const providerAuthContributions = [];
for (const plugin of plugins) {
const envProviders = (plugin.setup?.providers ?? []).filter((provider) => provider.envVars?.length);
const evidenceProviders = (plugin.setup?.providers ?? []).filter((provider) => provider.authEvidence?.length);
const fallbackProviderRefs = plugin.setup?.requiresRuntime !== false ? listSetupProviderIds(plugin).map(normalizeProviderId).filter(Boolean) : [];
if (envProviders.length || evidenceProviders.length || fallbackProviderRefs.length) providerAuthContributions.push({
plugin,
envProviders,
evidenceProviders,
fallbackProviderRefs
});
const requests = isRecord(plugin.providerRequest?.providers) ? plugin.providerRequest.providers : {};
for (const [rawProvider, request] of Object.entries(requests)) {
if (!isRecord(request)) continue;
const provider = normalizeLowercaseStringOrEmpty(rawProvider);
if (!provider) continue;
providerRequests.set(provider, normalizeManifestProviderRequestProvider(request) ?? {});
}
}
for (const manifest of listOfficialExternalProviderEndpointManifests()) providerEndpoints.push(...prepareProviderEndpoints(manifest.providerEndpoints));
return {
providerEndpoints,
providerRequests,
providerAuthContributions,
modelIdNormalizationPolicies: collectManifestModelIdNormalizationPolicies(plugins),
providerAuthAliases: buildPluginMetadataProviderAuthAliases(plugins)
};
}
//#endregion
export { listSetupCliBackendIds as a, normalizePluginProviderBaseUrl as i, buildPluginMetadataProviderFacts as n, listSetupProviderIds as o, matchesPluginProviderEndpoint as r, buildPluginMetadataProviderAuthAliases as t };