openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
116 lines (115 loc) • 5.63 kB
JavaScript
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 };