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