openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
227 lines (226 loc) • 15 kB
JavaScript
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { t as isDeliverableMessageChannel } from "./message-channel-normalize-B81s0XMO.js";
import "./message-channel-BQrhwUEA.js";
import { c as normalizeDeliveryContext } from "./delivery-context.shared-CXmRgetN.js";
import { isDeepStrictEqual } from "node:util";
//#region src/config/sessions/restart-recovery-state.ts
/** Resolves only a complete durable channel claim; session-route fallbacks carry no authority. */
function resolveRestartRecoveryChannelAuthority(entry) {
const sourceTurnId = normalizeOptionalString(entry.restartRecoveryDeliverySourceRunId);
const deliveryContext = normalizeDeliveryContext(entry.restartRecoveryDeliveryContext);
const channel = normalizeOptionalString(deliveryContext?.channel);
const to = normalizeOptionalString(deliveryContext?.to);
if (entry.restartRecoverySourceIngress !== "channel" || !sourceTurnId || !channel || !to || !isDeliverableMessageChannel(channel)) return;
return {
sourceTurnId,
deliveryContext: {
...deliveryContext,
channel,
to
}
};
}
function normalizeThreadId(value) {
return normalizeOptionalString(value) ?? (typeof value === "number" && Number.isFinite(value) ? String(value) : void 0);
}
function normalizeStringArray(value) {
if (!Array.isArray(value)) return;
const values = Array.from(new Set(value.flatMap((item) => {
const normalized = normalizeOptionalString(item);
return normalized ? [normalized] : [];
})));
return values.length > 0 ? values : void 0;
}
function normalizePresentStringArray(value) {
if (!Array.isArray(value)) return;
return normalizeStringArray(value) ?? [];
}
function normalizeTerminalDeliveryEvidenceResult(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return;
const record = value;
const captured = record.captured === true ? true : void 0;
const rawPayloads = Array.isArray(record.payloads) ? record.payloads : void 0;
const payloads = rawPayloads ? rawPayloads.slice(0, 64).map((item) => {
if (!item || typeof item !== "object" || Array.isArray(item)) return {};
const payload = item;
const mediaUrls = normalizeStringArray(payload.mediaUrls);
const visible = typeof payload.visible === "boolean" ? payload.visible : void 0;
const evidence = {};
if (mediaUrls) evidence.mediaUrls = mediaUrls;
if (visible !== void 0) evidence.visible = visible;
return evidence;
}) : void 0;
const payloadsTruncated = record.payloadsTruncated === true || (rawPayloads?.length ?? 0) > 64 ? true : void 0;
const rawStatus = record.deliveryStatus && typeof record.deliveryStatus === "object" ? record.deliveryStatus : void 0;
const status = rawStatus?.status === "failed" || rawStatus?.status === "partial_failed" || rawStatus?.status === "sent" || rawStatus?.status === "suppressed" ? rawStatus.status : void 0;
const payloadOutcomes = Array.isArray(rawStatus?.payloadOutcomes) ? rawStatus.payloadOutcomes.slice(0, 64).flatMap((item) => {
if (!item || typeof item !== "object" || Array.isArray(item)) return [];
const outcome = item;
const outcomeStatus = outcome.status === "failed" || outcome.status === "sent" || outcome.status === "suppressed" ? outcome.status : void 0;
if (!outcomeStatus || typeof outcome.index !== "number" || !Number.isInteger(outcome.index) || outcome.index < 0) return [];
return [{
index: outcome.index,
status: outcomeStatus,
...typeof outcome.sentBeforeError === "boolean" ? { sentBeforeError: outcome.sentBeforeError } : {}
}];
}) : void 0;
const errorMessage = normalizeOptionalString(rawStatus?.errorMessage);
const deliveryStatus = status ? {
status,
...errorMessage ? { errorMessage } : {},
...payloadOutcomes?.length ? { payloadOutcomes } : {}
} : void 0;
const rawMessagingToolSentTargets = Array.isArray(record.messagingToolSentTargets) ? record.messagingToolSentTargets : void 0;
const messagingToolSentTargets = rawMessagingToolSentTargets ? rawMessagingToolSentTargets.slice(0, 64).flatMap((item) => {
if (!item || typeof item !== "object" || Array.isArray(item)) return [];
const target = item;
const provider = normalizeOptionalString(target.provider);
const accountId = normalizeOptionalString(target.accountId);
const to = normalizeOptionalString(target.to);
const threadId = normalizeThreadId(target.threadId);
const mediaUrls = normalizeStringArray(target.mediaUrls);
const visible = typeof target.visible === "boolean" ? target.visible : void 0;
if (!provider && !accountId && !to && !threadId && !mediaUrls && visible === void 0) return [];
return [{
...provider ? { provider } : {},
...accountId ? { accountId } : {},
...to ? { to } : {},
...threadId ? { threadId } : {},
...target.threadImplicit === true ? { threadImplicit: true } : {},
...target.threadSuppressed === true ? { threadSuppressed: true } : {},
...mediaUrls ? { mediaUrls } : {},
...visible !== void 0 ? { visible } : {}
}];
}) : void 0;
const messagingToolSentTargetsTruncated = record.messagingToolSentTargetsTruncated === true || (rawMessagingToolSentTargets?.length ?? 0) > 64 ? true : void 0;
const messagingToolAggregateEvidenceUnaccounted = record.messagingToolAggregateEvidenceUnaccounted === true ? true : void 0;
const restartUnsafeSideEffectsDetected = record.restartUnsafeSideEffectsDetected === true ? true : void 0;
if (!captured && !payloads?.length && !payloadsTruncated && !deliveryStatus && !messagingToolSentTargets?.length && !messagingToolSentTargetsTruncated && !messagingToolAggregateEvidenceUnaccounted && !restartUnsafeSideEffectsDetected) return;
return {
...captured ? { captured } : {},
...payloads?.length ? { payloads } : {},
...payloadsTruncated ? { payloadsTruncated } : {},
...deliveryStatus ? { deliveryStatus } : {},
...messagingToolSentTargets?.length ? { messagingToolSentTargets } : {},
...messagingToolSentTargetsTruncated ? { messagingToolSentTargetsTruncated } : {},
...messagingToolAggregateEvidenceUnaccounted ? { messagingToolAggregateEvidenceUnaccounted } : {},
...restartUnsafeSideEffectsDetected ? { restartUnsafeSideEffectsDetected } : {}
};
}
function normalizeRestartRecoveryTerminalDeliveryEvidence(value) {
if (!Array.isArray(value)) return;
const evidence = [];
for (const item of value) {
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
const runId = normalizeOptionalString(item.runId);
const result = normalizeTerminalDeliveryEvidenceResult(item);
if (!runId || !result) continue;
const previousIndex = evidence.findIndex((entry) => entry.runId === runId);
if (previousIndex >= 0) evidence.splice(previousIndex, 1);
evidence.push({
runId,
...result
});
}
const bounded = evidence.slice(-64);
return bounded.length > 0 ? bounded : void 0;
}
/** Keeps a bounded durable set of client runs that must never execute again. */
function normalizeRestartRecoveryTerminalRunIds(value) {
if (!Array.isArray(value)) return;
const runIds = [];
for (const item of value) {
const runId = normalizeOptionalString(item);
if (!runId) continue;
const previousIndex = runIds.indexOf(runId);
if (previousIndex >= 0) runIds.splice(previousIndex, 1);
runIds.push(runId);
}
const bounded = runIds.slice(-64);
return bounded.length > 0 ? bounded : void 0;
}
function sameOptionalStringArray(left, right) {
if (!Array.isArray(left) || !right) return left === void 0 && right === void 0;
return left.length === right.length && left.every((value, index) => value === right[index]);
}
/** Compares normalized durable terminal-source tombstones by value and order. */
function sameRestartRecoveryTerminalRunIds(left, right) {
return sameOptionalStringArray(left, normalizeRestartRecoveryTerminalRunIds(right));
}
/** Normalizes restart-claim fields while preserving an already-canonical array identity. */
function normalizeRestartRecoveryEntryFields(entry, assign) {
const deliveryMediaUrls = normalizePresentStringArray(entry.restartRecoveryDeliveryMediaUrls);
assign("restartRecoveryDeliveryMediaUrls", sameOptionalStringArray(entry.restartRecoveryDeliveryMediaUrls, deliveryMediaUrls) ? entry.restartRecoveryDeliveryMediaUrls : deliveryMediaUrls);
assign("restartRecoveryDisableMessageTool", entry.restartRecoveryDisableMessageTool === true ? true : void 0);
assign("restartRecoverySuppressTextDelivery", entry.restartRecoverySuppressTextDelivery === true ? true : void 0);
assign("restartRecoveryBeforeAgentReplyState", entry.restartRecoveryBeforeAgentReplyState === "admitted" || entry.restartRecoveryBeforeAgentReplyState === "pending" || entry.restartRecoveryBeforeAgentReplyState === "continue" || entry.restartRecoveryBeforeAgentReplyState === "handled-silent" || entry.restartRecoveryBeforeAgentReplyState === "handled-reply" || entry.restartRecoveryBeforeAgentReplyState === "handled-unrecoverable" ? entry.restartRecoveryBeforeAgentReplyState : void 0);
assign("restartRecoveryDeliveryReceiptState", entry.restartRecoveryDeliveryReceiptState === "terminal-pending" || entry.restartRecoveryDeliveryReceiptState === "delivered-terminal" ? entry.restartRecoveryDeliveryReceiptState : void 0);
assign("restartRecoveryDeliveryToolCallId", normalizeOptionalString(entry.restartRecoveryDeliveryToolCallId));
assign("restartRecoveryDeliveryRequestFingerprint", normalizeOptionalString(entry.restartRecoveryDeliveryRequestFingerprint));
assign("restartRecoveryDeliveryRunId", normalizeOptionalString(entry.restartRecoveryDeliveryRunId));
assign("restartRecoveryDeliverySourceRunId", normalizeOptionalString(entry.restartRecoveryDeliverySourceRunId));
assign("restartRecoveryRequesterAccountId", normalizeOptionalString(entry.restartRecoveryRequesterAccountId));
assign("restartRecoveryRequesterSenderId", normalizeOptionalString(entry.restartRecoveryRequesterSenderId));
assign("restartRecoverySameChannelThreadRequired", entry.restartRecoverySameChannelThreadRequired === true ? true : void 0);
assign("restartRecoverySourceIngress", entry.restartRecoverySourceIngress === "channel" || entry.restartRecoverySourceIngress === "control-ui" || entry.restartRecoverySourceIngress === "internal" ? entry.restartRecoverySourceIngress : void 0);
assign("restartRecoverySourceReplyDeliveryMode", entry.restartRecoverySourceReplyDeliveryMode === "automatic" || entry.restartRecoverySourceReplyDeliveryMode === "message_tool_only" ? entry.restartRecoverySourceReplyDeliveryMode : void 0);
const terminalDeliveryEvidence = normalizeRestartRecoveryTerminalDeliveryEvidence(entry.restartRecoveryTerminalDeliveryEvidence);
assign("restartRecoveryTerminalDeliveryEvidence", isDeepStrictEqual(entry.restartRecoveryTerminalDeliveryEvidence, terminalDeliveryEvidence) ? entry.restartRecoveryTerminalDeliveryEvidence : terminalDeliveryEvidence);
const terminalRunIds = normalizeRestartRecoveryTerminalRunIds(entry.restartRecoveryTerminalRunIds);
assign("restartRecoveryTerminalRunIds", sameOptionalStringArray(entry.restartRecoveryTerminalRunIds, terminalRunIds) ? entry.restartRecoveryTerminalRunIds : terminalRunIds);
}
function mergeRestartRecoveryTerminalDeliveryEvidence(current, appended) {
return normalizeRestartRecoveryTerminalDeliveryEvidence([...normalizeRestartRecoveryTerminalDeliveryEvidence(current) ?? [], ...normalizeRestartRecoveryTerminalDeliveryEvidence(appended) ?? []]);
}
function getRestartRecoveryTerminalDeliveryEvidence(entry, runId) {
return normalizeRestartRecoveryTerminalDeliveryEvidence(entry?.restartRecoveryTerminalDeliveryEvidence)?.find((evidence) => evidence.runId === runId);
}
/** Appends new terminal ids without refreshing or evicting existing members. */
function mergeRestartRecoveryTerminalRunIds(current, appended) {
const currentRunIds = normalizeRestartRecoveryTerminalRunIds(current) ?? [];
const currentSet = new Set(currentRunIds);
const appendedRunIds = (normalizeRestartRecoveryTerminalRunIds(appended) ?? []).filter((runId) => !currentSet.has(runId));
return normalizeRestartRecoveryTerminalRunIds([...currentRunIds, ...appendedRunIds]);
}
function hasRestartRecoveryTerminalRun(entry, runId) {
return normalizeRestartRecoveryTerminalRunIds(entry?.restartRecoveryTerminalRunIds)?.includes(runId) === true;
}
/** Matches durable source ownership regardless of the surrounding run status. */
function hasRestartRecoverySourceClaim(entry, sourceTurnId) {
const normalizedSourceTurnId = normalizeOptionalString(sourceTurnId);
return normalizedSourceTurnId !== void 0 && normalizeOptionalString(entry?.restartRecoveryDeliveryRunId) !== void 0 && normalizeOptionalString(entry?.restartRecoveryDeliverySourceRunId) === normalizedSourceTurnId;
}
function hasActiveRestartRecoverySourceClaim(entry, sourceTurnId) {
return entry?.status === "running" && hasRestartRecoverySourceClaim(entry, sourceTurnId);
}
/** Clears exact active ownership and optionally records its client source as terminal. */
function buildRestartRecoveryClaimCleanupPatch(params) {
const sourceRunId = normalizeOptionalString(params.terminalSourceRunId) ?? normalizeOptionalString(params.entry.restartRecoveryDeliverySourceRunId);
const terminalRunIds = params.recordTerminalSource && (sourceRunId || params.terminalRunId) ? mergeRestartRecoveryTerminalRunIds(params.entry.restartRecoveryTerminalRunIds, [...sourceRunId ? [sourceRunId] : [], ...params.terminalRunId ? [params.terminalRunId] : []]) : void 0;
const terminalDeliveryEvidence = params.recordTerminalSource && sourceRunId && params.terminalDeliveryEvidence ? mergeRestartRecoveryTerminalDeliveryEvidence(params.entry.restartRecoveryTerminalDeliveryEvidence, [{
runId: sourceRunId,
...params.terminalDeliveryEvidence
}]) : void 0;
return {
restartRecoveryBeforeAgentReplyState: void 0,
restartRecoveryDeliveryReceiptState: void 0,
restartRecoveryDeliveryToolCallId: void 0,
restartRecoveryDeliveryContext: void 0,
restartRecoveryDeliveryMediaUrls: void 0,
restartRecoveryDisableMessageTool: void 0,
restartRecoverySuppressTextDelivery: void 0,
restartRecoveryDeliveryRequestFingerprint: void 0,
restartRecoveryDeliveryRunId: void 0,
restartRecoveryDeliverySourceRunId: void 0,
restartRecoveryRequesterAccountId: void 0,
restartRecoveryRequesterSenderId: void 0,
restartRecoverySameChannelThreadRequired: void 0,
restartRecoverySourceIngress: void 0,
restartRecoverySourceReplyDeliveryMode: void 0,
restartRecoveryForceSafeTools: void 0,
...terminalDeliveryEvidence ? { restartRecoveryTerminalDeliveryEvidence: terminalDeliveryEvidence } : {},
...terminalRunIds ? { restartRecoveryTerminalRunIds: terminalRunIds } : {}
};
}
//#endregion
export { hasRestartRecoveryTerminalRun as a, resolveRestartRecoveryChannelAuthority as c, hasRestartRecoverySourceClaim as i, sameRestartRecoveryTerminalRunIds as l, getRestartRecoveryTerminalDeliveryEvidence as n, mergeRestartRecoveryTerminalRunIds as o, hasActiveRestartRecoverySourceClaim as r, normalizeRestartRecoveryEntryFields as s, buildRestartRecoveryClaimCleanupPatch as t };