Spaces:
Paused
Paused
| import type { OpenClawConfig } from "../../config/config.js"; | |
| import type { SandboxConfig, SandboxToolPolicyResolved } from "./types.js"; | |
| import { formatCliCommand } from "../../cli/command-format.js"; | |
| import { canonicalizeMainSessionAlias, resolveAgentMainSessionKey } from "../../config/sessions.js"; | |
| import { resolveSessionAgentId } from "../agent-scope.js"; | |
| import { expandToolGroups } from "../tool-policy.js"; | |
| import { resolveSandboxConfigForAgent } from "./config.js"; | |
| import { resolveSandboxToolPolicyForAgent } from "./tool-policy.js"; | |
| function shouldSandboxSession(cfg: SandboxConfig, sessionKey: string, mainSessionKey: string) { | |
| if (cfg.mode === "off") { | |
| return false; | |
| } | |
| if (cfg.mode === "all") { | |
| return true; | |
| } | |
| return sessionKey.trim() !== mainSessionKey.trim(); | |
| } | |
| function resolveMainSessionKeyForSandbox(params: { | |
| cfg?: OpenClawConfig; | |
| agentId: string; | |
| }): string { | |
| if (params.cfg?.session?.scope === "global") { | |
| return "global"; | |
| } | |
| return resolveAgentMainSessionKey({ | |
| cfg: params.cfg, | |
| agentId: params.agentId, | |
| }); | |
| } | |
| function resolveComparableSessionKeyForSandbox(params: { | |
| cfg?: OpenClawConfig; | |
| agentId: string; | |
| sessionKey: string; | |
| }): string { | |
| return canonicalizeMainSessionAlias({ | |
| cfg: params.cfg, | |
| agentId: params.agentId, | |
| sessionKey: params.sessionKey, | |
| }); | |
| } | |
| export function resolveSandboxRuntimeStatus(params: { | |
| cfg?: OpenClawConfig; | |
| sessionKey?: string; | |
| }): { | |
| agentId: string; | |
| sessionKey: string; | |
| mainSessionKey: string; | |
| mode: SandboxConfig["mode"]; | |
| sandboxed: boolean; | |
| toolPolicy: SandboxToolPolicyResolved; | |
| } { | |
| const sessionKey = params.sessionKey?.trim() ?? ""; | |
| const agentId = resolveSessionAgentId({ | |
| sessionKey, | |
| config: params.cfg, | |
| }); | |
| const cfg = params.cfg; | |
| const sandboxCfg = resolveSandboxConfigForAgent(cfg, agentId); | |
| const mainSessionKey = resolveMainSessionKeyForSandbox({ cfg, agentId }); | |
| const sandboxed = sessionKey | |
| ? shouldSandboxSession( | |
| sandboxCfg, | |
| resolveComparableSessionKeyForSandbox({ cfg, agentId, sessionKey }), | |
| mainSessionKey, | |
| ) | |
| : false; | |
| return { | |
| agentId, | |
| sessionKey, | |
| mainSessionKey, | |
| mode: sandboxCfg.mode, | |
| sandboxed, | |
| toolPolicy: resolveSandboxToolPolicyForAgent(cfg, agentId), | |
| }; | |
| } | |
| export function formatSandboxToolPolicyBlockedMessage(params: { | |
| cfg?: OpenClawConfig; | |
| sessionKey?: string; | |
| toolName: string; | |
| }): string | undefined { | |
| const tool = params.toolName.trim().toLowerCase(); | |
| if (!tool) { | |
| return undefined; | |
| } | |
| const runtime = resolveSandboxRuntimeStatus({ | |
| cfg: params.cfg, | |
| sessionKey: params.sessionKey, | |
| }); | |
| if (!runtime.sandboxed) { | |
| return undefined; | |
| } | |
| const deny = new Set(expandToolGroups(runtime.toolPolicy.deny)); | |
| const allow = expandToolGroups(runtime.toolPolicy.allow); | |
| const allowSet = allow.length > 0 ? new Set(allow) : null; | |
| const blockedByDeny = deny.has(tool); | |
| const blockedByAllow = allowSet ? !allowSet.has(tool) : false; | |
| if (!blockedByDeny && !blockedByAllow) { | |
| return undefined; | |
| } | |
| const reasons: string[] = []; | |
| const fixes: string[] = []; | |
| if (blockedByDeny) { | |
| reasons.push("deny list"); | |
| fixes.push(`Remove "${tool}" from ${runtime.toolPolicy.sources.deny.key}.`); | |
| } | |
| if (blockedByAllow) { | |
| reasons.push("allow list"); | |
| fixes.push( | |
| `Add "${tool}" to ${runtime.toolPolicy.sources.allow.key} (or set it to [] to allow all).`, | |
| ); | |
| } | |
| const lines: string[] = []; | |
| lines.push(`Tool "${tool}" blocked by sandbox tool policy (mode=${runtime.mode}).`); | |
| lines.push(`Session: ${runtime.sessionKey || "(unknown)"}`); | |
| lines.push(`Reason: ${reasons.join(" + ")}`); | |
| lines.push("Fix:"); | |
| lines.push(`- agents.defaults.sandbox.mode=off (disable sandbox)`); | |
| for (const fix of fixes) { | |
| lines.push(`- ${fix}`); | |
| } | |
| if (runtime.mode === "non-main") { | |
| lines.push(`- Use main session key (direct): ${runtime.mainSessionKey}`); | |
| } | |
| lines.push( | |
| `- See: ${formatCliCommand(`openclaw sandbox explain --session ${runtime.sessionKey}`)}`, | |
| ); | |
| return lines.join("\n"); | |
| } | |