UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

231 lines (230 loc) 11.5 kB
import { o as normalizeNullableString } from "./string-coerce-mnp54Vah.js"; import { n as VERSION } from "./version-Crcn9X9T.js"; import { r as normalizeChatChannelId } from "./ids-BVNPk-iM.js"; import { t as getOfficialExternalPluginCatalogEntry } from "./official-external-plugin-catalog-h7dZZiYs.js"; import { a as listPotentialConfiguredChannelPresenceSignals, u as collectConfiguredModelRefs } from "./channel-env-var-names-B6Cczraa.js"; import { t as collectConfiguredAgentHarnessRuntimes } from "./harness-runtimes-B7OdBY2U.js"; import { n as resolveWebSearchInstallCatalogEntry } from "./web-search-install-catalog-C37dpKGw.js"; import { t as compareOpenClawVersions } from "./version-NKzkBmMs.js"; import { r as detectPluginAutoEnableCandidates } from "./plugin-auto-enable-pAtqig-B.js"; import { t as isChannelConfigured } from "./channel-configured-tJYqancm.js"; import "./registry-9YoS2BJP.js"; import { t as resolveProviderInstallCatalogEntries } from "./provider-install-catalog-BSmVuCKR.js"; import { c as shouldDeferConfiguredPluginInstallRepair } from "./update-phase-Br0EIrpk.js"; import { t as asObjectRecord } from "./object-BsiS9JXh.js"; import { n as repairMissingPluginInstallsForIds } from "./missing-configured-plugin-install-BMULB-0J.js"; const AGENT_HARNESS_RUNTIME_PLUGIN_IDS = { codex: "codex" }; function isPluginsGloballyDisabled(cfg) { return cfg.plugins?.enabled === false; } function isDenied(cfg, pluginId) { const deny = cfg.plugins?.deny; return Array.isArray(deny) && deny.includes(pluginId); } function collectBlockedPluginIds(cfg) { const ids = /* @__PURE__ */ new Set(); const deny = cfg.plugins?.deny; if (Array.isArray(deny)) for (const pluginId of deny) { const normalized = normalizeNullableString(pluginId); if (normalized) ids.add(normalized); } const entries = asObjectRecord(cfg.plugins?.entries); for (const [pluginId, entry] of Object.entries(entries ?? {})) if (asObjectRecord(entry)?.enabled === false && pluginId.trim()) ids.add(pluginId.trim()); return [...ids].toSorted((left, right) => left.localeCompare(right)); } function isPluginEntryDisabled(cfg, pluginId) { return cfg.plugins?.entries?.[pluginId]?.enabled === false; } function isChannelDisabled(cfg, channelId) { return asObjectRecord(asObjectRecord(cfg.channels)?.[channelId])?.enabled === false; } function isDisabled(cfg, pluginId) { if (isPluginEntryDisabled(cfg, pluginId)) return true; const channelId = normalizeChatChannelId(pluginId); return channelId ? isChannelDisabled(cfg, channelId) : false; } function hasMaterialPluginEntry(entry) { const record = asObjectRecord(entry); if (!record) return false; return record.enabled === true || asObjectRecord(record.config) !== null || asObjectRecord(record.hooks) !== null || asObjectRecord(record.subagent) !== null || record.apiKey !== void 0 || record.env !== void 0; } function collectMaterialPluginEntryIds(cfg) { const entries = asObjectRecord(cfg.plugins?.entries); if (!entries) return []; return Object.entries(entries).filter(([, entry]) => hasMaterialPluginEntry(entry)).map(([pluginId]) => pluginId.trim()).filter((pluginId) => pluginId); } function collectSlotPluginIds(cfg) { const slots = asObjectRecord(cfg.plugins?.slots); return ["memory", "contextEngine"].map((key) => normalizeNullableString(slots?.[key])).filter((pluginId) => typeof pluginId === "string" && pluginId.toLowerCase() !== "none"); } function collectConfiguredChannelIds(cfg, env) { const ids = /* @__PURE__ */ new Set(); const channels = asObjectRecord(cfg.channels); if (channels) for (const [channelId, value] of Object.entries(channels)) { if (channelId === "defaults" || channelId === "modelByChannel" || !channelId.trim()) continue; const entry = asObjectRecord(value); if (entry?.enabled === false) continue; if (entry?.enabled === true || Object.keys(entry ?? {}).some((key) => key !== "enabled")) ids.add(channelId.trim()); } for (const signal of listPotentialConfiguredChannelPresenceSignals(cfg, env, { includePersistedAuthState: false })) { const channelId = normalizeChatChannelId(signal.channelId) ?? signal.channelId; if (!isChannelDisabled(cfg, channelId) && isChannelConfigured(cfg, channelId, env)) ids.add(channelId); } return [...ids].toSorted((left, right) => left.localeCompare(right)); } function collectConfiguredProviderIds(cfg) { const ids = /* @__PURE__ */ new Set(); const add = (value) => { const id = normalizeNullableString(value); if (id) ids.add(id.toLowerCase()); }; for (const profile of Object.values(asObjectRecord(cfg.auth?.profiles) ?? {})) add(asObjectRecord(profile)?.provider); for (const providerId of Object.keys(asObjectRecord(cfg.models?.providers) ?? {})) add(providerId); const modelByChannel = asObjectRecord(cfg.channels?.modelByChannel); for (const [providerId, channelMap] of Object.entries(modelByChannel ?? {})) { add(providerId); for (const modelRef of Object.values(asObjectRecord(channelMap) ?? {})) { if (typeof modelRef !== "string") continue; const slash = modelRef.indexOf("/"); if (slash > 0) add(modelRef.slice(0, slash)); } } for (const { value } of collectConfiguredModelRefs(cfg, { includeChannelModelOverrides: false })) { const slash = value.indexOf("/"); if (slash > 0) add(value.slice(0, slash)); } return ids; } function collectProviderPluginIds(cfg, env) { const configuredProviders = collectConfiguredProviderIds(cfg); if (configuredProviders.size === 0) return []; const ids = /* @__PURE__ */ new Set(); for (const entry of resolveProviderInstallCatalogEntries({ config: cfg, env, includeUntrustedWorkspacePlugins: false })) if (configuredProviders.has(entry.providerId.toLowerCase())) ids.add(entry.pluginId); return [...ids].toSorted((left, right) => left.localeCompare(right)); } function collectAgentHarnessRuntimePluginIds(cfg, _env) { return collectConfiguredAgentHarnessRuntimes(cfg).map((runtime) => AGENT_HARNESS_RUNTIME_PLUGIN_IDS[runtime]).filter((pluginId) => Boolean(pluginId)).toSorted((left, right) => left.localeCompare(right)); } function collectWebSearchPluginIds(cfg) { const providerId = cfg.tools?.web?.search?.provider; if (typeof providerId !== "string") return []; const entry = resolveWebSearchInstallCatalogEntry({ providerId }); return entry?.pluginId ? [entry.pluginId] : []; } function collectAcpRuntimePluginIds(cfg) { const acp = asObjectRecord(cfg.acp); if (!acp) return []; const backend = normalizeNullableString(acp.backend)?.toLowerCase() ?? ""; if (!(acp.enabled === true || asObjectRecord(acp.dispatch)?.enabled === true || backend === "acpx") || backend && backend !== "acpx") return []; return ["acpx"]; } function collectAllowOnlyOfficialPluginIds(cfg) { const allow = cfg.plugins?.allow; if (!Array.isArray(allow) || allow.length === 0) return []; const materialEntryIds = new Set(collectMaterialPluginEntryIds(cfg).map((id) => id.toLowerCase())); const ids = []; for (const rawPluginId of allow) { const pluginId = normalizeNullableString(rawPluginId); if (!pluginId || materialEntryIds.has(pluginId.toLowerCase())) continue; if (getOfficialExternalPluginCatalogEntry(pluginId)) ids.push(pluginId); } return ids; } function addEligiblePluginId(cfg, pluginIds, pluginId) { const normalized = pluginId.trim(); if (!normalized || isDenied(cfg, normalized) || isDisabled(cfg, normalized)) return; pluginIds.add(normalized); } /** Return true when this config has not yet crossed the configured-plugin install release gate. */ function shouldRunConfiguredPluginInstallReleaseStep(params) { const releaseVersion = params.releaseVersion ?? "2026.5.2-beta.1"; const currentComparedToRelease = compareOpenClawVersions(params.currentVersion ?? VERSION, releaseVersion); if (currentComparedToRelease === null || currentComparedToRelease < 0) return false; const touchedComparedToRelease = compareOpenClawVersions(params.touchedVersion, releaseVersion); return touchedComparedToRelease === null || touchedComparedToRelease < 0; } /** Collect plugin/channel ids implied by config for the release install backfill step. */ function collectReleaseConfiguredPluginIds(params) { const env = params.env ?? process.env; const pluginIds = /* @__PURE__ */ new Set(); const channelIds = /* @__PURE__ */ new Set(); if (isPluginsGloballyDisabled(params.cfg)) return { pluginIds: [], channelIds: [] }; for (const candidate of detectPluginAutoEnableCandidates({ config: params.cfg, env })) addEligiblePluginId(params.cfg, pluginIds, candidate.pluginId); for (const pluginId of collectMaterialPluginEntryIds(params.cfg)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const pluginId of collectSlotPluginIds(params.cfg)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const pluginId of collectProviderPluginIds(params.cfg, env)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const pluginId of collectAgentHarnessRuntimePluginIds(params.cfg, env)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const pluginId of collectWebSearchPluginIds(params.cfg)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const pluginId of collectAcpRuntimePluginIds(params.cfg)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const pluginId of collectAllowOnlyOfficialPluginIds(params.cfg)) addEligiblePluginId(params.cfg, pluginIds, pluginId); for (const channelId of collectConfiguredChannelIds(params.cfg, env)) if (!isChannelDisabled(params.cfg, channelId) && !isDenied(params.cfg, channelId) && !isPluginEntryDisabled(params.cfg, channelId)) channelIds.add(channelId); return { pluginIds: [...pluginIds].toSorted((left, right) => left.localeCompare(right)), channelIds: [...channelIds].toSorted((left, right) => left.localeCompare(right)) }; } /** Run the configured-plugin install release backfill when the config still needs it. */ async function maybeRunConfiguredPluginInstallReleaseStep(params) { const env = params.env ?? process.env; const updateInProgress = shouldDeferConfiguredPluginInstallRepair(env); const configured = collectReleaseConfiguredPluginIds({ cfg: params.cfg, env }); if (!shouldRunConfiguredPluginInstallReleaseStep({ currentVersion: params.currentVersion, touchedVersion: params.touchedVersion })) { if (configured.pluginIds.length === 0 && configured.channelIds.length === 0) return { changes: [], warnings: [], completed: false, touchedConfig: false }; const repaired = await repairMissingPluginInstallsForIds({ cfg: params.cfg, pluginIds: configured.pluginIds, channelIds: configured.channelIds, blockedPluginIds: collectBlockedPluginIds(params.cfg), env }); return { changes: repaired.changes, warnings: repaired.warnings, completed: repaired.warnings.length === 0, touchedConfig: false }; } if (configured.pluginIds.length === 0 && configured.channelIds.length === 0) return { changes: [], warnings: [], completed: true, touchedConfig: !updateInProgress }; const repaired = await repairMissingPluginInstallsForIds({ cfg: params.cfg, pluginIds: configured.pluginIds, channelIds: configured.channelIds, blockedPluginIds: collectBlockedPluginIds(params.cfg), env }); const completed = repaired.warnings.length === 0 && !updateInProgress; return { changes: repaired.changes, warnings: repaired.warnings, completed, touchedConfig: completed }; } //#endregion export { maybeRunConfiguredPluginInstallReleaseStep };