UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

204 lines (203 loc) • 10.1 kB
import { l as normalizeOptionalString } from "./string-coerce-6kR-86XC.mjs"; import { t as _usingCtx } from "./usingCtx-DwOBYOJf.mjs"; import { Gn as validatePluginApprovalResolveParams, Wn as validatePluginApprovalRequestParams } from "./src-D2gvuSyP.mjs"; import { t as ErrorCodes } from "./gateway-error-details-DIefe7Zy.mjs"; import { f as errorShape } from "./error-codes-DI20vDEB.mjs"; import { n as resolveRequestedSessionAgentId } from "./session-request-agent-D8Xj-iBG.mjs"; import { a as resolveStoredSessionKeyForAgentStore } from "./session-store-key-11PJMhso.mjs"; import { i as sanitizeExecApprovalWarningText, n as sanitizeExecApprovalDisplayText, t as exceedsApprovalTextLimit } from "./exec-approval-text-sanitize-C5Sh27u3.mjs"; import { t as sanitizeApprovalScope } from "./approval-scope-4KFvgPWW.mjs"; import { f as resolvePluginApprovalTimeoutMs, p as truncatePluginApprovalDetail } from "./plugin-approvals-BL3jD3Ct.mjs"; import { t as resolveCanonicalPluginApprovalRequestAllowedDecisions } from "./plugin-approval-canonical-decisions-CavBtA0l.mjs"; import { n as takeMcpToolApprovalBinding } from "./mcp-tool-approval-binding-Rill2aFw.mjs"; import { t as assertValidParams } from "./validation-B7TobU6-.mjs"; import { r as listVisiblePendingApprovalRequests } from "./approval-record-lookup-9znlaBg1.mjs"; import { a as handleApprovalResolve, c as registerPendingApprovalRecord, l as resolveApprovalDecisionParams, n as bindApprovalReviewerDeviceIds, o as handleApprovalWaitDecision, t as bindApprovalRequesterMetadata } from "./approval-shared-Dp5fQIdi.mjs"; import { t as createApprovalRequestAuthority } from "./approval-request-authority-DF1YV4kB.mjs"; import { t as handlePendingApprovalRequestWithDelivery } from "./approval-request-delivery-CK_HN0oY.mjs"; import { randomUUID } from "node:crypto"; //#region src/gateway/server-methods/plugin-approval.ts /** Create plugin approval handlers backed by the shared approval manager. */ function createPluginApprovalHandlers(manager, opts) { return { "plugin.approval.list": async (options) => { try { var _usingCtx$1 = _usingCtx(); const authority = _usingCtx$1.u(createApprovalRequestAuthority(options)); const { respond, client, context } = options; const approvals = await listVisiblePendingApprovalRequests({ authority, manager, client, approvalKind: "plugin", ...client?.authenticatedUserProfile ? { getCfg: context.getRuntimeConfig } : {} }); authority.assertCurrent(); respond(true, approvals, void 0); } catch (_) { _usingCtx$1.e = _; } finally { _usingCtx$1.d(); } }, "plugin.approval.request": async ({ params, client, respond, context }) => { if (!assertValidParams(params, validatePluginApprovalRequestParams, "plugin.approval.request", respond)) return; const p = params; const twoPhase = p.twoPhase === true; const timeoutMs = resolvePluginApprovalTimeoutMs(p.timeoutMs); const trustedAgentRuntime = client?.internal?.agentRuntimeIdentity; if (trustedAgentRuntime && context.validateAgentRuntimeApprovalAuthority?.(trustedAgentRuntime) !== true) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "agent runtime approval authority is no longer active")); return; } if (trustedAgentRuntime && !trustedAgentRuntime.approvalOwnerPluginId) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "signed plugin approval owner is unavailable")); return; } if (p.policySubject && !trustedAgentRuntime) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "plugin approval policy subject requires agent runtime authority")); return; } const normalizeTrimmedString = (value) => normalizeOptionalString(value) || null; const rawSessionKey = normalizeOptionalString(trustedAgentRuntime?.sessionKey ?? p.sessionKey); const sessionOwner = rawSessionKey ? resolveRequestedSessionAgentId(context.getRuntimeConfig(), rawSessionKey, normalizeOptionalString(trustedAgentRuntime?.agentId ?? p.agentId)) : void 0; if (sessionOwner && !sessionOwner.ok) { respond(false, void 0, sessionOwner.error); return; } const sessionKey = rawSessionKey && sessionOwner?.ok ? resolveStoredSessionKeyForAgentStore({ cfg: context.getRuntimeConfig(), agentId: sessionOwner.agentId, sessionKey: rawSessionKey }) : null; const sanitizedTitle = sanitizeExecApprovalDisplayText(p.title); const sanitizedDescription = sanitizeExecApprovalWarningText(p.description); if (exceedsApprovalTextLimit(sanitizedTitle, 80) || exceedsApprovalTextLimit(sanitizedDescription, 512)) { respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "approval title or description exceeds the display limit after sanitization")); return; } const rawDetail = normalizeTrimmedString(p.detail); const sanitizeMeta = (value) => normalizeTrimmedString(value) === null ? null : sanitizeExecApprovalDisplayText(normalizeTrimmedString(value)); const request = { pluginId: trustedAgentRuntime?.approvalOwnerPluginId ?? sanitizeMeta(p.pluginId), title: sanitizedTitle, description: sanitizedDescription, scope: p.scope ? sanitizeApprovalScope(p.scope) : null, detail: rawDetail === null ? null : truncatePluginApprovalDetail(sanitizeExecApprovalWarningText(rawDetail)), severity: p.severity ?? null, toolName: sanitizeMeta(p.toolName), toolCallId: p.toolCallId ?? null, ...trustedAgentRuntime && p.policySubject ? { policySubject: { ...p.policySubject } } : {}, ...trustedAgentRuntime && p.mcpTool ? { mcpTool: { ...p.mcpTool } } : {}, ...Array.isArray(p.allowedDecisions) ? { allowedDecisions: resolveCanonicalPluginApprovalRequestAllowedDecisions({ allowedDecisions: p.allowedDecisions }) } : {}, agentId: trustedAgentRuntime?.agentId ?? (sessionOwner?.ok ? sessionOwner.agentId : sanitizeMeta(p.agentId)), sessionKey, runId: trustedAgentRuntime?.operationalRunInstance.runId ?? null, turnSourceChannel: trustedAgentRuntime ? normalizeTrimmedString(trustedAgentRuntime.turnSourceChannel) : normalizeTrimmedString(p.turnSourceChannel), turnSourceTo: trustedAgentRuntime ? normalizeTrimmedString(trustedAgentRuntime.turnSourceTo) : normalizeTrimmedString(p.turnSourceTo), turnSourceAccountId: trustedAgentRuntime ? normalizeTrimmedString(trustedAgentRuntime.turnSourceAccountId) : normalizeTrimmedString(p.turnSourceAccountId), turnSourceThreadId: trustedAgentRuntime ? trustedAgentRuntime.turnSourceThreadId ?? null : p.turnSourceThreadId ?? null }; const record = manager.create(request, timeoutMs, `plugin:${randomUUID()}`); if (trustedAgentRuntime) { record.agentRuntimeDelegatedAuthority = trustedAgentRuntime.delegatedAuthority; if (request.mcpTool && request.toolCallId) record.mcpToolApprovalActive = takeMcpToolApprovalBinding({ authority: trustedAgentRuntime.delegatedAuthority, agentId: trustedAgentRuntime.agentId, toolCallId: request.toolCallId, ...request.mcpTool }); } if (trustedAgentRuntime?.executionIdentity && request.runId === trustedAgentRuntime.executionIdentity.runId) record.executionIdentityToken = trustedAgentRuntime.executionIdentity; bindApprovalRequesterMetadata({ record, client }); if (client?.internal?.approvalRuntime === true) bindApprovalReviewerDeviceIds({ record, deviceIds: p.approvalReviewerDeviceIds }); if (!await registerPendingApprovalRecord({ manager, record, timeoutMs, respond, context })) return; await handlePendingApprovalRequestWithDelivery({ approvalKind: "plugin", manager, record, respond, context, clientConnId: client?.connId, twoPhase, forwardRequest: opts?.forwarder?.handlePluginApprovalRequested?.bind(opts.forwarder), getIosPushDelivery: () => opts?.iosPushDelivery, source: "rpc" }); }, "plugin.approval.waitDecision": async (options) => { try { var _usingCtx3 = _usingCtx(); const authority = _usingCtx3.u(createApprovalRequestAuthority(options)); const { params, respond, client, context } = options; await handleApprovalWaitDecision({ authority, manager, inputId: params.id, client, ...client?.authenticatedUserProfile ? { getCfg: context.getRuntimeConfig } : {}, respond }); } catch (_) { _usingCtx3.e = _; } finally { _usingCtx3.d(); } }, "plugin.approval.resolve": async (options) => { try { var _usingCtx4 = _usingCtx(); const authority = _usingCtx4.u(createApprovalRequestAuthority(options)); const { params, respond, client, context } = options; const resolveParams = resolveApprovalDecisionParams({ rawParams: params, validate: validatePluginApprovalResolveParams, methodName: "plugin.approval.resolve", respond }); if (!resolveParams) return; const { inputId, decision, reviewer } = resolveParams; await handleApprovalResolve({ approvalKind: "plugin", authority, manager, inputId, decision, respond, context, client, reviewer, exposeAmbiguousPrefixError: false, validateDecision: (snapshot) => resolveCanonicalPluginApprovalRequestAllowedDecisions(snapshot.request).includes(decision) ? null : { message: `${decision} is unavailable for this plugin approval`, details: { allowedDecisions: resolveCanonicalPluginApprovalRequestAllowedDecisions(snapshot.request) } }, forwardResolved: (resolvedEvent) => opts?.forwarder?.handlePluginApprovalResolved?.(resolvedEvent), forwardResolvedErrorLabel: "plugin approvals: forward resolve failed", extraResolvedHandlers: opts?.iosPushDelivery?.handleResolved ? [{ run: (resolvedEvent) => opts.iosPushDelivery.handleResolved(resolvedEvent), errorLabel: "plugin approvals: iOS push resolve failed" }] : void 0 }); } catch (_) { _usingCtx4.e = _; } finally { _usingCtx4.d(); } } }; } //#endregion export { createPluginApprovalHandlers };