

















@@ -339,6 +339,7 @@ import {
339339shouldInjectHeartbeatPrompt,
340340} from "./attempt.prompt-helpers.js";
341341import {
342+EmbeddedAttemptSessionTakeoverError,
342343createEmbeddedAttemptSessionLockController,
343344installPromptSubmissionLockRelease,
344345installSessionExternalHookWriteLock,
@@ -1060,6 +1061,28 @@ export function shouldRunLlmOutputHooksForAttempt(params: { promptErrorSource: s
10601061return params.promptErrorSource !== "hook:before_agent_run";
10611062}
106210631064+function shouldPreservePromptErrorAfterCleanupError(params: {
1065+promptError: unknown;
1066+cleanupError: unknown;
1067+}): boolean {
1068+return (
1069+Boolean(params.promptError) &&
1070+params.cleanupError instanceof EmbeddedAttemptSessionTakeoverError
1071+);
1072+}
1073+1074+class EmbeddedAttemptPromptErrorWithCleanupTakeoverError extends Error {
1075+readonly promptError: unknown;
1076+readonly cleanupError: EmbeddedAttemptSessionTakeoverError;
1077+1078+constructor(params: { promptError: unknown; cleanupError: EmbeddedAttemptSessionTakeoverError }) {
1079+super(formatErrorMessage(params.promptError), { cause: params.cleanupError });
1080+this.name = "EmbeddedAttemptSessionTakeoverError";
1081+this.promptError = params.promptError;
1082+this.cleanupError = params.cleanupError;
1083+}
1084+}
1085+10631086function hasVisiblePendingToolMediaReply(
10641087reply: { mediaUrls?: string[]; audioAsVoice?: boolean } | null | undefined,
10651088): boolean {
@@ -5173,8 +5196,17 @@ export async function runEmbeddedAttempt(
51735196} catch (err) {
51745197cleanupError = err;
51755198}
5199+const synthesizedCleanupTakeoverError =
5200+!cleanupError && promptError && sessionLockController.hasSessionTakeover()
5201+ ? new EmbeddedAttemptSessionTakeoverError(params.sessionFile)
5202+ : undefined;
5203+const cleanupFailure = cleanupError ?? synthesizedCleanupTakeoverError;
5204+const shouldPreservePromptError = shouldPreservePromptErrorAfterCleanupError({
5205+ promptError,
5206+cleanupError: cleanupFailure,
5207+});
51765208emitDiagnosticRunCompleted?.(
5177-cleanupError
5209+cleanupFailure
51785210 ? "error"
51795211 : beforeAgentRunBlocked
51805212 ? "blocked"
@@ -5183,13 +5215,27 @@ export async function runEmbeddedAttempt(
51835215 : aborted || timedOut || idleTimedOut || timedOutDuringCompaction
51845216 ? "aborted"
51855217 : "completed",
5186-cleanupError ?? promptError,
5218+shouldPreservePromptError ? promptError : (cleanupFailure ?? promptError),
51875219beforeAgentRunBlocked
51885220 ? { blockedBy: beforeAgentRunBlockedBy ?? "before_agent_run" }
51895221 : undefined,
51905222);
5191-if (cleanupError) {
5192-await Promise.reject(cleanupError);
5223+if (cleanupFailure) {
5224+if (shouldPreservePromptError) {
5225+log.warn(
5226+`embedded attempt cleanup detected session takeover after prompt failure; preserving prompt error: ` +
5227+`runId=${params.runId} sessionId=${params.sessionId} ` +
5228+`promptError=${formatErrorMessage(promptError)} cleanupError=${formatErrorMessage(cleanupFailure)}`,
5229+);
5230+await Promise.reject(
5231+new EmbeddedAttemptPromptErrorWithCleanupTakeoverError({
5232+ promptError,
5233+cleanupError: cleanupFailure as EmbeddedAttemptSessionTakeoverError,
5234+}),
5235+);
5236+} else {
5237+await Promise.reject(cleanupFailure);
5238+}
51935239}
51945240}
51955241} finally {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。