UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

154 lines (153 loc) 7.27 kB
import { a as addTimerTimeoutGraceMs } from "./number-coercion-CLj0HTDM.js"; import { i as resolveGlobalSingleton } from "./global-singleton-Dc_stLtU.js"; import { t as createAbortError } from "./abort-signal-D2k14JsD.js"; import { n as captureAgentRunLifecycleGeneration, t as assertAgentRunLifecycleGenerationCurrent } from "./agent-events-CoxiItUi.js"; import { S as retainQueuedAgentRunContext } from "./agent-run-registry-CKYKdfNd.js"; import { u as isMainSessionRestartRecoveryInputProvenance } from "./input-provenance-DiG-Cwnd.js"; import { t as DEFAULT_AGENT_TIMEOUT_MS } from "./timeout-Dm7mxETK.js"; import { P as resolveSessionPlacementTurnSettlementAssertion } from "./runs-Cb42qain.js"; import { c as isCommandLaneTaskMarkerCurrent, r as enqueueCommandInLane } from "./command-queue-C3Fv2rcU.js"; import { T as settleRequesterAfterSessionSpawns } from "./subagent-registry-BMJDw92y.js"; import { r as resolveSessionLane } from "./lanes-CVttd5qX.js"; import { n as registerAgentRunCapacityWait } from "./agent-run-capacity-wait-uKhiNyQF.js"; //#region src/agents/embedded-agent-runner/run/lane-runtime.ts const EMBEDDED_RUN_LANE_TIMEOUT_GRACE_MS = 3e4; function shouldNoteLaneWait(snapshot) { return snapshot.queuedCount > 0 || snapshot.activeCount >= snapshot.maxConcurrent || snapshot.blockedBy != null; } function resolveEmbeddedRunLaneTimeoutMs(timeoutMs) { const defaultLaneTimeoutMs = DEFAULT_AGENT_TIMEOUT_MS + EMBEDDED_RUN_LANE_TIMEOUT_GRACE_MS; if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs >= 2147e6) return defaultLaneTimeoutMs; return addTimerTimeoutGraceMs(Math.floor(timeoutMs), 3e4) ?? defaultLaneTimeoutMs; } function withEmbeddedRunLaneTimeout(opts, laneTaskTimeoutMs) { if (opts?.taskTimeoutMs !== void 0) return opts; return { ...opts, taskTimeoutMs: laneTaskTimeoutMs }; } function resolveEmbeddedRunSessionLanePolicy(trigger, inputProvenance) { let triggerPriority; switch (trigger) { case "user": case "manual": triggerPriority = "foreground"; break; case "cron": case "heartbeat": case "memory": case "overflow": triggerPriority = "background"; break; default: triggerPriority = "normal"; } const isRestartRecovery = isMainSessionRestartRecoveryInputProvenance(inputProvenance); return { priority: isRestartRecovery || inputProvenance?.kind === "inter_session" ? "background" : triggerPriority, canResumeAcrossRotation: !isRestartRecovery && triggerPriority === "foreground" }; } //#endregion //#region src/agents/session-placement-admission.ts const state = resolveGlobalSingleton(Symbol.for("openclaw.sessionPlacementAdmissionState"), () => ({})); function installSessionPlacementAdmissionProvider(provider) { state.provider = provider; return () => { if (state.provider === provider) state.provider = void 0; }; } /** Captures the exact placement owner, including standalone absence, before awaited work. */ function captureSessionPlacementCompactionSuccessorAssertion() { const provider = state.provider; return (params) => { if (state.provider !== provider) throw new Error("session placement owner changed during compaction successor acceptance"); provider?.assertCompactionSuccessorAllowed(params); }; } async function withSessionPlacementTurnAdmission(claim, params, task, onAdmitted) { let admitted = false; const admitTurn = () => { if (admitted) return; admitted = true; onAdmitted?.(); }; const runAdmittedLocalTurn = () => { admitTurn(); return task(); }; const provider = state.provider; const result = provider ? await provider.executeTurn(claim, params, runAdmittedLocalTurn, admitTurn) : await runAdmittedLocalTurn(); if (result.meta.executionTrace?.runner === "cli") settleYieldedRequesterAfterPlacementRelease(claim, result); return result; } /** Serializes direct CLI turns with every runtime before acquiring placement ownership. */ async function withLocalSessionPlacementTurnSettlement(claim, task, options = {}) { const provider = state.provider; const lifecycleGeneration = options.lifecycleGeneration ?? captureAgentRunLifecycleGeneration(claim.runId); const assertOwnerCurrent = () => { assertAgentRunLifecycleGenerationCurrent(lifecycleGeneration); if (state.provider !== provider) throw createAbortError("session placement owner changed during turn admission"); }; const assertCurrent = () => { if (options.abortSignal?.aborted) throw options.abortSignal.reason instanceof Error ? options.abortSignal.reason : createAbortError("Operation aborted", { cause: options.abortSignal.reason }); assertOwnerCurrent(); }; assertCurrent(); const releaseQueuedContext = retainQueuedAgentRunContext(claim.runId, lifecycleGeneration); let releaseCapacityWait; try { return await enqueueCommandInLane(resolveSessionLane(claim.sessionKey?.trim() || claim.sessionId), async (taskMarker) => { assertCurrent(); const runLocal = async () => { assertCurrent(); const assertClaimCurrent = resolveSessionPlacementTurnSettlementAssertion(); let open = true; const assertSettlementCurrent = () => { if (!open || !isCommandLaneTaskMarkerCurrent(taskMarker)) throw createAbortError("session placement turn settlement is closed"); assertOwnerCurrent(); assertClaimCurrent?.(); }; try { assertSettlementCurrent(); releaseCapacityWait?.(); releaseQueuedContext?.("admitted"); return await task(assertSettlementCurrent); } finally { open = false; } }; const result = provider ? await provider.executeLocalTurn(claim, runLocal) : await runLocal(); settleYieldedRequesterAfterPlacementRelease(claim, result); return result; }, { priority: resolveEmbeddedRunSessionLanePolicy(options.trigger, options.inputProvenance).priority, onQueued: () => { releaseCapacityWait = registerAgentRunCapacityWait(claim.runId, lifecycleGeneration); } }); } finally { releaseCapacityWait?.(); releaseQueuedContext?.("abandoned"); } } function settleYieldedRequesterAfterPlacementRelease(claim, result) { if (!claim.sessionKey || result.meta.yielded !== true || !result.acceptedSessionSpawns?.length) return; settleRequesterAfterSessionSpawns({ requesterSessionKey: claim.sessionKey, requesterAgentId: claim.agentId, requesterTurnRunId: claim.runId, requesterYielded: true, acceptedSessionSpawns: result.acceptedSessionSpawns }); } /** Resolves an authoritative sandbox only when the live placement owns remote execution. */ async function resolveSessionPlacementSandbox(params) { return await state.provider?.resolveSandbox?.(params) ?? null; } /** The current placement owner alone can settle a proven terminal worker turn. */ function recoverTerminalSessionPlacementTurn(session) { return state.provider?.recoverTerminalTurn?.(session); } //#endregion export { withLocalSessionPlacementTurnSettlement as a, resolveEmbeddedRunLaneTimeoutMs as c, withEmbeddedRunLaneTimeout as d, resolveSessionPlacementSandbox as i, resolveEmbeddedRunSessionLanePolicy as l, installSessionPlacementAdmissionProvider as n, withSessionPlacementTurnAdmission as o, recoverTerminalSessionPlacementTurn as r, EMBEDDED_RUN_LANE_TIMEOUT_GRACE_MS as s, captureSessionPlacementCompactionSuccessorAssertion as t, shouldNoteLaneWait as u };