UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

282 lines (281 loc) • 14.4 kB
import { l as resolveSessionStorePathCore } from "./paths-CAzSovN1.mjs"; import { g as resolveSessionAgentId } from "./agent-scope-DWB4x52T.mjs"; import { r as isKnownCoreToolId } from "./tool-catalog-D1rzNkvG.mjs"; import { l as normalizeToolPolicyName, o as expandToolGroups, u as readToolAllowlistIntersection } from "./tool-policy-shared-DSNSYBF4.mjs"; import { o as isToolAllowedByPolicies } from "./tool-policy-match-COwlx5YS.mjs"; import { d as toolPolicyRestrictsTools, l as mergeAlsoAllowPolicy } from "./tool-policy-C57wduz9.mjs"; import { t as AgentHarnessPreflightError } from "./errors-Bd6GQRkh.mjs"; import { E as resolveSessionEntry } from "./session-accessor.sqlite-pending-inputs-BpI_NyvM.mjs"; import { r as resolveGroupToolPolicy } from "./agent-tools.policy-E-66VU7i.mjs"; import { n as resolveEffectiveToolFsWorkspaceOnly } from "./tool-fs-policy-BUhKAtVz.mjs"; import { n as resolveSandboxRuntimeStatus } from "./runtime-status-Bfel3YpH.mjs"; import { t as resolveScheduledToolCallerContext } from "./scheduled-tool-policy-dpd0XLqN.mjs"; import { t as resolveConversationCapabilityProfile } from "./conversation-capability-profile-rQYLcX4p.mjs"; import { n as resolveExecConfigState } from "./exec-defaults-D_C0LX4M.mjs"; //#region src/agents/harness/execution-environment.ts /** Selection and invocation share this decision; a native working directory is not containment. */ function resolveAgentHarnessExecutionRestriction(harness, facts) { if (harness.executionEnvironment !== "host-only") return; const label = harness.label; if (facts.sandboxRequired) return { reason: "sandbox-required", message: label + " runs on the Gateway host, but this chat requires a sandbox. Choose another runtime; this requirement cannot be removed." }; if (facts.remoteExecution) return { reason: "remote-execution", message: label + " runs on the Gateway host and cannot use this chat's remote execution environment. Choose another runtime or a local chat." }; if (facts.workspaceRequired) return { reason: "workspace-only", message: label + " cannot enforce this run's required workspace boundary. Choose another runtime." }; if (facts.nativeRuntimeConsent === harness.id) return; if (facts.workspaceOnly) return { reason: "workspace-only", message: label + " cannot enforce this chat's workspace-only file access. Choose another runtime or ask an administrator to review the file-access policy." }; if (facts.sandboxed) return { reason: "sandbox", message: label + " runs on the Gateway host, outside the sandbox. Use its own permissions for this chat, or choose another runtime." }; if (facts.permissionMode && facts.permissionMode !== "full") return { reason: "permission-mode", message: label + " uses its own permissions and requires Full access. Change this chat's permissions explicitly, or choose another runtime." }; if (facts.toolPolicyRestricted) return { reason: "tool-policy", message: label + " uses its own tools and cannot enforce this chat's OpenClaw tool restrictions." }; } /** Classifies stored or prospective session policy without selecting runtime availability. */ function resolveAgentHarnessSessionExecutionRestriction(params) { const { cfg, agentId, sessionKey, entry, harness } = params; if (harness.executionEnvironment !== "host-only") return; const sandbox = resolveSandboxRuntimeStatus({ cfg, agentId, sessionKey, preparedSessionEntry: entry }); const exec = resolveExecConfigState({ cfg, agentId, sessionKey, sessionEntry: entry }); const nativeRuntimeConsent = entry.permissionMode === "full" && entry.sandboxMode === "off" ? entry.nativeRuntimeConsent : void 0; return resolveAgentHarnessExecutionRestriction(harness, { sandboxed: sandbox.sandboxed || exec.host === "sandbox", sandboxRequired: sandbox.sandboxRequired || exec.host === "sandbox", workspaceOnly: resolveEffectiveToolFsWorkspaceOnly({ cfg, agentId }), permissionMode: entry.permissionMode, nativeRuntimeConsent, remoteExecution: exec.host === "node", toolPolicyRestricted: nativeRuntimeConsent !== harness.id && harness.conversationToolPolicySupport !== "exact" && resolveAgentHarnessNativeToolPolicyRestricted({ config: cfg, agentId, sessionKey, sessionId: entry.sessionId, preparedSessionEntry: entry, provider: params.provider, modelId: params.modelId }, harness) }); } /** Revalidates execution policy and returns whether this run has native permission consent. */ function assertAgentHarnessExecutionEnvironment(harness, params) { if (harness.executionEnvironment !== "host-only") return false; const agentId = resolveSessionAgentId({ config: params.config, agentId: params.agentId, sessionKey: params.sessionKey }); const entry = params.sessionKey ? resolveSessionEntry({ agentId, sessionKey: params.sessionKey, storePath: resolveSessionStorePathCore(params.config?.session?.store, { agentId }), clone: false }, { readOnly: true }).existing : void 0; const nativeRuntimeConsent = entry?.sessionId === params.sessionId && entry.agentRuntimeOverride === harness.id && entry.permissionMode === "full" && entry.sandboxMode === "off" && !params.disableTools && params.toolsAllow === void 0 && !params.swarmCollector ? entry.nativeRuntimeConsent : void 0; const runtime = resolveSandboxRuntimeStatus({ cfg: params.config, agentId: params.agentId, sessionKey: params.sessionKey, classificationSessionKey: params.sandboxSessionKey, classificationAgentId: params.sandboxAgentId, ...(!params.sandboxSessionKey || params.sandboxSessionKey === params.sessionKey) && (!params.sandboxAgentId || params.sandboxAgentId === agentId) ? { preparedSessionEntry: entry ?? null } : {} }); const exec = resolveExecConfigState({ cfg: params.config, agentId: runtime.classificationAgentId, sessionKey: params.sessionKey, execOverrides: params.execOverrides }); const restriction = resolveAgentHarnessExecutionRestriction(harness, { sandboxed: params.sandbox?.enabled === true || runtime.sandboxed || exec.host === "sandbox", nativeRuntimeConsent, workspaceRequired: params.requireWorkspaceOnly === true, sandboxRequired: runtime.sandboxRequired || exec.host === "sandbox", workspaceOnly: params.requireWorkspaceOnly === true || resolveEffectiveToolFsWorkspaceOnly({ cfg: params.config, agentId: runtime.classificationAgentId }), permissionMode: params.permissionMode, remoteExecution: exec.host === "node" }); if (restriction) throw new AgentHarnessPreflightError(restriction.message, { scope: "harness", userMessage: restriction.message }); return nativeRuntimeConsent === harness.id; } const PLUGIN_HARNESS_SENDER_DENY_ALL_PROMPT = "Tool and file actions are disabled for this sender by chat policy. If asked to edit files or use tools, say this sender is not allowed by policy; do not imply retrying will help."; const PLUGIN_HARNESS_GROUP_DENY_ALL_PROMPT = "Tool and file actions are disabled for this chat by policy. If asked to edit files or use tools, say this chat is not allowed by policy."; const PLUGIN_HARNESS_RUNTIME_DENY_ALL_PROMPT = "Tool and file actions are disabled by runtime policy. If asked to edit files or use tools, say tools are disabled by policy."; function resolvePluginHarnessPolicyToolsAllow(params) { const policies = resolvePluginHarnessToolPolicies(params); return [ policies.senderPolicy, policies.groupPolicy, ...policies.runtimePolicies ].some(toolPolicyRestrictsTools) ? [] : void 0; } /** Resolves whether a harness operation must remove its ambient native tool surface. */ function resolveAgentHarnessNativeToolPolicyRestricted(params, harness) { return resolvePluginHarnessToolPolicies(params, harness.conversationToolPolicySupport === "exact" ? harness.conversationToolPolicySafeDenyTools : void 0, harness.conversationToolPolicyNativeTools).toolPolicyRestricted; } function resolvePluginHarnessDenyAllToolPolicyPrompt(policies) { if (policyDeniesAllTools(policies.senderPolicy) || policyDeniesAllTools(policies.senderScopedGroupPolicy)) return PLUGIN_HARNESS_SENDER_DENY_ALL_PROMPT; if (policyDeniesAllTools(policies.groupPolicy)) return PLUGIN_HARNESS_GROUP_DENY_ALL_PROMPT; return policies.runtimePolicies.some(policyDeniesAllTools) ? PLUGIN_HARNESS_RUNTIME_DENY_ALL_PROMPT : void 0; } function resolvePluginHarnessToolPolicies(params, safeDenyToolNames, nativeToolNames) { const messageProvider = params.messageProvider ?? params.messageChannel; const sandboxSessionKey = params.sandboxSessionKey ?? params.sessionKey; const sandboxRuntime = resolveSandboxRuntimeStatus({ cfg: params.config, agentId: params.agentId, sessionKey: params.sessionKey ?? (params.agentId ? void 0 : sandboxSessionKey), classificationSessionKey: sandboxSessionKey, classificationAgentId: params.sandboxAgentId, preparedSessionEntry: params.preparedSessionEntry }); const sandboxPolicy = sandboxRuntime.sandboxed ? sandboxRuntime.toolPolicy : void 0; const capabilityProfile = resolveConversationCapabilityProfile({ config: params.config, sessionId: params.sessionId, sessionKey: params.sessionKey, sandboxSessionKey, agentId: params.agentId, modelProvider: params.provider, modelId: params.modelId, messageProvider, messageChannel: params.messageChannel, conversationToolPolicy: params.conversationToolPolicy, agentAccountId: params.agentAccountId, groupId: params.groupId, groupChannel: params.groupChannel, groupSpace: params.groupSpace, memberRoleIds: params.memberRoleIds, spawnedBy: params.spawnedBy, senderId: params.senderId, senderName: params.senderName, senderUsername: params.senderUsername, senderE164: params.senderE164, senderIsOwner: params.senderIsOwner, sandboxToolPolicy: sandboxPolicy, inputProvenance: params.inputProvenance, trustedInternalHandoff: params.trustedInternalHandoff, scheduledToolPolicy: params.scheduledToolPolicy, runtimePluginToolGrant: params.runtimePluginToolGrant }); const callerContext = resolveScheduledToolCallerContext({ scheduledToolPolicy: params.scheduledToolPolicy, channel: messageProvider }); const groupPolicyParams = { config: params.config, sessionKey: params.scheduledToolPolicy?.ownerSessionKey ?? params.sessionKey, spawnedBy: params.spawnedBy, messageProvider: callerContext.local ? messageProvider : callerContext.channel ?? void 0, groupId: params.groupId, groupChannel: params.groupChannel, groupSpace: params.groupSpace, accountId: params.scheduledToolPolicy?.ownerAccountId ?? params.agentAccountId, requireConfiguredAccount: params.scheduledToolPolicy?.mode === "account", senderId: params.senderId, senderName: params.senderName, senderUsername: params.senderUsername, senderE164: params.senderE164, senderPolicyMode: params.scheduledToolPolicy ? "never" : "always" }; const { policy } = capabilityProfile; const runtimeRestrictions = params.toolsAllow && (readToolAllowlistIntersection(params.toolsAllow) ?? [params.toolsAllow]); const requestedToolPolicy = params.disableTools || runtimeRestrictions?.some((allow) => allow.length === 0) ? { deny: ["*"] } : params.toolsAllow ? { allow: params.toolsAllow } : void 0; const explicitPolicies = [ policy.globalPolicy, policy.globalProviderPolicy, policy.agentPolicy, policy.agentProviderPolicy, policy.groupPolicy, policy.senderPolicy, policy.sandboxPolicy, policy.subagentPolicy, policy.inheritedToolPolicy, policy.runtimeToolPolicyForInheritance, requestedToolPolicy ]; const safeDenyToolNameSet = safeDenyToolNames ? new Set(safeDenyToolNames.map(normalizeToolPolicyName)) : void 0; const profilePolicies = [mergeAlsoAllowPolicy(policy.profilePolicy, policy.profileAlsoAllow), mergeAlsoAllowPolicy(policy.providerProfilePolicy, policy.providerProfileAlsoAllow)]; return { senderPolicy: policy.senderPolicy, senderScopedGroupPolicy: resolveSenderScopedGroupToolPolicy(params, groupPolicyParams, policy.groupPolicy), groupPolicy: policy.groupPolicy, runtimePolicies: [ ...profilePolicies, policy.globalPolicy, policy.globalProviderPolicy, policy.agentPolicy, policy.agentProviderPolicy, sandboxPolicy, policy.subagentPolicy, policy.inheritedToolPolicy, requestedToolPolicy ], safeDeniedToolNames: collectHarnessSafeDeniedToolNames(explicitPolicies, safeDenyToolNameSet), toolPolicyRestricted: params.swarmCollector === true || nativeToolNames?.some((toolName) => !isToolAllowedByPolicies(toolName, profilePolicies)) === true || explicitPolicies.some((explicitPolicy) => toolPolicyRestrictsHarnessNativeTools(explicitPolicy, safeDenyToolNameSet)) }; } function collectHarnessSafeDeniedToolNames(policies, safeDenyToolNames) { if (!safeDenyToolNames) return []; return [...new Set(policies.flatMap((policy) => expandToolGroups(policy?.deny ?? [])).map(normalizeToolPolicyName).filter((name) => isKnownCoreToolId(name) && safeDenyToolNames.has(name)))].toSorted(); } function toolPolicyRestrictsHarnessNativeTools(policy, safeDenyToolNames) { if (!safeDenyToolNames) return toolPolicyRestrictsTools(policy); if (!policy || toolPolicyRestrictsTools({ allow: policy.allow })) return toolPolicyRestrictsTools(policy); return expandToolGroups(policy.deny ?? []).some((deniedName) => { const normalized = normalizeToolPolicyName(deniedName); return !isKnownCoreToolId(normalized) || !safeDenyToolNames.has(normalized); }); } function resolveSenderScopedGroupToolPolicy(params, groupPolicyParams, groupPolicy) { if (!policyDeniesAllTools(groupPolicy) || !hasSenderIdentity(params)) return; return policyDeniesAllTools(resolveGroupToolPolicy({ ...groupPolicyParams, senderId: void 0, senderName: void 0, senderUsername: void 0, senderE164: void 0 })) ? void 0 : groupPolicy; } function hasSenderIdentity(params) { return Boolean(params.senderId?.trim() || params.senderName?.trim() || params.senderUsername?.trim() || params.senderE164?.trim()); } function policyDeniesAllTools(policy) { return expandToolGroups(policy?.deny ?? []).some((entry) => normalizeToolPolicyName(entry) === "*"); } //#endregion export { resolvePluginHarnessPolicyToolsAllow as a, resolvePluginHarnessDenyAllToolPolicyPrompt as i, resolveAgentHarnessNativeToolPolicyRestricted as n, resolvePluginHarnessToolPolicies as o, resolveAgentHarnessSessionExecutionRestriction as r, assertAgentHarnessExecutionEnvironment as t };