UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

114 lines (113 loc) 4.96 kB
import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js"; import { u as normalizeAgentId } from "./session-key-B_NoIfpX.js"; import { n as listAgentIds } from "./agent-scope-config-CgCYpZfK.js"; //#region src/commands/doctor/shared/stale-subagent-allowlist.ts function normalizeOptionalAgentId(value) { const trimmed = normalizeOptionalString(value) ?? ""; if (!trimmed) return; return normalizeAgentId(trimmed); } function collectConfiguredSubagentTargetIds(cfg) { const ids = new Set(listAgentIds(cfg)); for (const agent of cfg.agents?.list ?? []) { if (agent.runtime?.type !== "acp") continue; const acpAgent = normalizeOptionalAgentId(agent.runtime.acp?.agent); if (acpAgent) ids.add(acpAgent); } const defaultAcpAgent = normalizeOptionalAgentId(cfg.acp?.defaultAgent); if (defaultAcpAgent) ids.add(defaultAcpAgent); for (const entry of cfg.acp?.allowedAgents ?? []) { if (entry.trim() === "*") continue; const acpAgent = normalizeOptionalAgentId(entry); if (acpAgent) ids.add(acpAgent); } return ids; } function collectStaleAllowlistEntries(params) { if (!Array.isArray(params.allowAgents)) return []; const hits = []; const seen = /* @__PURE__ */ new Set(); for (const entry of params.allowAgents) { if (typeof entry !== "string") continue; const trimmed = entry.trim(); if (!trimmed || trimmed === "*") continue; const normalizedAgentId = normalizeAgentId(trimmed); if (params.configuredTargetIds.has(normalizedAgentId)) continue; const key = `${params.pathLabel}:${normalizedAgentId}`; if (seen.has(key)) continue; seen.add(key); hits.push({ pathLabel: params.pathLabel, agentId: trimmed, normalizedAgentId }); } return hits; } /** Find subagent allowlist entries not backed by configured agent or ACP targets. */ function scanStaleSubagentAllowlistReferences(cfg) { const configuredTargetIds = collectConfiguredSubagentTargetIds(cfg); const hits = []; hits.push(...collectStaleAllowlistEntries({ allowAgents: cfg.agents?.defaults?.subagents?.allowAgents, pathLabel: "agents.defaults.subagents.allowAgents", configuredTargetIds })); const agents = Array.isArray(cfg.agents?.list) ? cfg.agents.list : []; for (const [index, agent] of agents.entries()) hits.push(...collectStaleAllowlistEntries({ allowAgents: agent?.subagents?.allowAgents, pathLabel: `agents.list.${index}.subagents.allowAgents`, configuredTargetIds })); return hits; } /** Format warnings for stale subagent allowlist entries. */ function collectStaleSubagentAllowlistWarnings(params) { if (params.hits.length === 0) return []; return [...params.hits.map((hit) => `- ${hit.pathLabel}: stale subagent target "${hit.agentId}" is not in the configured agent registry.`), `- Run "${params.doctorFixCommand}" to remove stale subagent target ids, or add a configured agent or ACP target for each intended target.`]; } function filterAllowAgents(params) { return params.allowAgents.filter((entry) => { const trimmed = entry.trim(); return !trimmed || trimmed === "*" || !params.staleTargetIds.has(normalizeAgentId(trimmed)); }); } /** Remove stale subagent allowlist entries while preserving valid targets and wildcards. */ function maybeRepairStaleSubagentAllowlists(cfg) { const hits = scanStaleSubagentAllowlistReferences(cfg); if (hits.length === 0) return { config: cfg, changes: [] }; const next = structuredClone(cfg); const hitsByPath = /* @__PURE__ */ new Map(); for (const hit of hits) hitsByPath.set(hit.pathLabel, [...hitsByPath.get(hit.pathLabel) ?? [], hit]); const defaultsHits = hitsByPath.get("agents.defaults.subagents.allowAgents") ?? []; if (defaultsHits.length > 0 && Array.isArray(next.agents?.defaults?.subagents?.allowAgents)) { const staleTargetIds = new Set(defaultsHits.map((hit) => hit.normalizedAgentId)); next.agents.defaults.subagents.allowAgents = filterAllowAgents({ allowAgents: next.agents.defaults.subagents.allowAgents, staleTargetIds }); } const agents = Array.isArray(next.agents?.list) ? next.agents.list : []; for (const [index, agent] of agents.entries()) { const pathLabel = `agents.list.${index}.subagents.allowAgents`; const agentHits = hitsByPath.get(pathLabel) ?? []; if (agentHits.length === 0 || !Array.isArray(agent?.subagents?.allowAgents)) continue; const staleTargetIds = new Set(agentHits.map((hit) => hit.normalizedAgentId)); agent.subagents.allowAgents = filterAllowAgents({ allowAgents: agent.subagents.allowAgents, staleTargetIds }); } return { config: next, changes: [...hitsByPath.entries()].map(([pathLabel, pathHits]) => { const ids = pathHits.map((hit) => hit.agentId).join(", "); return `- ${pathLabel}: removed ${pathHits.length} stale subagent target id${pathHits.length === 1 ? "" : "s"} (${ids})`; }) }; } //#endregion export { maybeRepairStaleSubagentAllowlists as n, scanStaleSubagentAllowlistReferences as r, collectStaleSubagentAllowlistWarnings as t };