Skip to content

Commit 050c779

Browse files
fix(clawsweeper): address review for automerge-openclaw-openclaw-84056 (1)
1 parent 9be6184 commit 050c779

2 files changed

Lines changed: 28 additions & 21 deletions

File tree

src/agents/pi-embedded-runner/run/attempt.spawn-workspace.context-engine.test.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,21 +1314,18 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => {
13141314
expectInitialLockReleasedBeforePostTurnWrite(lockEvents);
13151315
});
13161316

1317-
it("preserves provider prompt errors while carrying cleanup session takeover", async () => {
1317+
it("preserves provider prompt errors when cleanup reacquire detects session takeover", async () => {
13181318
const providerError = new Error("provider rejected request: HTTP 400");
1319-
let releasingCleanupLock = false;
1320-
let cleanupTakeover: EmbeddedAttemptSessionTakeoverError | undefined;
1321-
hoisted.flushPendingToolResultsAfterIdleMock.mockImplementation(async () => {
1322-
releasingCleanupLock = true;
1319+
let acquireCount = 0;
1320+
let cleanupReacquireSessionFile: string | undefined;
1321+
hoisted.acquireSessionWriteLockMock.mockImplementation(async (params) => {
1322+
acquireCount += 1;
1323+
if (acquireCount === 3) {
1324+
cleanupReacquireSessionFile = params.sessionFile;
1325+
await fs.appendFile(params.sessionFile, '{"type":"message","id":"takeover"}\n', "utf8");
1326+
}
1327+
return { release: async () => {} };
13231328
});
1324-
hoisted.acquireSessionWriteLockMock.mockImplementation(async (params) => ({
1325-
release: async () => {
1326-
if (releasingCleanupLock) {
1327-
cleanupTakeover = new EmbeddedAttemptSessionTakeoverError(params.sessionFile);
1328-
throw cleanupTakeover;
1329-
}
1330-
},
1331-
}));
13321329

13331330
const error = await createContextEngineAttemptRunner({
13341331
contextEngine: createContextEngineBootstrapAndAssemble(),
@@ -1342,8 +1339,13 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => {
13421339
expect(error).toBeInstanceOf(Error);
13431340
expect((error as Error).name).toBe("EmbeddedAttemptSessionTakeoverError");
13441341
expect((error as Error).message).toBe(providerError.message);
1345-
expect((error as Error).cause).toBe(cleanupTakeover);
1342+
expect((error as Error).cause).toBeInstanceOf(EmbeddedAttemptSessionTakeoverError);
1343+
if (!cleanupReacquireSessionFile) {
1344+
throw new Error("expected cleanup lock reacquire");
1345+
}
1346+
expect(((error as Error).cause as Error).message).toContain(cleanupReacquireSessionFile);
13461347
expect((error as { promptError?: unknown }).promptError).toBe(providerError);
1348+
expect(hoisted.flushPendingToolResultsAfterIdleMock).not.toHaveBeenCalled();
13471349
});
13481350

13491351
it("keeps cleanup session takeover fatal when no provider prompt error exists", async () => {

src/agents/pi-embedded-runner/run/attempt.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5196,12 +5196,17 @@ export async function runEmbeddedAttempt(
51965196
} catch (err) {
51975197
cleanupError = err;
51985198
}
5199+
const synthesizedCleanupTakeoverError =
5200+
!cleanupError && promptError && sessionLockController.hasSessionTakeover()
5201+
? new EmbeddedAttemptSessionTakeoverError(params.sessionFile)
5202+
: undefined;
5203+
const cleanupFailure = cleanupError ?? synthesizedCleanupTakeoverError;
51995204
const shouldPreservePromptError = shouldPreservePromptErrorAfterCleanupError({
52005205
promptError,
5201-
cleanupError,
5206+
cleanupError: cleanupFailure,
52025207
});
52035208
emitDiagnosticRunCompleted?.(
5204-
cleanupError
5209+
cleanupFailure
52055210
? "error"
52065211
: beforeAgentRunBlocked
52075212
? "blocked"
@@ -5210,26 +5215,26 @@ export async function runEmbeddedAttempt(
52105215
: aborted || timedOut || idleTimedOut || timedOutDuringCompaction
52115216
? "aborted"
52125217
: "completed",
5213-
shouldPreservePromptError ? promptError : (cleanupError ?? promptError),
5218+
shouldPreservePromptError ? promptError : (cleanupFailure ?? promptError),
52145219
beforeAgentRunBlocked
52155220
? { blockedBy: beforeAgentRunBlockedBy ?? "before_agent_run" }
52165221
: undefined,
52175222
);
5218-
if (cleanupError) {
5223+
if (cleanupFailure) {
52195224
if (shouldPreservePromptError) {
52205225
log.warn(
52215226
`embedded attempt cleanup detected session takeover after prompt failure; preserving prompt error: ` +
52225227
`runId=${params.runId} sessionId=${params.sessionId} ` +
5223-
`promptError=${formatErrorMessage(promptError)} cleanupError=${formatErrorMessage(cleanupError)}`,
5228+
`promptError=${formatErrorMessage(promptError)} cleanupError=${formatErrorMessage(cleanupFailure)}`,
52245229
);
52255230
await Promise.reject(
52265231
new EmbeddedAttemptPromptErrorWithCleanupTakeoverError({
52275232
promptError,
5228-
cleanupError: cleanupError as EmbeddedAttemptSessionTakeoverError,
5233+
cleanupError: cleanupFailure as EmbeddedAttemptSessionTakeoverError,
52295234
}),
52305235
);
52315236
} else {
5232-
await Promise.reject(cleanupError);
5237+
await Promise.reject(cleanupFailure);
52335238
}
52345239
}
52355240
}

0 commit comments

Comments
 (0)