UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

116 lines (115 loc) 5.63 kB
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js"; import { t as pruneMapToMaxSize } from "./map-size-CNcWiFKu.js"; import "./session-key-BnWWjqNc.js"; import { n as normalizeMessageChannel } from "./message-channel-core-AaEWic-A.js"; import { t as isDeliverableMessageChannel } from "./message-channel-normalize-B81s0XMO.js"; import { randomBytes } from "node:crypto"; //#region src/gateway/message-action-turn-capability.ts const DEFAULT_TTL_MS = 9e5; const MAX_TTL_MS = 864e5; const RUN_LIFETIME_EXPIRES_AT_MS = Number.MAX_SAFE_INTEGER; const CAPABILITY_COMPLETION_GRACE_MS = 6e4; function selectMessageActionRequesterIdentity(context) { return { requesterAccountId: context?.requesterAccountId, requesterSenderId: context?.requesterSenderId, requesterSenderName: context?.requesterSenderName, requesterSenderUsername: context?.requesterSenderUsername, requesterSenderE164: context?.requesterSenderE164 }; } const capabilitiesByToken = /* @__PURE__ */ new Map(); function isTrustedMessageActionTurnIngress(provider) { const normalized = normalizeMessageChannel(provider); return normalized !== void 0 && isDeliverableMessageChannel(normalized); } function resolveTtlMs(value) { if (!Number.isFinite(value) || value === void 0 || value <= 0) return DEFAULT_TTL_MS; return Math.min(Math.trunc(value), MAX_TTL_MS); } /** Mirrors agent timeout semantics while leaving unlimited runs to explicit revocation. */ function resolveMessageActionTurnCapabilityLifetime(timeoutMs) { return Number.isFinite(timeoutMs) && timeoutMs > 0 ? { ttlMs: timeoutMs + CAPABILITY_COMPLETION_GRACE_MS } : { expiresWithRun: true }; } function copyToolContext(context) { if (!context) return; return { currentChannelId: normalizeOptionalString(context.currentChannelId), currentChatType: context.currentChatType, currentMessagingTarget: normalizeOptionalString(context.currentMessagingTarget), currentGraphChannelId: normalizeOptionalString(context.currentGraphChannelId), currentChannelProvider: context.currentChannelProvider, currentThreadTs: normalizeOptionalString(context.currentThreadTs), currentMessageId: context.currentMessageId, currentSourceTurnId: normalizeOptionalString(context.currentSourceTurnId), replyToMode: context.replyToMode, hasRepliedRef: context.hasRepliedRef, sameChannelThreadRequired: context.sameChannelThreadRequired, skipCrossContextDecoration: context.skipCrossContextDecoration }; } function sweepExpiredMessageActionTurnCapabilities(nowMs = Date.now()) { let removed = 0; for (const [token, capability] of capabilitiesByToken) if (nowMs >= capability.expiresAtMs) { capabilitiesByToken.delete(token); removed += 1; } return removed; } /** * Mint an opaque current-turn capability from trusted channel ingress. * Public Gateway agent requests never receive this token. */ function mintMessageActionTurnCapability(params) { const agentId = normalizeAgentId(params.agentId); const runId = params.runId.trim(); const sessionKey = params.sessionKey.trim(); if (!agentId || !runId || !sessionKey) throw new Error("message action turn capability requires agent, run, and session identity"); const nowMs = params.nowMs ?? Date.now(); sweepExpiredMessageActionTurnCapabilities(nowMs); pruneMapToMaxSize(capabilitiesByToken, 4095); const token = randomBytes(32).toString("base64url"); capabilitiesByToken.set(token, { agentId, runId, sessionKey, expiresAtMs: params.expiresWithRun ? RUN_LIFETIME_EXPIRES_AT_MS : nowMs + resolveTtlMs(params.ttlMs), sessionId: normalizeOptionalString(params.sessionId), sourceReplySessionKey: normalizeOptionalString(params.sourceReplySessionKey), requesterAccountId: normalizeOptionalString(params.requesterAccountId), requesterSenderId: normalizeOptionalString(params.requesterSenderId), requesterSenderName: normalizeOptionalString(params.requesterSenderName), requesterSenderUsername: normalizeOptionalString(params.requesterSenderUsername), requesterSenderE164: normalizeOptionalString(params.requesterSenderE164), toolContext: copyToolContext(params.toolContext) }); return token; } function resolveMessageActionTurnCapability(params) { const token = params.token?.trim(); if (!token) return; const capability = capabilitiesByToken.get(token); if (!capability) return; if ((params.nowMs ?? Date.now()) >= capability.expiresAtMs) { capabilitiesByToken.delete(token); return; } if (capability.agentId !== normalizeAgentId(params.agentId) || capability.runId !== params.runId?.trim() || capability.sessionKey !== params.sessionKey.trim() || capability.sessionId && capability.sessionId !== normalizeOptionalString(params.sessionId)) return; return { expiresAtMs: capability.expiresAtMs, sessionId: capability.sessionId, sourceReplySessionKey: capability.sourceReplySessionKey, requesterAccountId: capability.requesterAccountId, requesterSenderId: capability.requesterSenderId, requesterSenderName: capability.requesterSenderName, requesterSenderUsername: capability.requesterSenderUsername, requesterSenderE164: capability.requesterSenderE164, toolContext: copyToolContext(capability.toolContext) }; } function revokeMessageActionTurnCapability(token) { return token ? capabilitiesByToken.delete(token) : false; } //#endregion export { revokeMessageActionTurnCapability as a, resolveMessageActionTurnCapabilityLifetime as i, mintMessageActionTurnCapability as n, selectMessageActionRequesterIdentity as o, resolveMessageActionTurnCapability as r, isTrustedMessageActionTurnIngress as t };