UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

118 lines (117 loc) 4.61 kB
import { g as readStringValue } from "./string-coerce-CIXf7egm.js"; import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js"; import { i as emitAgentEvent } from "./agent-events-CoxiItUi.js"; import { a as classifyOAuthRefreshFailureError } from "./oauth-refresh-failure-DP-bO7C0.js"; import { i as getFailoverErrorCode } from "./error-Bb_OF8ag.js"; import { i as AGENT_RUN_RESTART_ABORT_STOP_REASON } from "./run-termination-jabvTOp5.js"; import { v as renderFailoverCodeUserCopy } from "./user-copy-CxiPNpae.js"; //#region src/auto-reply/reply/agent-lifecycle-terminal.ts const DEFERRED_TERMINAL_METADATA_KEYS = [ "stopReason", "yielded", "timeoutPhase", "providerStarted", "aborted", "livenessState", "replayInvalid", "errorObservation" ]; function resolveAgentLifecycleTerminalMetadata(meta) { const metadata = {}; if (!meta || typeof meta !== "object") return metadata; const record = meta; for (const key of DEFERRED_TERMINAL_METADATA_KEYS) if (Object.hasOwn(record, key)) metadata[key] = record[key]; return metadata; } function createAgentLifecycleTerminalBackstop(params) { let state = { kind: "pending", metadata: {} }; let startedAt = params.startedAt ?? Date.now(); const beginAttempt = () => { if (state.kind !== "emitted") state = { kind: "pending", metadata: {} }; }; const note = (evt) => { if (state.kind === "emitted" || evt.stream !== "lifecycle") return; const phase = readStringValue(evt.data.phase); if (phase === "start") { beginAttempt(); if (typeof evt.data.startedAt === "number") startedAt = evt.data.startedAt; } if (phase === "finishing" && state.kind === "pending") { state.deferredError = readStringValue(evt.data.error) ?? state.deferredError; Object.assign(state.metadata, resolveAgentLifecycleTerminalMetadata(evt.data)); } if (phase === "end" || phase === "error") state = { kind: "emitted" }; }; const prepareTerminal = (pending, phase, resultOrError, extraData) => { const terminationFields = params.resolveTerminationFields(phase === "error" ? resultOrError : void 0); const restartAbort = terminationFields.stopReason === AGENT_RUN_RESTART_ABORT_STOP_REASON; const data = { ...pending.metadata, phase: restartAbort ? "end" : phase, endedAt: Date.now(), startedAt }; if (restartAbort) { data.aborted = true; data.stopReason = AGENT_RUN_RESTART_ABORT_STOP_REASON; } else if (phase === "error") { const oauthFailure = classifyOAuthRefreshFailureError(resultOrError); data.error = renderFailoverCodeUserCopy(getFailoverErrorCode(resultOrError)) ?? (oauthFailure?.summary ? `⚠️ ${oauthFailure.summary}` : void 0) ?? formatErrorMessage(resultOrError); if (oauthFailure?.summary) data.errorObservation = { ...oauthFailure.provider ? { provider: oauthFailure.provider } : {}, ...oauthFailure.reason ? { failoverReason: oauthFailure.reason } : {}, providerRuntimeFailureKind: "auth_refresh", ...oauthFailure.errorType ? { providerErrorType: oauthFailure.errorType } : {}, ...oauthFailure.status ? { httpStatus: oauthFailure.status } : {} }; Object.assign(data, terminationFields); } else { const meta = resultOrError && typeof resultOrError === "object" && "meta" in resultOrError ? resultOrError.meta : void 0; Object.assign(data, resolveAgentLifecycleTerminalMetadata(meta)); if (terminationFields.aborted === true) data.aborted = true; if (terminationFields.stopReason && !readStringValue(data.stopReason)) data.stopReason = terminationFields.stopReason; } if (extraData) Object.assign(data, extraData); return { runId: params.runId, lifecycleGeneration: params.getLifecycleGeneration(), ...params.sessionKey ? { sessionKey: params.sessionKey } : {}, stream: "lifecycle", data }; }; const capture = (phase, resultOrError, extraData) => { if (state.kind === "pending") state = { kind: "captured", event: prepareTerminal(state, phase, resultOrError, extraData) }; }; const emit = (phase, resultOrError, extraData) => { const current = state; if (current.kind === "emitted") return; state = { kind: "emitted" }; const event = current.kind === "captured" ? current.event : prepareTerminal(current, phase, resultOrError, extraData); emitAgentEvent({ ...event, data: { ...event.data, executionSettled: true } }); }; return { beginAttempt, capture, emit, getDeferredError: () => state.kind === "pending" ? state.deferredError : void 0, note }; } //#endregion export { resolveAgentLifecycleTerminalMetadata as n, createAgentLifecycleTerminalBackstop as t };