UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

132 lines (131 loc) 4.71 kB
import { n as resolveGlobalMap } from "./global-singleton-Dc_stLtU.js"; import { s as removeRemoteNodeInfo } from "./remote-D-j1AEXQ.js"; import { a as reconcileDeviceWorker } from "./device-provider-BjFBZG2n.js"; import { t as clearNodePendingWork } from "./node-pending-work-B-emncmK.js"; import { a as invalidateNodeWakeState } from "./node-wake-state-CWVR-GCk.js"; import { randomUUID } from "node:crypto"; //#region src/gateway/device-worker-revocation.ts async function reconcileRevokedDeviceWorker(context, deviceId) { const environmentIds = await reconcileDeviceWorker(context.workerEnvironmentService, deviceId); for (const environmentId of environmentIds) try { await context.workerPlacementDispatchService?.reconcileActive?.(environmentId); } catch { context.logGateway.warn(`device worker placement reconciliation failed device=${deviceId} environment=${environmentId}`); } } //#endregion //#region src/gateway/node-runtime-state.ts const pendingNodeActionsById = resolveGlobalMap(Symbol.for("openclaw.pendingNodeActions"), "close-and-restart"); function prunePendingNodeActions(params) { const queue = pendingNodeActionsById.get(params.nodeId) ?? []; const minTimestampMs = params.nowMs - params.ttlMs; const live = queue.filter((entry) => entry.enqueuedAtMs >= minTimestampMs); if (live.length === 0) { pendingNodeActionsById.delete(params.nodeId); return []; } pendingNodeActionsById.set(params.nodeId, live); return params.pairingGeneration ? live.filter((entry) => entry.pairingGeneration === params.pairingGeneration) : live; } function replacePendingNodeActionsForGeneration(params) { const next = [...prunePendingNodeActions({ nodeId: params.nodeId, nowMs: params.nowMs ?? Date.now(), ttlMs: params.ttlMs }).filter((entry) => entry.pairingGeneration !== params.pairingGeneration), ...params.replacement]; if (next.length === 0) { pendingNodeActionsById.delete(params.nodeId); return; } pendingNodeActionsById.set(params.nodeId, next); } function enqueuePendingNodeAction(params) { const nowMs = params.nowMs ?? Date.now(); const queue = prunePendingNodeActions({ nodeId: params.nodeId, nowMs, ttlMs: params.ttlMs, pairingGeneration: params.pairingGeneration }); const existing = queue.find((entry) => entry.idempotencyKey === params.idempotencyKey); if (existing) return { action: existing, created: false }; const action = { id: randomUUID(), nodeId: params.nodeId, pairingGeneration: params.pairingGeneration, command: params.command, paramsJSON: params.paramsJSON, idempotencyKey: params.idempotencyKey, enqueuedAtMs: nowMs }; queue.push(action); if (queue.length > params.maxPerNode) queue.splice(0, queue.length - params.maxPerNode); replacePendingNodeActionsForGeneration({ nodeId: params.nodeId, pairingGeneration: params.pairingGeneration, replacement: queue, ttlMs: params.ttlMs, nowMs }); return { action, created: true }; } function listPendingNodeActions(params) { return prunePendingNodeActions({ nodeId: params.nodeId, nowMs: params.nowMs ?? Date.now(), ttlMs: params.ttlMs, pairingGeneration: params.pairingGeneration }); } function acknowledgePendingNodeActions(params) { const pending = prunePendingNodeActions({ nodeId: params.nodeId, pairingGeneration: params.pairingGeneration, nowMs: Date.now(), ttlMs: params.ttlMs }); if (params.ids.length === 0) return pending; const ids = new Set(params.ids); const remaining = pending.filter((entry) => !ids.has(entry.id)); replacePendingNodeActionsForGeneration({ ...params, replacement: remaining }); return remaining; } function removePendingNodeAction(params) { const pending = prunePendingNodeActions({ nodeId: params.nodeId, pairingGeneration: params.pairingGeneration, nowMs: Date.now(), ttlMs: params.ttlMs }); const remaining = pending.filter((entry) => entry.id !== params.actionId); if (remaining.length === pending.length) return; replacePendingNodeActionsForGeneration({ ...params, replacement: remaining }); } function clearPendingNodeActions(nodeId) { pendingNodeActionsById.delete(nodeId); } function clearRemovedNodeRuntimeState(params) { clearPendingNodeActions(params.nodeId); clearNodePendingWork(params.nodeId); invalidateNodeWakeState(params.nodeId); params.context.nodeRegistry.updateSurface(params.nodeId, { caps: [], commands: [], permissions: void 0 }); removeRemoteNodeInfo(params.nodeId); } //#endregion export { removePendingNodeAction as a, listPendingNodeActions as i, clearRemovedNodeRuntimeState as n, replacePendingNodeActionsForGeneration as o, enqueuePendingNodeAction as r, reconcileRevokedDeviceWorker as s, acknowledgePendingNodeActions as t };