openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
547 lines (546 loc) • 20.2 kB
JavaScript
import { s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js";
import { c as isRecord } from "./utils-CCC-BEJH.js";
import "./shared-CuqTS6Vs.js";
import { n as collectSecretInputAssignment } from "./runtime-shared-DR5938Io.js";
import { t as collectPluginConfigAssignments } from "./runtime-config-collectors-plugins-j14FBueI.js";
import { t as loadChannelSecretContractApi } from "./channel-contract-api-CieuqXr4.js";
import { n as getBootstrapChannelSecrets } from "./bootstrap-registry-DdZI5Mh6.js";
import { r as resolvePluginCapabilityProviders } from "./capability-provider-runtime-kNmuYvcj.js";
import { n as normalizeMediaProviderId } from "./provider-id-DSbuCFIb.js";
import { t as resolveImageCapableConfigProviderIds } from "./config-provider-models-C4gvrjuU.js";
import { n as resolveConfiguredMediaEntryCapabilities, r as resolveEffectiveMediaEntryCapabilities } from "./entry-capabilities-BK3bTOCE.js";
import { t as collectTtsApiKeyAssignments } from "./runtime-config-collectors-tts-DPQmNqck.js";
import { n as evaluateGatewayAuthSurfaceStates } from "./runtime-gateway-auth-surfaces-B6IqufiU.js";
//#region src/secrets/runtime-config-collectors-channels.ts
/** Collects channel contract secret assignments during runtime preparation. */
/** Collects SecretRef assignments declared by active channel/plugin channel contracts. */
function collectChannelConfigAssignments(params) {
const channelIds = Object.keys(params.config.channels ?? {});
if (channelIds.length === 0) return;
for (const channelId of channelIds) (loadChannelSecretContractApi({
channelId,
config: params.config,
env: params.context.env,
loadablePluginOrigins: params.loadablePluginOrigins
})?.collectRuntimeConfigAssignments ?? getBootstrapChannelSecrets(channelId)?.collectRuntimeConfigAssignments)?.(params);
}
//#endregion
//#region src/media-understanding/provider-capability-registry.ts
function mergeProviderCapabilities(registry, provider) {
const normalizedKey = normalizeMediaProviderId(provider.id);
const existing = registry.get(normalizedKey);
registry.set(normalizedKey, { capabilities: provider.capabilities ?? existing?.capabilities });
}
/** Builds provider capability metadata used to filter shared media model entries. */
function buildMediaUnderstandingCapabilityRegistry(cfg) {
const registry = /* @__PURE__ */ new Map();
for (const provider of resolvePluginCapabilityProviders({
key: "mediaUnderstandingProviders",
cfg
})) mergeProviderCapabilities(registry, provider);
for (const normalizedKey of resolveImageCapableConfigProviderIds(cfg)) if (!registry.has(normalizedKey)) mergeProviderCapabilities(registry, {
id: normalizedKey,
capabilities: ["image"]
});
return registry;
}
//#endregion
//#region src/secrets/runtime-config-collectors-core.ts
/** Collects core config secret refs during runtime preparation. */
function collectModelProviderAssignments(params) {
for (const [providerId, provider] of Object.entries(params.providers)) {
const providerIsActive = provider.enabled !== false;
collectSecretInputAssignment({
value: provider.apiKey,
path: `models.providers.${providerId}.apiKey`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: providerIsActive,
inactiveReason: "provider is disabled.",
apply: (value) => {
provider.apiKey = value;
}
});
const headers = isRecord(provider.headers) ? provider.headers : void 0;
if (headers) for (const [headerKey, headerValue] of Object.entries(headers)) collectSecretInputAssignment({
value: headerValue,
path: `models.providers.${providerId}.headers.${headerKey}`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: providerIsActive,
inactiveReason: "provider is disabled.",
apply: (value) => {
headers[headerKey] = value;
}
});
const request = isRecord(provider.request) ? provider.request : void 0;
if (request) collectProviderRequestAssignments({
request,
pathPrefix: `models.providers.${providerId}.request`,
defaults: params.defaults,
context: params.context,
active: providerIsActive,
inactiveReason: "provider is disabled.",
collectTransportSecrets: true
});
}
}
function collectSkillAssignments(params) {
for (const [skillKey, entry] of Object.entries(params.entries)) collectSecretInputAssignment({
value: entry.apiKey,
path: `skills.entries.${skillKey}.apiKey`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: entry.enabled !== false,
inactiveReason: "skill entry is disabled.",
apply: (value) => {
entry.apiKey = value;
}
});
}
function collectAgentMemorySearchAssignments(params) {
const agents = params.config.agents;
if (!isRecord(agents)) return;
const defaultsConfig = isRecord(agents.defaults) ? agents.defaults : void 0;
const defaultsMemorySearch = isRecord(defaultsConfig?.memorySearch) ? defaultsConfig.memorySearch : void 0;
const defaultsEnabled = defaultsMemorySearch?.enabled !== false;
const list = Array.isArray(agents.list) ? agents.list : [];
let hasEnabledAgentWithoutOverride = false;
for (const rawAgent of list) {
if (!isRecord(rawAgent)) continue;
if (rawAgent.enabled === false) continue;
const memorySearch = isRecord(rawAgent.memorySearch) ? rawAgent.memorySearch : void 0;
if (memorySearch?.enabled === false) continue;
if (!memorySearch || !Object.hasOwn(memorySearch, "remote")) {
hasEnabledAgentWithoutOverride = true;
continue;
}
const remote = isRecord(memorySearch.remote) ? memorySearch.remote : void 0;
if (!remote || !Object.hasOwn(remote, "apiKey")) {
hasEnabledAgentWithoutOverride = true;
continue;
}
}
if (defaultsMemorySearch && isRecord(defaultsMemorySearch.remote)) {
const remote = defaultsMemorySearch.remote;
collectSecretInputAssignment({
value: remote.apiKey,
path: "agents.defaults.memorySearch.remote.apiKey",
expected: "string",
defaults: params.defaults,
context: params.context,
active: defaultsEnabled && (hasEnabledAgentWithoutOverride || list.length === 0),
inactiveReason: hasEnabledAgentWithoutOverride ? void 0 : "all enabled agents override memorySearch.remote.apiKey.",
apply: (value) => {
remote.apiKey = value;
}
});
}
list.forEach((rawAgent, index) => {
if (!isRecord(rawAgent)) return;
const memorySearch = isRecord(rawAgent.memorySearch) ? rawAgent.memorySearch : void 0;
if (!memorySearch) return;
const remote = isRecord(memorySearch.remote) ? memorySearch.remote : void 0;
if (!remote || !Object.hasOwn(remote, "apiKey")) return;
const enabled = rawAgent.enabled !== false && memorySearch.enabled !== false;
collectSecretInputAssignment({
value: remote.apiKey,
path: `agents.list.${index}.memorySearch.remote.apiKey`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: enabled,
inactiveReason: "agent or memorySearch override is disabled.",
apply: (value) => {
remote.apiKey = value;
}
});
});
}
function collectTalkAssignments(params) {
const talk = params.config.talk;
if (!isRecord(talk)) return;
collectSecretInputAssignment({
value: talk.apiKey,
path: "talk.apiKey",
expected: "string",
defaults: params.defaults,
context: params.context,
apply: (value) => {
talk.apiKey = value;
}
});
collectTalkProviderApiKeyAssignments({
providers: talk.providers,
pathPrefix: "talk.providers",
defaults: params.defaults,
context: params.context
});
collectTalkProviderApiKeyAssignments({
providers: (isRecord(talk.realtime) ? talk.realtime : void 0)?.providers,
pathPrefix: "talk.realtime.providers",
defaults: params.defaults,
context: params.context
});
}
function collectTalkProviderApiKeyAssignments(params) {
if (!isRecord(params.providers)) return;
for (const [providerId, providerConfig] of Object.entries(params.providers)) {
if (!isRecord(providerConfig)) continue;
collectSecretInputAssignment({
value: providerConfig.apiKey,
path: `${params.pathPrefix}.${providerId}.apiKey`,
expected: "string",
defaults: params.defaults,
context: params.context,
apply: (value) => {
providerConfig.apiKey = value;
}
});
}
}
function collectGatewayAssignments(params) {
const gateway = params.config.gateway;
if (!isRecord(gateway)) return;
const auth = isRecord(gateway.auth) ? gateway.auth : void 0;
const remote = isRecord(gateway.remote) ? gateway.remote : void 0;
const gatewaySurfaceStates = evaluateGatewayAuthSurfaceStates({
config: params.config,
env: params.context.env,
defaults: params.defaults
});
if (auth) {
collectSecretInputAssignment({
value: auth.token,
path: "gateway.auth.token",
expected: "string",
defaults: params.defaults,
context: params.context,
active: gatewaySurfaceStates["gateway.auth.token"].active,
inactiveReason: gatewaySurfaceStates["gateway.auth.token"].reason,
apply: (value) => {
auth.token = value;
}
});
collectSecretInputAssignment({
value: auth.password,
path: "gateway.auth.password",
expected: "string",
defaults: params.defaults,
context: params.context,
active: gatewaySurfaceStates["gateway.auth.password"].active,
inactiveReason: gatewaySurfaceStates["gateway.auth.password"].reason,
apply: (value) => {
auth.password = value;
}
});
}
if (remote) {
collectSecretInputAssignment({
value: remote.token,
path: "gateway.remote.token",
expected: "string",
defaults: params.defaults,
context: params.context,
active: gatewaySurfaceStates["gateway.remote.token"].active,
inactiveReason: gatewaySurfaceStates["gateway.remote.token"].reason,
apply: (value) => {
remote.token = value;
}
});
collectSecretInputAssignment({
value: remote.password,
path: "gateway.remote.password",
expected: "string",
defaults: params.defaults,
context: params.context,
active: gatewaySurfaceStates["gateway.remote.password"].active,
inactiveReason: gatewaySurfaceStates["gateway.remote.password"].reason,
apply: (value) => {
remote.password = value;
}
});
}
}
function collectProviderRequestAssignments(params) {
const headers = isRecord(params.request.headers) ? params.request.headers : void 0;
if (headers) for (const [headerKey, headerValue] of Object.entries(headers)) collectSecretInputAssignment({
value: headerValue,
path: `${params.pathPrefix}.headers.${headerKey}`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: params.active,
inactiveReason: params.inactiveReason,
apply: (value) => {
headers[headerKey] = value;
}
});
const auth = isRecord(params.request.auth) ? params.request.auth : void 0;
if (auth) {
collectSecretInputAssignment({
value: auth.token,
path: `${params.pathPrefix}.auth.token`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: params.active,
inactiveReason: params.inactiveReason,
apply: (value) => {
auth.token = value;
}
});
collectSecretInputAssignment({
value: auth.value,
path: `${params.pathPrefix}.auth.value`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: params.active,
inactiveReason: params.inactiveReason,
apply: (value) => {
auth.value = value;
}
});
}
const collectTlsAssignments = (tls, pathPrefix) => {
if (!tls) return;
for (const key of [
"ca",
"cert",
"key",
"passphrase"
]) collectSecretInputAssignment({
value: tls[key],
path: `${pathPrefix}.${key}`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: params.active,
inactiveReason: params.inactiveReason,
apply: (value) => {
tls[key] = value;
}
});
};
if (params.collectTransportSecrets !== false) {
collectTlsAssignments(isRecord(params.request.tls) ? params.request.tls : void 0, `${params.pathPrefix}.tls`);
const proxy = isRecord(params.request.proxy) ? params.request.proxy : void 0;
collectTlsAssignments(isRecord(proxy?.tls) ? proxy.tls : void 0, `${params.pathPrefix}.proxy.tls`);
}
}
function collectMediaRequestAssignments(params) {
const tools = isRecord(params.config.tools) ? params.config.tools : void 0;
const media = isRecord(tools?.media) ? tools.media : void 0;
if (!media) return;
let providerRegistry;
const getProviderRegistry = () => {
providerRegistry ??= buildMediaUnderstandingCapabilityRegistry(params.config);
return providerRegistry;
};
const capabilityKeys = [
"audio",
"image",
"video"
];
const isCapabilityEnabled = (capability) => (isRecord(media[capability]) ? media[capability] : void 0)?.enabled !== false;
const collectModelAssignments = (models, pathPrefix, resolveActivity) => {
if (!Array.isArray(models)) return;
models.forEach((rawModel, index) => {
if (!isRecord(rawModel) || !isRecord(rawModel.request)) return;
const { active, inactiveReason } = resolveActivity(rawModel);
collectProviderRequestAssignments({
request: rawModel.request,
pathPrefix: `${pathPrefix}.${index}.request`,
defaults: params.defaults,
context: params.context,
active,
inactiveReason
});
});
};
collectModelAssignments(media.models, "tools.media.models", (rawModel) => {
const entry = rawModel;
const capabilities = resolveConfiguredMediaEntryCapabilities(entry) ?? resolveEffectiveMediaEntryCapabilities({
entry,
source: "shared",
providerRegistry: getProviderRegistry()
});
if (!capabilities || capabilities.length === 0) return {
active: false,
inactiveReason: "shared media model does not declare capabilities and none could be inferred from its provider."
};
return {
active: capabilities.some((capability) => isCapabilityEnabled(capability)),
inactiveReason: `all configured media capabilities for this shared model are disabled: ${capabilities.join(", ")}.`
};
});
for (const capability of capabilityKeys) {
const section = isRecord(media[capability]) ? media[capability] : void 0;
const active = isCapabilityEnabled(capability);
const inactiveReason = `${capability} media understanding is disabled.`;
if (section && isRecord(section.request)) collectProviderRequestAssignments({
request: section.request,
pathPrefix: `tools.media.${capability}.request`,
defaults: params.defaults,
context: params.context,
active,
inactiveReason
});
collectModelAssignments(section?.models, `tools.media.${capability}.models`, (rawModel) => ({
active: active && (() => {
const configuredCapabilities = resolveConfiguredMediaEntryCapabilities(rawModel);
return configuredCapabilities ? configuredCapabilities.includes(capability) : true;
})(),
inactiveReason: active ? `${capability} media model is filtered out by its configured capabilities.` : inactiveReason
}));
}
}
function collectMessagesTtsAssignments(params) {
const messages = params.config.messages;
if (!isRecord(messages) || !isRecord(messages.tts)) return;
collectTtsApiKeyAssignments({
tts: messages.tts,
pathPrefix: "messages.tts",
defaults: params.defaults,
context: params.context
});
}
function collectAgentTtsAssignments(params) {
const list = params.config.agents?.list;
if (!Array.isArray(list)) return;
for (const [index, entry] of list.entries()) {
if (!isRecord(entry) || !isRecord(entry.tts)) continue;
collectTtsApiKeyAssignments({
tts: entry.tts,
pathPrefix: `agents.list.${index}.tts`,
defaults: params.defaults,
context: params.context
});
}
}
function collectCronAssignments(params) {
const cron = params.config.cron;
if (!isRecord(cron)) return;
collectSecretInputAssignment({
value: cron.webhookToken,
path: "cron.webhookToken",
expected: "string",
defaults: params.defaults,
context: params.context,
apply: (value) => {
cron.webhookToken = value;
}
});
}
function collectSandboxSshAssignments(params) {
const agents = isRecord(params.config.agents) ? params.config.agents : void 0;
if (!agents) return;
const defaultsAgent = isRecord(agents.defaults) ? agents.defaults : void 0;
const defaultsSandbox = isRecord(defaultsAgent?.sandbox) ? defaultsAgent.sandbox : void 0;
const defaultsSsh = isRecord(defaultsSandbox?.ssh) ? defaultsSandbox.ssh : void 0;
const defaultsBackend = typeof defaultsSandbox?.backend === "string" ? defaultsSandbox.backend : void 0;
const defaultsMode = typeof defaultsSandbox?.mode === "string" ? defaultsSandbox.mode : void 0;
const inheritedDefaultsUsage = {
identityData: false,
certificateData: false,
knownHostsData: false
};
(Array.isArray(agents.list) ? agents.list : []).forEach((rawAgent, index) => {
const agentRecord = isRecord(rawAgent) ? rawAgent : null;
if (!agentRecord || agentRecord.enabled === false) return;
const sandbox = isRecord(agentRecord.sandbox) ? agentRecord.sandbox : void 0;
const ssh = isRecord(sandbox?.ssh) ? sandbox.ssh : void 0;
const effectiveBackend = (typeof sandbox?.backend === "string" ? sandbox.backend : void 0) ?? defaultsBackend ?? "docker";
const effectiveMode = (typeof sandbox?.mode === "string" ? sandbox.mode : void 0) ?? defaultsMode ?? "off";
const active = normalizeOptionalLowercaseString(effectiveBackend) === "ssh" && effectiveMode !== "off";
for (const key of [
"identityData",
"certificateData",
"knownHostsData"
]) if (ssh && Object.hasOwn(ssh, key)) collectSecretInputAssignment({
value: ssh[key],
path: `agents.list.${index}.sandbox.ssh.${key}`,
expected: "string",
defaults: params.defaults,
context: params.context,
active,
inactiveReason: "sandbox SSH backend is not active for this agent.",
apply: (value) => {
ssh[key] = value;
}
});
else if (active) inheritedDefaultsUsage[key] = true;
});
if (!defaultsSsh) return;
const defaultsActive = normalizeOptionalLowercaseString(defaultsBackend) === "ssh" && defaultsMode !== "off" || inheritedDefaultsUsage.identityData || inheritedDefaultsUsage.certificateData || inheritedDefaultsUsage.knownHostsData;
for (const key of [
"identityData",
"certificateData",
"knownHostsData"
]) collectSecretInputAssignment({
value: defaultsSsh[key],
path: `agents.defaults.sandbox.ssh.${key}`,
expected: "string",
defaults: params.defaults,
context: params.context,
active: defaultsActive || inheritedDefaultsUsage[key],
inactiveReason: "sandbox SSH backend is not active.",
apply: (value) => {
defaultsSsh[key] = value;
}
});
}
/** Collects SecretRef assignments from core-owned config surfaces. */
/** Collects SecretRef assignments from core non-plugin config surfaces. */
function collectCoreConfigAssignments(params) {
const providers = params.config.models?.providers;
if (providers) collectModelProviderAssignments({
providers,
defaults: params.defaults,
context: params.context
});
const skillEntries = params.config.skills?.entries;
if (skillEntries) collectSkillAssignments({
entries: skillEntries,
defaults: params.defaults,
context: params.context
});
collectAgentMemorySearchAssignments(params);
collectTalkAssignments(params);
collectGatewayAssignments(params);
collectSandboxSshAssignments(params);
collectMessagesTtsAssignments(params);
collectAgentTtsAssignments(params);
collectCronAssignments(params);
collectMediaRequestAssignments(params);
}
//#endregion
//#region src/secrets/runtime-config-collectors.ts
/** Collects every config-backed SecretRef assignment before runtime values are materialized. */
/** Collects concrete config path assignments that may need SecretRef conversion. */
function collectConfigAssignments(params) {
const defaults = params.context.sourceConfig.secrets?.defaults;
collectCoreConfigAssignments({
config: params.config,
defaults,
context: params.context
});
collectChannelConfigAssignments({
config: params.config,
defaults,
context: params.context,
loadablePluginOrigins: params.loadablePluginOrigins
});
collectPluginConfigAssignments({
config: params.config,
defaults,
context: params.context,
loadablePluginOrigins: params.loadablePluginOrigins
});
}
//#endregion
export { collectConfigAssignments as t };