openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
1,156 lines (1,155 loc) • 46 kB
JavaScript
import "./src-vebZIeLe.js";
import { t as expectDefined } from "./expect-CyE8FADM.js";
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { c as normalizeOptionalLowercaseString, o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js";
import { v as sortUniqueStrings } from "./string-normalization-DsCfAx8q.js";
import { a as createLazyRuntimeSurface, i as createLazyRuntimeNamedExport } from "./lazy-runtime-CgCh8H_K.js";
import { v as resolveSecretInputRef } from "./types.secrets-kC0nOetj.js";
import { f as secretRefKey } from "./ref-contract-D92DqQ-r.js";
import { i as loadInstalledPluginIndexInstallRecordsSync } from "./installed-plugin-index-record-reader-SXWwf_BU.js";
import "./shared-CeAc-MzA.js";
import { d as pushWarning, g as digestRuntimeWebOwnerContract, m as isExpectedResolvedSecretValue, u as pushInactiveSurfaceWarning } from "./runtime-shared-CqbaocQu.js";
import { i as setPathExistingStrict } from "./path-utils-BSrJtisq.js";
import { r as resolveSecretRefValues } from "./resolve-224YoYfx.js";
import { a as isProviderScopedSecretResolutionError, t as describeSecretResolutionError } from "./resolve-errors-C2XRFrol.js";
import { i as associateSecretResolutionErrorOwners, l as isRetryableSecretDegradationReason } from "./runtime-degraded-state-D5EZZ925.js";
import { n as normalizeSecretInput } from "./normalize-secret-input-Df_qhWv_.js";
import "./installed-plugin-index-records-C06Xozeq.js";
import { l as getActiveSecretsRuntimeSnapshotState } from "./runtime-state-C4aJ8Hzz.js";
import { n as sortPluginEntriesForAutoDetect } from "./plugin-entry-order-DxrT0ucv.js";
import { a as resolveBundledExplicitWebSearchProvidersFromPublicArtifacts, i as resolveBundledExplicitWebFetchProvidersFromPublicArtifacts } from "./web-provider-public-artifacts.explicit-Qonq-IRk.js";
import { i as warnDegradedSecretOwner, t as classifySecretOwnerDegradationState } from "./runtime-owner-assignments-CLf4mfX3.js";
import { t as hasCredentialBearingObjectValue } from "./runtime-secret-scan-ByLaDc9T.js";
//#region src/secrets/runtime-web-secret-owner.ts
/** Stable degraded-owner id for one configured web provider surface. */
function runtimeWebSecretOwnerId(kind, providerId) {
return `web-${kind}:${providerId}`;
}
//#endregion
//#region src/secrets/runtime-web-tools-selection.types.ts
/** Carries typed web-provider ownership through strict reload failures. */
var RuntimeWebProviderUnavailableError = class extends Error {
constructor(code, reason, unavailableProviders) {
super(`[${code}] ${reason}`);
this.name = "RuntimeWebProviderUnavailableError";
this.unavailableProviders = unavailableProviders;
}
};
//#endregion
//#region src/secrets/runtime-web-tools.shared.ts
const loadResolveManifestContractOwnerPluginId = createLazyRuntimeNamedExport(() => import("./runtime-web-tools-manifest.runtime.js"), "resolveManifestContractOwnerPluginId");
function pushInactiveProviderCredentialWarnings(params) {
for (const provider of params.selection.providers) {
if (provider.id === params.skipProviderId) continue;
const value = params.selection.readConfiguredCredential({
provider,
config: params.selection.sourceConfig,
toolConfig: params.selection.toolConfig
});
if (!params.selection.hasConfiguredSecretRef(value, params.selection.defaults)) continue;
for (const path of params.selection.inactivePathsForProvider(provider)) pushInactiveSurfaceWarning({
context: params.selection.context,
path,
details: params.details
});
}
}
function normalizeKnownProvider(value, providers) {
const normalized = normalizeOptionalLowercaseString(value);
if (!normalized) return;
if (providers.some((provider) => provider.id === normalized)) return normalized;
}
/**
* Returns whether a configured value or sibling ref field contains a SecretRef.
*/
function hasConfiguredSecretRef(value, defaults) {
return Boolean(resolveSecretInputRef({
value,
defaults
}).ref);
}
function getProviderEnvVars(provider) {
return "envVars" in provider && Array.isArray(provider.envVars) ? provider.envVars : [];
}
function setResolvedCredentialPath(params) {
const pathSegments = params.path.split(".").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
if (pathSegments.length === 0) return;
try {
setPathExistingStrict(params.resolvedConfig, pathSegments, params.value);
} catch {}
}
/**
* Resolves available providers, configured provider validity, and whether the surface is active.
*/
async function resolveRuntimeWebProviderSurface(params) {
let configuredBundledPluginId = params.configuredBundledPluginIdHint;
if (!configuredBundledPluginId && params.rawProvider) configuredBundledPluginId = (await loadResolveManifestContractOwnerPluginId())({
contract: params.contract,
value: params.rawProvider,
origin: "bundled",
config: params.sourceConfig,
env: {
...process.env,
...params.context.env
},
manifestRecords: params.context.manifestRegistry?.plugins
});
let allProviders = params.sortProviders(await params.resolveProviders({ configuredBundledPluginId }));
if (params.rawProvider && params.configuredBundledPluginIdHint && configuredBundledPluginId && !allProviders.some((provider) => provider.id === params.rawProvider)) configuredBundledPluginId = void 0;
if (params.rawProvider && !configuredBundledPluginId && !allProviders.some((provider) => provider.id === params.rawProvider)) {
configuredBundledPluginId = (await loadResolveManifestContractOwnerPluginId())({
contract: params.contract,
value: params.rawProvider,
origin: "bundled",
config: params.sourceConfig,
env: {
...process.env,
...params.context.env
},
manifestRecords: params.context.manifestRegistry?.plugins
});
allProviders = params.sortProviders(await params.resolveProviders({ configuredBundledPluginId }));
}
const hasConfiguredSurface = Boolean(params.toolConfig) || allProviders.some((provider) => {
if (params.ignoreKeylessProvidersForConfiguredSurface && provider.requiresCredential === false) return false;
return params.readConfiguredCredential({
provider,
config: params.sourceConfig,
toolConfig: params.toolConfig
}) !== void 0 || params.readConfiguredCredentialFallback?.({
provider,
config: params.sourceConfig,
toolConfig: params.toolConfig
})?.value !== void 0;
});
const providers = hasConfiguredSurface || !params.emptyProvidersWhenSurfaceMissing ? allProviders : [];
const configuredProvider = normalizeKnownProvider(params.rawProvider, params.normalizeConfiguredProviderAgainstActiveProviders ? providers : allProviders);
const invalidConfiguredProvider = params.normalizeConfiguredProviderAgainstActiveProviders === true && Boolean(params.rawProvider) && !configuredProvider;
if (params.rawProvider && !configuredProvider) {
const diagnostic = {
code: params.invalidAutoDetectCode,
message: invalidConfiguredProvider ? `${params.providerPath} is "${params.rawProvider}". No provider will be selected.` : `${params.providerPath} is "${params.rawProvider}". Falling back to auto-detect precedence.`,
path: params.providerPath
};
params.diagnostics.push(diagnostic);
params.metadataDiagnostics.push(diagnostic);
pushWarning(params.context, {
code: params.invalidAutoDetectCode,
path: params.providerPath,
message: diagnostic.message
});
}
return {
providers,
configuredProvider,
enabled: hasConfiguredSurface && !invalidConfiguredProvider && (!isRecord(params.toolConfig) || params.toolConfig.enabled !== false),
hasConfiguredSurface
};
}
/**
* Selects a configured or auto-detected provider and materializes its resolved credential.
*/
async function resolveRuntimeWebProviderSelection(params) {
if (params.configuredProvider) {
params.metadata.providerConfigured = params.configuredProvider;
params.metadata.providerSource = "configured";
}
const unavailableProviders = [];
const resolveProviderContractDigest = (providerId) => digestRuntimeWebOwnerContract({
...params,
providerId
});
let selectedProvider;
let selectedPath;
let selectedResolution;
if (params.enabled) {
const candidates = params.configuredProvider ? params.providers.filter((provider) => provider.id === params.configuredProvider) : params.providers;
const unresolvedWithoutFallback = [];
let keylessFallbackProvider;
for (const provider of candidates) {
const contractDigest = resolveProviderContractDigest(provider.id);
const isKeyless = provider.requiresCredential === false;
if (isKeyless) {
if (!params.configuredProvider && !params.allowKeylessAutoSelect) continue;
if (params.deferKeylessFallback && !params.configuredProvider) {
keylessFallbackProvider ||= provider;
continue;
}
}
const path = params.inactivePathsForProvider(provider)[0] ?? "";
const value = params.readConfiguredCredential({
provider,
config: params.sourceConfig,
toolConfig: params.toolConfig
});
const resolution = await params.resolveSecretInput({
providerId: provider.id,
value,
path,
envVars: getProviderEnvVars(provider),
contractDigest
});
let selectedCandidatePath = path;
let selectedCandidateResolution = resolution;
if (!resolution.value && !resolution.secretRefConfigured) {
const fallback = params.readConfiguredCredentialFallback?.({
provider,
config: params.sourceConfig,
toolConfig: params.toolConfig
});
if (fallback?.value !== void 0) {
selectedCandidatePath = fallback.path;
selectedCandidateResolution = await params.resolveSecretInput({
providerId: provider.id,
value: fallback.value,
path: fallback.path,
envVars: getProviderEnvVars(provider),
contractDigest
});
}
} else if (resolution.source === "env" && !resolution.secretRefConfigured) {
const fallback = params.readConfiguredCredentialFallback?.({
provider,
config: params.sourceConfig,
toolConfig: params.toolConfig
});
if (fallback?.value !== void 0 && params.hasConfiguredSecretRef(fallback.value, params.defaults)) {
const fallbackResolution = await params.resolveSecretInput({
providerId: provider.id,
value: fallback.value,
path: fallback.path,
envVars: getProviderEnvVars(provider),
contractDigest
});
if (fallbackResolution.source === "secretRef" && fallbackResolution.value) setResolvedCredentialPath({
resolvedConfig: params.resolvedConfig,
path: fallback.path,
value: fallbackResolution.value
});
}
}
if (selectedCandidateResolution.secretRefConfigured && !selectedCandidateResolution.value && selectedCandidateResolution.unresolvedRefReason) unresolvedWithoutFallback.push({
provider: provider.id,
path: selectedCandidatePath,
ref: selectedCandidateResolution.secretRef,
refKey: selectedCandidateResolution.secretRefKey,
reason: selectedCandidateResolution.unresolvedRefReason,
contractDigest,
restoreResolvedValue: (resolvedValue) => params.setResolvedCredential({
resolvedConfig: params.resolvedConfig,
provider,
value: resolvedValue
})
});
if (isKeyless && selectedCandidateResolution.secretRefConfigured && !selectedCandidateResolution.value) continue;
if (isKeyless && !params.configuredProvider && !selectedCandidateResolution.value) continue;
if (params.configuredProvider) {
selectedProvider = provider.id;
selectedPath = selectedCandidatePath;
selectedResolution = selectedCandidateResolution;
if (selectedCandidateResolution.value) {
setResolvedCredentialPath({
resolvedConfig: params.resolvedConfig,
path: selectedCandidatePath,
value: selectedCandidateResolution.value
});
params.setResolvedCredential({
resolvedConfig: params.resolvedConfig,
provider,
value: selectedCandidateResolution.value
});
}
break;
}
if (isKeyless) {
selectedProvider = provider.id;
selectedPath = selectedCandidatePath;
selectedResolution = selectedCandidateResolution;
if (selectedCandidateResolution.value) {
setResolvedCredentialPath({
resolvedConfig: params.resolvedConfig,
path: selectedCandidatePath,
value: selectedCandidateResolution.value
});
params.setResolvedCredential({
resolvedConfig: params.resolvedConfig,
provider,
value: selectedCandidateResolution.value
});
}
break;
}
if (selectedCandidateResolution.value) {
selectedProvider = provider.id;
selectedPath = selectedCandidatePath;
selectedResolution = selectedCandidateResolution;
setResolvedCredentialPath({
resolvedConfig: params.resolvedConfig,
path: selectedCandidatePath,
value: selectedCandidateResolution.value
});
params.setResolvedCredential({
resolvedConfig: params.resolvedConfig,
provider,
value: selectedCandidateResolution.value
});
break;
}
}
if (!selectedProvider && keylessFallbackProvider && params.allowKeylessAutoSelect) {
selectedProvider = keylessFallbackProvider.id;
selectedResolution = {
source: "missing",
secretRefConfigured: false
};
}
const recordUnresolvedNoFallback = (unresolved) => {
const diagnostic = {
code: params.noFallbackCode,
message: unresolved.reason,
path: unresolved.path
};
params.diagnostics.push(diagnostic);
params.metadata.diagnostics.push(diagnostic);
pushWarning(params.context, {
code: params.noFallbackCode,
path: unresolved.path,
message: unresolved.reason
});
};
const failUnresolvedNoFallback = (unresolved, related = [unresolved]) => {
recordUnresolvedNoFallback(unresolved);
const relatedUnavailableProviders = related.flatMap((entry) => entry.ref && entry.refKey ? [{
providerId: entry.provider,
path: entry.path,
ref: entry.ref,
refKey: entry.refKey,
reason: entry.reason,
contractDigest: entry.contractDigest,
restoreResolvedValue: entry.restoreResolvedValue
}] : []);
if (relatedUnavailableProviders.length > 0) {
const error = new RuntimeWebProviderUnavailableError(params.noFallbackCode, unresolved.reason, relatedUnavailableProviders);
params.onUnavailableProviders?.(error);
throw error;
}
throw new Error(`[${params.noFallbackCode}] ${unresolved.reason}`);
};
if (params.configuredProvider) {
const unresolved = unresolvedWithoutFallback[0];
if (unresolved) {
const refKey = unresolved.refKey;
const ref = unresolved.ref;
if (refKey && ref) {
const unavailable = {
providerId: params.configuredProvider,
path: unresolved.path,
ref,
refKey,
reason: unresolved.reason,
contractDigest: unresolved.contractDigest,
restoreResolvedValue: unresolved.restoreResolvedValue
};
if (params.allowUnavailableProviders) unavailableProviders.push(unavailable);
else failUnresolvedNoFallback(unresolved);
} else failUnresolvedNoFallback(unresolved);
}
} else {
if (!selectedProvider && unresolvedWithoutFallback.length > 0) {
const firstUnresolved = expectDefined(unresolvedWithoutFallback[0], "unresolved without fallback entry at 0");
if (!params.allowUnavailableProviders) failUnresolvedNoFallback(firstUnresolved, unresolvedWithoutFallback);
const unavailable = unresolvedWithoutFallback.flatMap((entry) => entry.ref && entry.refKey ? [{
providerId: entry.provider,
path: entry.path,
ref: entry.ref,
refKey: entry.refKey,
reason: entry.reason,
contractDigest: entry.contractDigest,
restoreResolvedValue: entry.restoreResolvedValue
}] : []);
if (unavailable.length !== unresolvedWithoutFallback.length) failUnresolvedNoFallback(firstUnresolved, unresolvedWithoutFallback);
unavailableProviders.push(...unavailable);
}
if (selectedProvider) {
const selectedDetails = params.providers.find((entry) => entry.id === selectedProvider)?.requiresCredential === false ? `${params.scopePath} auto-detected keyless provider "${selectedProvider}".` : `${params.scopePath} auto-detected provider "${selectedProvider}" from available credentials.`;
const diagnostic = {
code: params.autoDetectSelectedCode,
message: selectedDetails,
path: `${params.scopePath}.provider`
};
params.diagnostics.push(diagnostic);
params.metadata.diagnostics.push(diagnostic);
}
}
if (selectedProvider && unavailableProviders.length === 0) {
params.metadata.selectedProvider = selectedProvider;
params.metadata.selectedProviderKeySource = selectedResolution?.source;
if (!params.configuredProvider) params.metadata.providerSource = "auto-detect";
const provider = params.providers.find((entry) => entry.id === selectedProvider);
if (provider && params.mergeRuntimeMetadata) await params.mergeRuntimeMetadata({
provider,
metadata: params.metadata,
toolConfig: params.toolConfig,
selectedResolution
});
}
}
if (params.enabled && !params.configuredProvider && params.metadata.selectedProvider) pushInactiveProviderCredentialWarnings({
selection: params,
skipProviderId: params.metadata.selectedProvider,
details: `${params.scopePath} auto-detected provider is "${params.metadata.selectedProvider}".`
});
else if (params.toolConfig && !params.enabled) pushInactiveProviderCredentialWarnings({
selection: params,
details: `${params.scopePath} is disabled.`
});
if (params.enabled && params.toolConfig && params.configuredProvider) pushInactiveProviderCredentialWarnings({
selection: params,
skipProviderId: params.configuredProvider,
details: `${params.scopePath}.provider is "${params.configuredProvider}".`
});
const selectedSecretOwner = selectedProvider && selectedPath && selectedResolution?.secretRef && selectedResolution.secretRefKey ? {
providerId: selectedProvider,
path: selectedPath,
ref: selectedResolution.secretRef,
refKey: selectedResolution.secretRefKey,
contractDigest: resolveProviderContractDigest(selectedProvider),
...selectedResolution.value ? { resolvedValue: selectedResolution.value } : {}
} : void 0;
return {
secretOwners: selectedSecretOwner ? [selectedSecretOwner] : unavailableProviders,
unavailableProviders
};
}
//#endregion
//#region src/secrets/runtime-web-tools.ts
/** Builds web-tool secret metadata from config, plugins, and provider contracts. */
const loadRuntimeWebToolsFallbackProviders = createLazyRuntimeSurface(() => import("./runtime-web-tools-fallback.runtime.js"), ({ runtimeWebToolsFallbackProviders }) => runtimeWebToolsFallbackProviders);
const loadRuntimeWebToolsPublicArtifacts = createLazyRuntimeSurface(() => import("./runtime-web-tools-public-artifacts.runtime.js"), (mod) => mod);
const loadRuntimeWebToolsManifest = createLazyRuntimeSurface(() => import("./runtime-web-tools-manifest.runtime.js"), (mod) => mod);
function ensureConfigObject(target, key) {
const current = target[key];
if (isRecord(current)) return current;
const next = {};
target[key] = next;
return next;
}
function createUnavailableWebProviderOwner(params) {
return {
ownerKind: "capability",
ownerId: runtimeWebSecretOwnerId(params.kind, params.unavailable.providerId),
state: "unavailable",
degradationState: params.degradationState ?? "cold",
paths: [params.unavailable.path],
refKeys: [params.unavailable.refKey],
reason: params.unavailable.reason,
...params.unavailable.providerFailure ? { providerFailures: [params.unavailable.providerFailure] } : {}
};
}
function attachWebProviderFailures(unavailableProviders, providerFailuresByRefKey) {
for (const unavailable of unavailableProviders) unavailable.providerFailure = providerFailuresByRefKey.get(unavailable.refKey);
}
function collectUnavailableWebProviders(params) {
for (const unavailable of params.result.unavailableProviders) {
let degradationState = classifySecretOwnerDegradationState({
ownerKind: "capability",
ownerId: runtimeWebSecretOwnerId(params.kind, unavailable.providerId),
refs: [unavailable.ref],
config: params.sourceConfig,
contractDigest: unavailable.contractDigest,
forceColdRefKeys: params.forceColdRefKeys
});
if (degradationState === "stale") {
const active = getActiveSecretsRuntimeSnapshotState();
const value = (active?.secretOwners?.find((entry) => entry.ownerKind === "capability" && entry.ownerId === runtimeWebSecretOwnerId(params.kind, unavailable.providerId)))?.resolvedValues?.find((entry) => entry.refKey === unavailable.refKey)?.value;
try {
if (typeof value !== "string" || !unavailable.restoreResolvedValue) throw new Error("last-known-good web credential is unavailable");
unavailable.restoreResolvedValue(value);
unavailable.resolvedValue = value;
const selectedOwner = params.result.secretOwners.find((entry) => entry.providerId === unavailable.providerId && entry.refKey === unavailable.refKey);
if (selectedOwner) selectedOwner.resolvedValue = value;
const activeMetadata = params.kind === "search" ? active?.webTools.search : active?.webTools.fetch;
if (!activeMetadata) throw new Error("last-known-good web metadata is unavailable");
for (const key of Object.keys(params.metadata)) delete params.metadata[key];
Object.assign(params.metadata, structuredClone(activeMetadata));
} catch {
degradationState = "cold";
}
}
const owner = createUnavailableWebProviderOwner({
kind: params.kind,
unavailable,
degradationState
});
params.degradedOwners.push(owner);
warnDegradedSecretOwner(params.context, owner);
}
}
function toWebSecretOwnerRefState(kind, owner) {
return {
ownerKind: "capability",
ownerId: runtimeWebSecretOwnerId(kind, owner.providerId),
refKeys: [owner.refKey],
contractDigest: owner.contractDigest,
...owner.resolvedValue ? { resolvedValues: [{
refKey: owner.refKey,
value: owner.resolvedValue
}] } : {}
};
}
function associateWebProviderResolutionError(params) {
const failureByRefKey = new Map(params.unavailableProviders.map((unavailable) => [unavailable.refKey, unavailable]));
const owners = params.unavailableProviders.map((unavailable) => {
const owner = createUnavailableWebProviderOwner({
kind: params.kind,
unavailable
});
return {
...owner,
degradationState: classifySecretOwnerDegradationState({
ownerKind: owner.ownerKind,
ownerId: owner.ownerId,
refs: [unavailable.ref],
config: params.config,
contractDigest: unavailable.contractDigest,
forceColdRefKeys: params.forceColdRefKeys
}),
failureMatched: true,
source: "config"
};
});
const ownerIds = new Set(owners.map((owner) => owner.ownerId));
const activeCoOwners = (getActiveSecretsRuntimeSnapshotState()?.secretOwners ?? []).flatMap((owner) => {
if (owner.ownerKind !== "capability" || ownerIds.has(owner.ownerId) || !owner.ownerId.startsWith("web-search:") && !owner.ownerId.startsWith("web-fetch:")) return [];
const matches = owner.refKeys.flatMap((refKey) => {
const unavailable = failureByRefKey.get(refKey);
return unavailable ? [unavailable] : [];
});
const firstMatch = matches[0];
if (!firstMatch) return [];
return [{
ownerKind: owner.ownerKind,
ownerId: owner.ownerId,
state: "unavailable",
paths: [],
refKeys: [...owner.refKeys],
reason: firstMatch.reason,
degradationState: classifySecretOwnerDegradationState({
ownerKind: owner.ownerKind,
ownerId: owner.ownerId,
refs: matches.map((match) => match.ref),
config: params.config,
contractDigest: owner.contractDigest,
forceColdRefKeys: params.forceColdRefKeys
}),
failureMatched: true,
source: "config",
...firstMatch.providerFailure ? { providerFailures: [firstMatch.providerFailure] } : {}
}];
});
associateSecretResolutionErrorOwners(params.error, [...owners, ...activeCoOwners]);
}
function needsRuntimeWebFetchProviderDiscovery(params) {
if (isRecord(params.fetch) && params.fetch.enabled === false) return false;
if (params.hasPluginWebFetchConfig) return true;
if (!isRecord(params.fetch)) return false;
if (params.rawProvider) return true;
return hasCredentialBearingObjectValue(params.fetch, params.defaults);
}
function hasPluginScopedWebToolConfig(config, key) {
const entries = config.plugins?.entries;
if (!entries) return false;
return Object.values(entries).some((entry) => {
if (!isRecord(entry)) return false;
const pluginConfig = isRecord(entry.config) ? entry.config : void 0;
return Boolean(pluginConfig?.[key]);
});
}
function inferSingleBundledPluginScopedWebToolConfigOwner(config, key) {
const entries = config.plugins?.entries;
if (!entries) return;
const matches = [];
for (const [pluginId, entry] of Object.entries(entries)) {
if (!isRecord(entry) || entry.enabled === false) continue;
const pluginConfig = isRecord(entry.config) ? entry.config : void 0;
if (!isRecord(pluginConfig?.[key])) continue;
matches.push(pluginId);
if (matches.length > 1) return;
}
return matches[0];
}
function inferExactBundledPluginScopedWebToolConfigOwner(params) {
const entry = params.config.plugins?.entries?.[params.pluginId];
if (!isRecord(entry) || entry.enabled === false) return;
const pluginConfig = isRecord(entry.config) ? entry.config : void 0;
return isRecord(pluginConfig?.[params.key]) ? params.pluginId : void 0;
}
async function hasCustomWebProviderPluginRisk(params) {
const installRecords = loadInstalledPluginIndexInstallRecordsSync({ env: params.env });
if (Object.keys(installRecords).length > 0) return true;
const plugins = params.config.plugins;
if (!plugins) return false;
if (Array.isArray(plugins.load?.paths) && plugins.load.paths.length > 0) return true;
const { resolveManifestContractPluginIds } = await loadRuntimeWebToolsManifest();
const bundledPluginIds = new Set(resolveManifestContractPluginIds({
contract: params.contract,
origin: "bundled",
config: params.config,
env: params.env,
manifestRecords: params.manifestRecords
}));
const hasNonBundledPluginId = (pluginId) => !bundledPluginIds.has(pluginId.trim());
if (Array.isArray(plugins.allow) && plugins.allow.some(hasNonBundledPluginId)) return true;
if (Array.isArray(plugins.deny) && plugins.deny.some(hasNonBundledPluginId)) return true;
if (plugins.entries && Object.keys(plugins.entries).some(hasNonBundledPluginId)) return true;
return false;
}
function readNonEmptyEnvValue(env, names) {
for (const envVar of names) {
const value = normalizeSecretInput(env[envVar]);
if (value) return {
value,
envVar
};
}
return {};
}
async function resolveSecretInputWithEnvFallback(params) {
const { ref } = resolveSecretInputRef({
value: params.value,
defaults: params.defaults
});
if (!ref) {
const configValue = normalizeSecretInput(params.value);
if (configValue) return {
value: configValue,
source: "config",
secretRefConfigured: false
};
const fallback = readNonEmptyEnvValue(params.context.env, params.envVars);
if (fallback.value) return {
value: fallback.value,
source: "env",
fallbackEnvVar: fallback.envVar,
secretRefConfigured: false
};
return {
source: "missing",
secretRefConfigured: false
};
}
let resolvedFromRef;
let unresolvedRefReason;
if (params.restrictEnvRefsToEnvVars === true && ref.source === "env" && !params.envVars.includes(ref.id)) throw new Error(`${params.path} SecretRef is not allowed for this provider.`);
else try {
const resolvedValue = (await resolveSecretRefValues([ref], {
config: params.sourceConfig,
env: params.context.env,
cache: params.context.cache,
manifestRegistry: params.context.manifestRegistry
})).get(secretRefKey(ref));
if (!isExpectedResolvedSecretValue(resolvedValue, "string")) {
const error = /* @__PURE__ */ new Error(`${params.path} resolved to a non-string or empty value.`);
associateWebProviderResolutionError({
kind: params.kind,
config: params.sourceConfig,
error,
forceColdRefKeys: params.forceColdRefKeys,
unavailableProviders: [{
providerId: params.providerId,
path: params.path,
ref,
refKey: secretRefKey(ref),
reason: "resolved secret value was invalid",
contractDigest: params.contractDigest
}]
});
throw error;
}
resolvedFromRef = normalizeSecretInput(resolvedValue);
} catch (error) {
const reason = describeSecretResolutionError(error);
if (!reason || !isRetryableSecretDegradationReason(reason)) {
if (reason) associateWebProviderResolutionError({
kind: params.kind,
config: params.sourceConfig,
error,
forceColdRefKeys: params.forceColdRefKeys,
unavailableProviders: [{
providerId: params.providerId,
path: params.path,
ref,
refKey: secretRefKey(ref),
reason,
contractDigest: params.contractDigest
}]
});
throw error;
}
unresolvedRefReason = reason;
if (isProviderScopedSecretResolutionError(error)) params.providerFailuresByRefKey.set(secretRefKey(ref), {
source: error.source,
provider: error.provider
});
}
if (resolvedFromRef) return {
value: resolvedFromRef,
source: "secretRef",
secretRefConfigured: true,
secretRef: ref,
secretRefKey: secretRefKey(ref)
};
return {
source: "missing",
secretRef: ref,
secretRefKey: secretRefKey(ref),
unresolvedRefReason,
secretRefConfigured: true
};
}
function setResolvedWebSearchApiKey(params) {
if (params.provider.setConfiguredCredentialValue) {
params.provider.setConfiguredCredentialValue(params.resolvedConfig, params.value);
return;
}
const search = ensureConfigObject(ensureConfigObject(ensureConfigObject(params.resolvedConfig, "tools"), "web"), "search");
params.provider.setCredentialValue(search, params.value);
}
async function resolveBundledWebSearchProviders(params) {
const env = {
...process.env,
...params.context.env
};
const onlyPluginIds = params.configuredBundledPluginId !== void 0 ? [params.configuredBundledPluginId] : params.onlyPluginIds && params.onlyPluginIds.length > 0 ? sortUniqueStrings(params.onlyPluginIds) : void 0;
if (onlyPluginIds && onlyPluginIds.length > 0) {
const bundled = resolveBundledExplicitWebSearchProvidersFromPublicArtifacts({ onlyPluginIds });
if (bundled && bundled.length > 0) return bundled;
const { resolvePluginWebSearchProviders } = await loadRuntimeWebToolsFallbackProviders();
return resolvePluginWebSearchProviders({
config: params.sourceConfig,
env,
onlyPluginIds,
origin: "bundled",
manifestRecords: params.context.manifestRegistry?.plugins
});
}
if (!params.hasCustomWebSearchPluginRisk) {
const { resolveBundledWebSearchProvidersFromPublicArtifacts } = await loadRuntimeWebToolsPublicArtifacts();
const bundled = resolveBundledWebSearchProvidersFromPublicArtifacts({
config: params.sourceConfig,
env,
manifestRecords: params.context.manifestRegistry?.plugins
});
if (bundled && bundled.length > 0) return bundled;
const { resolvePluginWebSearchProviders } = await loadRuntimeWebToolsFallbackProviders();
return resolvePluginWebSearchProviders({
config: params.sourceConfig,
env,
origin: "bundled",
manifestRecords: params.context.manifestRegistry?.plugins
});
}
const { resolvePluginWebSearchProviders } = await loadRuntimeWebToolsFallbackProviders();
return resolvePluginWebSearchProviders({
config: params.sourceConfig,
env,
manifestRecords: params.context.manifestRegistry?.plugins
});
}
async function resolveBundledWebFetchProviders(params) {
const env = {
...process.env,
...params.context.env
};
if (params.configuredBundledPluginId) {
const bundled = resolveBundledExplicitWebFetchProvidersFromPublicArtifacts({ onlyPluginIds: [params.configuredBundledPluginId] });
if (bundled && bundled.length > 0) return bundled;
const { resolvePluginWebFetchProviders } = await loadRuntimeWebToolsFallbackProviders();
return resolvePluginWebFetchProviders({
config: params.sourceConfig,
env,
onlyPluginIds: [params.configuredBundledPluginId],
origin: "bundled",
manifestRecords: params.context.manifestRegistry?.plugins
});
}
if (!params.hasCustomWebFetchPluginRisk) {
const { resolveBundledWebFetchProvidersFromPublicArtifacts } = await loadRuntimeWebToolsPublicArtifacts();
const bundled = resolveBundledWebFetchProvidersFromPublicArtifacts({
config: params.sourceConfig,
env,
manifestRecords: params.context.manifestRegistry?.plugins
});
if (bundled && bundled.length > 0) return bundled;
const { resolvePluginWebFetchProviders } = await loadRuntimeWebToolsFallbackProviders();
return resolvePluginWebFetchProviders({
config: params.sourceConfig,
env,
origin: "bundled",
manifestRecords: params.context.manifestRegistry?.plugins
});
}
const { resolvePluginWebFetchProviders } = await loadRuntimeWebToolsFallbackProviders();
return resolvePluginWebFetchProviders({
config: params.sourceConfig,
env,
sandboxed: true,
manifestRecords: params.context.manifestRegistry?.plugins
});
}
function readConfiguredProviderCredential(params) {
return params.provider.getConfiguredCredentialValue?.(params.config) ?? params.provider.getCredentialValue(params.search);
}
function readConfiguredProviderCredentialFallback(params) {
return params.provider.getConfiguredCredentialFallback?.(params.config);
}
function inactivePathsForProvider(provider) {
if (provider.requiresCredential === false) return [];
return provider.inactiveSecretPaths?.length ? provider.inactiveSecretPaths : [provider.credentialPath];
}
function setResolvedWebFetchApiKey(params) {
if (params.provider.setConfiguredCredentialValue) {
params.provider.setConfiguredCredentialValue(params.resolvedConfig, params.value);
return;
}
const fetch = ensureConfigObject(ensureConfigObject(ensureConfigObject(params.resolvedConfig, "tools"), "web"), "fetch");
params.provider.setCredentialValue(fetch, params.value);
}
function readConfiguredFetchProviderCredential(params) {
return params.provider.getConfiguredCredentialValue?.(params.config) ?? params.provider.getCredentialValue(params.fetch);
}
function readConfiguredFetchProviderCredentialFallback(params) {
return params.provider.getConfiguredCredentialFallback?.(params.config);
}
function inactivePathsForFetchProvider(provider) {
return provider.inactiveSecretPaths?.length ? provider.inactiveSecretPaths : provider.credentialPath ? [provider.credentialPath] : [];
}
/**
* Resolves runtime web search/fetch provider metadata and writes selected credentials into a
* cloned runtime config without mutating the source config.
*/
/** Resolves web search/fetch secret metadata from config, plugins, and fallback runtime providers. */
async function resolveRuntimeWebTools(params) {
const defaults = params.sourceConfig.secrets?.defaults;
const diagnostics = [];
const degradedOwners = [];
const secretOwners = [];
const providerFailuresByRefKey = /* @__PURE__ */ new Map();
const finish = (metadata) => ({
metadata,
degradedOwners,
secretOwners
});
const env = {
...process.env,
...params.context.env
};
const sourceTools = isRecord(params.sourceConfig.tools) ? params.sourceConfig.tools : void 0;
const sourceWeb = isRecord(sourceTools?.web) ? sourceTools.web : void 0;
let hasCustomWebSearchRisk;
const getHasCustomWebSearchRisk = () => {
hasCustomWebSearchRisk ??= hasCustomWebProviderPluginRisk({
contract: "webSearchProviders",
config: params.sourceConfig,
env,
manifestRecords: params.context.manifestRegistry?.plugins
});
return hasCustomWebSearchRisk;
};
let hasCustomWebFetchRisk;
const getHasCustomWebFetchRisk = () => {
hasCustomWebFetchRisk ??= hasCustomWebProviderPluginRisk({
contract: "webFetchProviders",
config: params.sourceConfig,
env,
manifestRecords: params.context.manifestRegistry?.plugins
});
return hasCustomWebFetchRisk;
};
const hasPluginWebSearchConfig = hasPluginScopedWebToolConfig(params.sourceConfig, "webSearch");
const hasPluginWebFetchConfig = hasPluginScopedWebToolConfig(params.sourceConfig, "webFetch");
if (!sourceWeb && !hasPluginWebSearchConfig && !hasPluginWebFetchConfig) return finish({
search: {
providerSource: "none",
diagnostics: []
},
fetch: {
providerSource: "none",
diagnostics: []
},
diagnostics
});
const search = isRecord(sourceWeb?.search) ? sourceWeb.search : void 0;
const fetch = isRecord(sourceWeb?.fetch) ? sourceWeb.fetch : void 0;
if (!search && !fetch && !hasPluginWebSearchConfig && !hasPluginWebFetchConfig) return finish({
search: {
providerSource: "none",
diagnostics: []
},
fetch: {
providerSource: "none",
diagnostics: []
},
diagnostics
});
const rawProvider = normalizeLowercaseStringOrEmpty(search?.provider);
let configuredBundledWebSearchPluginIdHint;
if (hasPluginWebSearchConfig && !await getHasCustomWebSearchRisk()) {
if (rawProvider) configuredBundledWebSearchPluginIdHint = inferExactBundledPluginScopedWebToolConfigOwner({
config: params.sourceConfig,
key: "webSearch",
pluginId: rawProvider
});
configuredBundledWebSearchPluginIdHint ??= inferSingleBundledPluginScopedWebToolConfigOwner(params.sourceConfig, "webSearch");
}
const searchMetadata = {
providerSource: "none",
diagnostics: []
};
if (search || hasPluginWebSearchConfig) {
const searchSurface = await resolveRuntimeWebProviderSurface({
contract: "webSearchProviders",
rawProvider,
providerPath: "tools.web.search.provider",
toolConfig: search,
diagnostics,
metadataDiagnostics: searchMetadata.diagnostics,
invalidAutoDetectCode: "WEB_SEARCH_PROVIDER_INVALID_AUTODETECT",
sourceConfig: params.sourceConfig,
context: params.context,
configuredBundledPluginIdHint: configuredBundledWebSearchPluginIdHint,
resolveProviders: async ({ configuredBundledPluginId }) => resolveBundledWebSearchProviders({
sourceConfig: params.sourceConfig,
context: params.context,
configuredBundledPluginId,
hasCustomWebSearchPluginRisk: await getHasCustomWebSearchRisk()
}),
sortProviders: sortPluginEntriesForAutoDetect,
readConfiguredCredential: ({ provider, config, toolConfig }) => readConfiguredProviderCredential({
provider,
config,
search: toolConfig
}),
readConfiguredCredentialFallback: ({ provider, config, toolConfig }) => readConfiguredProviderCredentialFallback({
provider,
config,
search: toolConfig
}),
ignoreKeylessProvidersForConfiguredSurface: true,
emptyProvidersWhenSurfaceMissing: true,
normalizeConfiguredProviderAgainstActiveProviders: true
});
const searchSelection = await resolveRuntimeWebProviderSelection({
scopePath: "tools.web.search",
toolConfig: search,
enabled: searchSurface.enabled,
providers: searchSurface.providers,
configuredProvider: searchSurface.configuredProvider,
metadata: searchMetadata,
diagnostics,
sourceConfig: params.sourceConfig,
resolvedConfig: params.resolvedConfig,
context: params.context,
defaults,
allowKeylessAutoSelect: false,
deferKeylessFallback: true,
allowUnavailableProviders: params.allowUnavailableSecretOwners,
onUnavailableProviders: (error) => {
attachWebProviderFailures(error.unavailableProviders, providerFailuresByRefKey);
associateWebProviderResolutionError({
kind: "search",
config: params.sourceConfig,
error,
forceColdRefKeys: params.forceColdRefKeys,
unavailableProviders: error.unavailableProviders
});
},
noFallbackCode: "WEB_SEARCH_KEY_UNRESOLVED_NO_FALLBACK",
autoDetectSelectedCode: "WEB_SEARCH_AUTODETECT_SELECTED",
readConfiguredCredential: ({ provider, config, toolConfig }) => readConfiguredProviderCredential({
provider,
config,
search: toolConfig
}),
readConfiguredCredentialFallback: ({ provider, config, toolConfig }) => readConfiguredProviderCredentialFallback({
provider,
config,
search: toolConfig
}),
resolveSecretInput: ({ providerId, value, path, envVars, contractDigest }) => resolveSecretInputWithEnvFallback({
kind: "search",
providerId,
sourceConfig: params.sourceConfig,
context: params.context,
defaults,
value,
path,
envVars,
contractDigest,
providerFailuresByRefKey,
forceColdRefKeys: params.forceColdRefKeys
}),
setResolvedCredential: ({ resolvedConfig, provider, value }) => setResolvedWebSearchApiKey({
resolvedConfig,
provider,
value
}),
inactivePathsForProvider,
hasConfiguredSecretRef,
mergeRuntimeMetadata: async ({ provider, metadata, toolConfig, selectedResolution }) => {
if (!provider.resolveRuntimeMetadata) return;
Object.assign(metadata, await provider.resolveRuntimeMetadata({
config: params.sourceConfig,
searchConfig: toolConfig,
runtimeMetadata: metadata,
resolvedCredential: selectedResolution ? {
value: selectedResolution.value,
source: selectedResolution.source,
fallbackEnvVar: selectedResolution.fallbackEnvVar
} : void 0
}));
}
});
attachWebProviderFailures(searchSelection.unavailableProviders, providerFailuresByRefKey);
collectUnavailableWebProviders({
kind: "search",
result: searchSelection,
context: params.context,
sourceConfig: params.sourceConfig,
metadata: searchMetadata,
degradedOwners,
forceColdRefKeys: params.forceColdRefKeys
});
for (const owner of searchSelection.secretOwners) secretOwners.push(toWebSecretOwnerRefState("search", owner));
}
const rawFetchProvider = normalizeLowercaseStringOrEmpty(fetch?.provider);
const fetchMetadata = {
providerSource: "none",
diagnostics: []
};
if (needsRuntimeWebFetchProviderDiscovery({
fetch,
rawProvider: rawFetchProvider,
hasPluginWebFetchConfig,
defaults
})) {
const fetchSurface = await resolveRuntimeWebProviderSurface({
contract: "webFetchProviders",
rawProvider: rawFetchProvider,
providerPath: "tools.web.fetch.provider",
toolConfig: fetch,
diagnostics,
metadataDiagnostics: fetchMetadata.diagnostics,
invalidAutoDetectCode: "WEB_FETCH_PROVIDER_INVALID_AUTODETECT",
sourceConfig: params.sourceConfig,
context: params.context,
resolveProviders: async ({ configuredBundledPluginId }) => resolveBundledWebFetchProviders({
sourceConfig: params.sourceConfig,
context: params.context,
configuredBundledPluginId,
hasCustomWebFetchPluginRisk: await getHasCustomWebFetchRisk()
}),
sortProviders: sortPluginEntriesForAutoDetect,
readConfiguredCredential: ({ provider, config, toolConfig }) => readConfiguredFetchProviderCredential({
provider,
config,
fetch: toolConfig
}),
readConfiguredCredentialFallback: ({ provider, config, toolConfig }) => readConfiguredFetchProviderCredentialFallback({
provider,
config,
fetch: toolConfig
})
});
const fetchSelection = await resolveRuntimeWebProviderSelection({
scopePath: "tools.web.fetch",
toolConfig: fetch,
enabled: fetchSurface.enabled,
providers: fetchSurface.providers,
configuredProvider: fetchSurface.configuredProvider,
metadata: fetchMetadata,
diagnostics,
sourceConfig: params.sourceConfig,
resolvedConfig: params.resolvedConfig,
context: params.context,
defaults,
allowKeylessAutoSelect: true,
deferKeylessFallback: false,
allowUnavailableProviders: params.allowUnavailableSecretOwners,
onUnavailableProviders: (error) => {
attachWebProviderFailures(error.unavailableProviders, providerFailuresByRefKey);
associateWebProviderResolutionError({
kind: "fetch",
config: params.sourceConfig,
error,
forceColdRefKeys: params.forceColdRefKeys,
unavailableProviders: error.unavailableProviders
});
},
noFallbackCode: "WEB_FETCH_PROVIDER_KEY_UNRESOLVED_NO_FALLBACK",
autoDetectSelectedCode: "WEB_FETCH_AUTODETECT_SELECTED",
readConfiguredCredential: ({ provider, config, toolConfig }) => readConfiguredFetchProviderCredential({
provider,
config,
fetch: toolConfig
}),
readConfiguredCredentialFallback: ({ provider, config, toolConfig }) => readConfiguredFetchProviderCredentialFallback({
provider,
config,
fetch: toolConfig
}),
resolveSecretInput: ({ providerId, value, path, envVars, contractDigest }) => resolveSecretInputWithEnvFallback({
kind: "fetch",
providerId,
sourceConfig: params.sourceConfig,
context: params.context,
defaults,
value,
path,
envVars,
contractDigest,
providerFailuresByRefKey,
restrictEnvRefsToEnvVars: true,
forceColdRefKeys: params.forceColdRefKeys
}),
setResolvedCredential: ({ resolvedConfig, provider, value }) => setResolvedWebFetchApiKey({
resolvedConfig,
provider,
value
}),
inactivePathsForProvider: inactivePathsForFetchProvider,
hasConfiguredSecretRef,
mergeRuntimeMetadata: async ({ provider, metadata, toolConfig, selectedResolution }) => {
if (!provider.resolveRuntimeMetadata) return;
Object.assign(metadata, await provider.resolveRuntimeMetadata({
config: params.sourceConfig,
fetchConfig: toolConfig,
runtimeMetadata: metadata,
resolvedCredential: selectedResolution ? {
value: selectedResolution.value,
source: selectedResolution.source,
fallbackEnvVar: selectedResolution.fallbackEnvVar
} : void 0
}));
}
});
attachWebProviderFailures(fetchSelection.unavailableProviders, providerFailuresByRefKey);
collectUnavailableWebProviders({
kind: "fetch",
result: fetchSelection,
context: params.context,
sourceConfig: params.sourceConfig,
metadata: fetchMetadata,
degradedOwners,
forceColdRefKeys: params.forceColdRefKeys
});
for (const owner of fetchSelection.secretOwners) secretOwners.push(toWebSecretOwnerRefState("fetch", owner));
}
return finish({
search: searchMetadata,
fetch: fetchMetadata,
diagnostics
});
}
//#endregion
export { runtimeWebSecretOwnerId as n, resolveRuntimeWebTools as t };