openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
287 lines (286 loc) • 14.8 kB
JavaScript
import { m as readNonBlankString } from "./string-coerce-1VuiLaaR.mjs";
import { s as asFiniteNumber } from "./number-coercion-CuVhdCBs.mjs";
import { t as formatErrorMessage } from "./errors-O33D01XW.mjs";
import { d as resolveAgentRunTerminalFacts, f as resolveAgentRunWaitTerminalFacts, u as resolveAgentRunLifecycleTerminalFacts } from "./agent-run-terminal-outcome-Ccvy5spR.mjs";
import { d as isAgentRunSupersededAbortReason, p as resolveAgentRunAbortLifecycleFields, t as AGENT_RUN_ABORTED_ERROR, u as isAgentRunRestartAbortReason } from "./run-termination-DGv2EKii.mjs";
//#region src/shared/agent-liveness.ts
function isBlockedLivenessState(livenessState) {
return typeof livenessState === "string" && livenessState.trim().toLowerCase() === "blocked";
}
function isAbandonedLivenessState(livenessState) {
return typeof livenessState === "string" && livenessState.trim().toLowerCase() === "abandoned";
}
function formatBlockedLivenessError(error) {
return (typeof error === "string" ? error.trim() : "") || "Agent run blocked before producing a usable result.";
}
function formatAbandonedLivenessError(error) {
return (typeof error === "string" ? error.trim() : "") || "Agent run ended before producing a complete result.";
}
/** Coerce any blocked liveness state into an error status while preserving other statuses. */
function normalizeBlockedLivenessWaitStatus(params) {
const error = typeof params.error === "string" ? params.error : void 0;
if (!isBlockedLivenessState(params.livenessState)) return {
status: params.status,
error
};
return {
status: "error",
error: formatBlockedLivenessError(error)
};
}
//#endregion
//#region src/agents/agent-run-terminal-outcome.ts
/** Normalizes agent run wait/liveness/timeout metadata into sticky terminal outcomes. */
const ATTEMPT_TERMINAL_KIND_RANK = {
ok: 0,
failed: 1,
aborted: 2,
timeout: 3
};
const ATTEMPT_TIMEOUT_PHASE_RANK = {
prompt: 0,
tool_execution: 1,
compaction: 2
};
const ATTEMPT_TIMEOUT_SOURCE_RANK = {
observation: 0,
runtime: 1,
idle: 2,
run_budget: 3,
external: 4
};
const ATTEMPT_ABORT_SOURCE_RANK = {
yield_cleanup: 0,
runtime: 1,
external: 2
};
function mergeAgentRunAttemptTimeoutPhase(phase, observation) {
return observation && ATTEMPT_TIMEOUT_PHASE_RANK[observation] > ATTEMPT_TIMEOUT_PHASE_RANK[phase] ? observation : phase;
}
function getAgentRunAttemptFailure(terminal) {
return terminal.kind === "failed" ? {
source: terminal.source,
error: terminal.error
} : terminal.kind === "ok" ? void 0 : terminal.failure;
}
function withAgentRunAttemptFailure(terminal, failure) {
if (!failure || terminal.kind === "ok") return terminal;
if (terminal.kind === "failed") return {
...terminal,
...failure
};
return {
...terminal,
failure
};
}
function withAgentRunAttemptTimeoutObservation(terminal, phase) {
const timeoutObservation = terminal.timeoutObservation === "compaction" || phase === "compaction" ? "compaction" : "tool_execution";
return {
...terminal,
timeoutObservation
};
}
function hasAgentRunAttemptTimeoutAbort(terminal) {
return terminal.kind === "timeout" && terminal.source !== "observation" && terminal.aborted === true;
}
function mergeAgentRunAttemptTimeoutInterruption(timeout, interruption) {
if (timeout.source === "observation") return withAgentRunAttemptTimeoutObservation(interruption, timeout.phase);
return {
...timeout,
phase: mergeAgentRunAttemptTimeoutPhase(timeout.phase, interruption.timeoutObservation),
source: interruption.kind === "aborted" && interruption.source === "external" ? "external" : timeout.source,
...(interruption.kind === "aborted" && interruption.source !== "yield_cleanup" || timeout.aborted === true) && { aborted: true }
};
}
/** Replaces attempt failure detail without changing a stronger interruption. */
function setAgentRunAttemptTerminalFailure(terminal, failure) {
if (!failure) {
if (terminal.kind === "failed") return terminal.timeoutObservation ? {
kind: "timeout",
phase: terminal.timeoutObservation,
source: "observation"
} : { kind: "ok" };
if (terminal.kind === "aborted" || terminal.kind === "timeout") {
const { failure: _failure, ...withoutFailure } = terminal;
return withoutFailure;
}
return terminal;
}
if (terminal.kind === "timeout" && terminal.source === "observation") return {
kind: "failed",
...failure,
timeoutObservation: terminal.phase
};
if (terminal.kind === "failed" || terminal.kind === "ok") return {
kind: "failed",
...failure,
...terminal.kind === "failed" && terminal.timeoutObservation && { timeoutObservation: terminal.timeoutObservation }
};
return {
...terminal,
failure
};
}
/** Merges attempt observations while keeping terminal precedence in one owner. */
function mergeAgentRunAttemptTerminal(current, incoming) {
if (incoming.kind === "ok") return current.kind === "ok" && !current.settlementWarning ? incoming : current;
const failure = getAgentRunAttemptFailure(incoming) ?? getAgentRunAttemptFailure(current);
if (current.kind === "timeout" && incoming.kind === "timeout") {
const phase = ATTEMPT_TIMEOUT_PHASE_RANK[incoming.phase] > ATTEMPT_TIMEOUT_PHASE_RANK[current.phase] ? incoming.phase : current.phase;
const selected = ATTEMPT_TIMEOUT_SOURCE_RANK[incoming.source] > ATTEMPT_TIMEOUT_SOURCE_RANK[current.source] ? incoming : current;
if (selected.source === "observation") return withAgentRunAttemptFailure({
kind: "timeout",
phase: current.phase === "compaction" || incoming.phase === "compaction" ? "compaction" : "tool_execution",
source: "observation"
}, failure);
return withAgentRunAttemptFailure({
kind: "timeout",
phase,
source: selected.source,
...(hasAgentRunAttemptTimeoutAbort(current) || hasAgentRunAttemptTimeoutAbort(incoming)) && { aborted: true }
}, failure);
}
if ((current.kind === "aborted" || current.kind === "failed") && incoming.kind === "timeout") return withAgentRunAttemptFailure(mergeAgentRunAttemptTimeoutInterruption(incoming, current), failure);
if (current.kind === "timeout" && (incoming.kind === "aborted" || incoming.kind === "failed")) return withAgentRunAttemptFailure(mergeAgentRunAttemptTimeoutInterruption(current, incoming), failure);
if ((current.kind === "aborted" || current.kind === "failed") && (incoming.kind === "aborted" || incoming.kind === "failed")) {
let selected;
if (current.kind === "aborted" && incoming.kind === "aborted") selected = {
kind: "aborted",
source: ATTEMPT_ABORT_SOURCE_RANK[incoming.source] > ATTEMPT_ABORT_SOURCE_RANK[current.source] ? incoming.source : current.source
};
else selected = ATTEMPT_TERMINAL_KIND_RANK[incoming.kind] >= ATTEMPT_TERMINAL_KIND_RANK[current.kind] ? incoming : current;
for (const observation of [current.timeoutObservation, incoming.timeoutObservation]) if (observation) selected = withAgentRunAttemptTimeoutObservation(selected, observation);
return withAgentRunAttemptFailure(selected, failure);
}
return withAgentRunAttemptFailure(incoming, failure);
}
/** Normalizes the shipped harness result shape at the Plugin SDK boundary. */
function normalizeAgentRunAttemptTerminal(input) {
let terminal = {
kind: "ok",
...input.settlementWarning && { settlementWarning: input.settlementWarning }
};
if (input.aborted || input.externalAbort) terminal = mergeAgentRunAttemptTerminal(terminal, {
kind: "aborted",
source: input.externalAbort ? "external" : "runtime"
});
if (input.timedOut || input.idleTimedOut || input.timedOutByRunBudget) terminal = mergeAgentRunAttemptTerminal(terminal, {
kind: "timeout",
phase: input.timedOutDuringCompaction ? "compaction" : input.timedOutDuringToolExecution ? "tool_execution" : "prompt",
source: input.externalAbort ? "external" : input.timedOutByRunBudget ? "run_budget" : input.idleTimedOut ? "idle" : "runtime",
...(input.aborted || input.externalAbort) && { aborted: true }
});
else if (input.timedOutDuringCompaction || input.timedOutDuringToolExecution) terminal = mergeAgentRunAttemptTerminal(terminal, {
kind: "timeout",
phase: input.timedOutDuringCompaction ? "compaction" : "tool_execution",
source: "observation"
});
if (input.promptError !== null && input.promptError !== void 0) terminal = setAgentRunAttemptTerminalFailure(terminal, {
error: input.promptError,
source: input.promptErrorSource ?? "prompt"
});
return terminal;
}
/** Projects the closed attempt terminal into legacy event/meta fields. */
function projectAgentRunAttemptTerminal(terminal) {
const failure = getAgentRunAttemptFailure(terminal);
const externalAbort = (terminal.kind === "aborted" || terminal.kind === "timeout") && terminal.source === "external";
const timedOut = terminal.kind === "timeout" && terminal.source !== "observation";
return {
...terminal.kind === "ok" && terminal.settlementWarning && { settlementWarning: terminal.settlementWarning },
aborted: terminal.kind === "aborted" && terminal.source !== "yield_cleanup" || hasAgentRunAttemptTimeoutAbort(terminal),
cleanupYieldAborted: terminal.kind === "aborted" && terminal.source === "yield_cleanup",
externalAbort,
failed: failure !== void 0,
idleTimedOut: terminal.kind === "timeout" && terminal.source === "idle",
interrupted: externalAbort || timedOut,
promptError: failure ? failure.error : null,
promptErrorSource: failure?.source ?? null,
timedOut,
timedOutByRunBudget: terminal.kind === "timeout" && terminal.source === "run_budget",
timedOutDuringCompaction: terminal.kind === "timeout" && terminal.phase === "compaction" || (terminal.kind === "aborted" || terminal.kind === "failed") && terminal.timeoutObservation === "compaction",
timedOutDuringToolExecution: terminal.kind === "timeout" && terminal.phase === "tool_execution" || (terminal.kind === "aborted" || terminal.kind === "failed") && terminal.timeoutObservation === "tool_execution"
};
}
/** Shared grace window for terminal observations that may still be followed by a retry. */
const AGENT_RUN_TERMINAL_RETRY_GRACE_MS = 15e3;
/** True when an outcome should not be overwritten by ordinary later status. */
function isStickyAgentRunTerminalOutcome(outcome) {
return outcome?.reason === "hard_timeout" || outcome?.reason === "superseded" || outcome?.reason === "cancelled";
}
function formatAgentRunTerminalOutcome(facts, input) {
const { reason, status, ...metadata } = facts;
const rawError = input.error == null ? void 0 : readNonBlankString(formatErrorMessage(input.error));
const error = reason === "hard_timeout" ? rawError : isBlockedLivenessState(facts.livenessState) ? formatBlockedLivenessError(rawError) : reason === "aborted" && !rawError ? AGENT_RUN_ABORTED_ERROR : reason === "superseded" || reason === "aborted" || reason === "cancelled" ? rawError : isAbandonedLivenessState(facts.livenessState) ? formatAbandonedLivenessError(rawError) : rawError;
return {
reason,
status,
...error ? { error } : {},
...metadata,
...asFiniteNumber(input.startedAt) !== void 0 ? { startedAt: asFiniteNumber(input.startedAt) } : {},
...asFiniteNumber(input.endedAt) !== void 0 ? { endedAt: asFiniteNumber(input.endedAt) } : {}
};
}
/** Builds the normalized terminal outcome from raw run status metadata. */
function buildAgentRunTerminalOutcome(input) {
return formatAgentRunTerminalOutcome(resolveAgentRunTerminalFacts(input), input);
}
/** Builds the canonical outcome directly from a terminal lifecycle event. */
function buildAgentRunTerminalOutcomeFromLifecycleEvent(input) {
const data = input.data;
const abortFields = typeof data?.aborted === "boolean" ? {} : resolveAgentRunAbortLifecycleFields(input.abortSignal);
return formatAgentRunTerminalOutcome(resolveAgentRunLifecycleTerminalFacts({
phase: input.phase,
data,
abortFields
}), {
error: data?.error,
startedAt: input.startedAt ?? data?.startedAt,
endedAt: input.endedAt ?? data?.endedAt
});
}
function hasNestedAbortReason(value, matches) {
let candidate = value;
for (let depth = 0; depth < 3; depth += 1) {
if (matches(candidate)) return true;
if (!(candidate instanceof Error)) return false;
try {
if (candidate.cause === void 0) return false;
candidate = candidate.cause;
} catch {
return false;
}
}
return false;
}
/** Maps the closed embedded-attempt terminal into the canonical run outcome. */
function buildAgentRunTerminalOutcomeFromAttempt(input) {
const projected = projectAgentRunAttemptTerminal(input.terminal);
const assistant = projected.cleanupYieldAborted ? void 0 : input.assistant;
const abortFields = resolveAgentRunAbortLifecycleFields(input.abortSignal);
const timedOut = projected.timedOut || abortFields.stopReason === "timeout";
const timedOutDuringPrompt = projected.timedOut && input.terminal.kind === "timeout" && input.terminal.phase === "prompt";
const timeoutPhase = input.promptTimeoutOutcome?.timeoutPhase ?? (timedOutDuringPrompt ? "provider" : void 0);
const providerStarted = input.promptTimeoutOutcome?.providerStarted ?? (timedOutDuringPrompt ? true : void 0);
const restartAborted = hasNestedAbortReason(projected.promptError, isAgentRunRestartAbortReason);
const superseded = hasNestedAbortReason(projected.promptError, isAgentRunSupersededAbortReason);
const assistantStopReason = projected.promptErrorSource !== null ? void 0 : assistant?.stopReason;
const stopReason = projected.timedOut && timeoutPhase === void 0 && providerStarted !== true ? void 0 : (superseded ? "superseded" : void 0) ?? abortFields.stopReason ?? (restartAborted ? "restart" : void 0) ?? (!timedOut && projected.aborted ? "aborted" : void 0) ?? (!timedOut ? assistantStopReason : void 0);
return buildAgentRunTerminalOutcome({
status: timedOut ? "timeout" : abortFields.aborted || projected.aborted || projected.promptErrorSource !== null || assistantStopReason === "error" ? "error" : "ok",
error: projected.promptErrorSource !== null ? projected.promptError : assistant?.errorMessage,
stopReason,
livenessState: input.promptTimeoutOutcome?.livenessState,
timeoutPhase,
providerStarted
});
}
/** Builds a terminal outcome from wait paths where status may still be pending/unknown. */
function buildAgentRunTerminalOutcomeFromWaitResult(wait) {
if (!wait) return;
const facts = resolveAgentRunWaitTerminalFacts(wait);
return facts ? formatAgentRunTerminalOutcome(facts, wait) : void 0;
}
//#endregion
export { buildAgentRunTerminalOutcomeFromWaitResult as a, normalizeAgentRunAttemptTerminal as c, normalizeBlockedLivenessWaitStatus as d, buildAgentRunTerminalOutcomeFromLifecycleEvent as i, projectAgentRunAttemptTerminal as l, buildAgentRunTerminalOutcome as n, isStickyAgentRunTerminalOutcome as o, buildAgentRunTerminalOutcomeFromAttempt as r, mergeAgentRunAttemptTerminal as s, AGENT_RUN_TERMINAL_RETRY_GRACE_MS as t, setAgentRunAttemptTerminalFailure as u };