openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
53 lines (52 loc) • 3.79 kB
JavaScript
import { o as execRequestMatches, r as cancelExecRequestOwners, s as readExecRequestOwners, t as activeExecRequestOwners } from "./exec-request-context-u4rNuPjF.mjs";
import { h as peekExecRequestSystemEventEntries, r as consumeSelectedSystemEventEntries } from "./system-events-GQMoAcQt.mjs";
import { T as waitForExecSession, b as removeNotifyOnExit, f as listExecSessionsForCancellation, l as getSession } from "./bash-process-registry-CI4nrAyM.mjs";
import { t as getProcessSupervisor } from "./supervisor-DLkAGOz1.mjs";
//#region src/agents/bash-process-control.ts
function isBackgroundExecCancellable(session) {
return Boolean(session?.backgrounded && !session.exited && !session.finalizing && session.processActivity && !session.processActivity.resultSettled);
}
function cancelBackgroundExecSession(sessionId) {
const session = getSession(sessionId);
if (!isBackgroundExecCancellable(session)) return false;
getProcessSupervisor().cancel(sessionId, "manual-cancel");
session.cancellationRequested = true;
return true;
}
/** A requested cancellation is successful only after its own terminal reason and cleanup. */
function isConfirmedRequestedStop(session) {
return session.cancellationRequested === true && session.exitReason === "manual-cancel" && session.finalizationFailed !== true;
}
/** Select before awaited cancellation work; a later human turn cannot enter this plan. */
function captureExecRequestCancellation(target, accept = () => true) {
const queued = peekExecRequestSystemEventEntries(target);
const initialSessions = listExecSessionsForCancellation();
const residualOwners = [...initialSessions.flatMap((session) => !session.exited || session.finalizing ? readExecRequestOwners(session) ?? [] : []), ...queued.flatMap(({ events }) => events.flatMap((event) => readExecRequestOwners(event) ?? []))].filter((owner) => execRequestMatches(owner, target) && accept(owner.identity));
const owners = /* @__PURE__ */ new Set([...activeExecRequestOwners(target, accept), ...residualOwners]);
const matching = (session) => readExecRequestOwners(session)?.some((owner) => owners.has(owner)) === true;
const capturedSessions = initialSessions.filter(matching);
let cancelled = false;
return {
owners: [...owners],
requestRunIds: [...new Set([...owners].flatMap((owner) => Array.from(owner.turnRunIds)))],
cancel() {
if (cancelled || owners.size === 0) return false;
cancelled = true;
cancelExecRequestOwners([...owners]);
for (const session of listExecSessionsForCancellation().filter(matching)) removeNotifyOnExit(session);
for (const { sessionKey, events } of queued) consumeSelectedSystemEventEntries(sessionKey, events.filter((event) => readExecRequestOwners(event)?.some((owner) => owners.has(owner))));
return true;
},
async settle() {
const stoppedOwners = new Set([...owners].filter((owner) => owner.signal.aborted));
if (stoppedOwners.size === 0) return;
const sessions = [.../* @__PURE__ */ new Set([...capturedSessions, ...listExecSessionsForCancellation()])].filter((session) => readExecRequestOwners(session)?.some((owner) => stoppedOwners.has(owner)));
const pending = sessions.map(waitForExecSession);
for (const owner of stoppedOwners) for (const settlement of owner.pendingProcesses) pending.push(settlement);
await Promise.all(pending);
if ([...stoppedOwners].some((owner) => owner.cleanupUncertain) || sessions.some((session) => session.finalizationFailed || session.cleanupUncertain)) throw new Error("Request stopped, but command cleanup could not be confirmed. Inspect its retained process output before retrying.");
}
};
}
//#endregion
export { isConfirmedRequestedStop as i, captureExecRequestCancellation as n, isBackgroundExecCancellable as r, cancelBackgroundExecSession as t };