fix: address delivery dedupe review follow-ups (#44666)

Merged via squash.

Prepared head SHA: 8e6d254cc4
Co-authored-by: frankekn <4488090+frankekn@users.noreply.github.com>
Co-authored-by: frankekn <4488090+frankekn@users.noreply.github.com>
Reviewed-by: @frankekn
This commit is contained in:
Frank Yang
2026-03-13 16:18:01 +08:00
committed by GitHub
parent 5b06619c67
commit f07033ed3f
17 changed files with 413 additions and 37 deletions

View File

@@ -343,6 +343,35 @@ describe("subagent registry persistence", () => {
expect(afterSecond.runs["run-3"].cleanupCompletedAt).toBeDefined();
});
it("retries cleanup announce after announce flow rejects", async () => {
const persisted = createPersistedEndedRun({
runId: "run-reject",
childSessionKey: "agent:main:subagent:reject",
task: "reject announce",
cleanup: "keep",
});
const registryPath = await writePersistedRegistry(persisted);
announceSpy.mockRejectedValueOnce(new Error("announce boom"));
await restartRegistryAndFlush();
expect(announceSpy).toHaveBeenCalledTimes(1);
const afterFirst = JSON.parse(await fs.readFile(registryPath, "utf8")) as {
runs: Record<string, { cleanupHandled?: boolean; cleanupCompletedAt?: number }>;
};
expect(afterFirst.runs["run-reject"].cleanupHandled).toBe(false);
expect(afterFirst.runs["run-reject"].cleanupCompletedAt).toBeUndefined();
announceSpy.mockResolvedValueOnce(true);
await restartRegistryAndFlush();
expect(announceSpy).toHaveBeenCalledTimes(2);
const afterSecond = JSON.parse(await fs.readFile(registryPath, "utf8")) as {
runs: Record<string, { cleanupCompletedAt?: number }>;
};
expect(afterSecond.runs["run-reject"].cleanupCompletedAt).toBeDefined();
});
it("keeps delete-mode runs retryable when announce is deferred", async () => {
const persisted = createPersistedEndedRun({
runId: "run-4",

View File

@@ -534,6 +534,18 @@ function startSubagentAnnounceCleanupFlow(runId: string, entry: SubagentRunRecor
return false;
}
const requesterOrigin = normalizeDeliveryContext(entry.requesterOrigin);
const finalizeAnnounceCleanup = (didAnnounce: boolean) => {
void finalizeSubagentCleanup(runId, entry.cleanup, didAnnounce).catch((err) => {
defaultRuntime.log(`[warn] subagent cleanup finalize failed (${runId}): ${String(err)}`);
const current = subagentRuns.get(runId);
if (!current || current.cleanupCompletedAt) {
return;
}
current.cleanupHandled = false;
persistSubagentRuns();
});
};
void runSubagentAnnounceFlow({
childSessionKey: entry.childSessionKey,
childRunId: entry.runId,
@@ -555,13 +567,13 @@ function startSubagentAnnounceCleanupFlow(runId: string, entry: SubagentRunRecor
wakeOnDescendantSettle: entry.wakeOnDescendantSettle === true,
})
.then((didAnnounce) => {
void finalizeSubagentCleanup(runId, entry.cleanup, didAnnounce);
finalizeAnnounceCleanup(didAnnounce);
})
.catch((error) => {
defaultRuntime.log(
`[warn] Subagent announce flow failed during cleanup for run ${runId}: ${String(error)}`,
);
void finalizeSubagentCleanup(runId, entry.cleanup, false);
finalizeAnnounceCleanup(false);
});
return true;
}