























@@ -1044,6 +1044,64 @@ describe("subagent registry seam flow", () => {
10441044expect(mocks.runSubagentAnnounceFlow).toHaveBeenCalledTimes(1);
10451045});
104610461047+it("resumes ended cleanup when lifecycle killed completion rejects before cleanup", async () => {
1048+mocks.callGateway.mockImplementation(async (request: { method?: string }) => {
1049+if (request.method === "agent.wait") {
1050+return { status: "pending" };
1051+}
1052+return {};
1053+});
1054+mocks.ensureRuntimePluginsLoaded
1055+.mockRejectedValueOnce(new Error("runtime unavailable before cleanup"))
1056+.mockRejectedValueOnce(new Error("runtime still unavailable before cleanup"));
1057+1058+mod.registerSubagentRun({
1059+runId: "run-killed-recovery",
1060+childSessionKey: "agent:main:subagent:child",
1061+requesterSessionKey: "agent:main:main",
1062+requesterDisplayKey: "main",
1063+task: "killed recovery test",
1064+cleanup: "keep",
1065+expectsCompletionMessage: false,
1066+});
1067+1068+const lastOnAgentEventCall = mocks.onAgentEvent.mock.calls[
1069+mocks.onAgentEvent.mock.calls.length - 1
1070+] as unknown as
1071+| [(evt: { runId: string; stream: string; data: Record<string, unknown> }) => void]
1072+| undefined;
1073+const lifecycleHandler = lastOnAgentEventCall?.[0];
1074+expect(lifecycleHandler).toBeTypeOf("function");
1075+1076+lifecycleHandler?.({
1077+runId: "run-killed-recovery",
1078+stream: "lifecycle",
1079+data: { phase: "start", startedAt: 100 },
1080+});
1081+1082+lifecycleHandler?.({
1083+runId: "run-killed-recovery",
1084+stream: "lifecycle",
1085+data: {
1086+phase: "end",
1087+startedAt: 100,
1088+endedAt: 200,
1089+stopReason: "aborted",
1090+},
1091+});
1092+1093+await waitForFast(() => {
1094+const run = mod
1095+.listSubagentRunsForRequester("agent:main:main")
1096+.find((entry) => entry.runId === "run-killed-recovery");
1097+expect(mocks.ensureRuntimePluginsLoaded).toHaveBeenCalledTimes(2);
1098+expect(run?.outcome?.status).toBe("error");
1099+expect(run?.endedReason).toBe("subagent-killed");
1100+expect(run?.cleanupCompletedAt).toBeTypeOf("number");
1101+});
1102+expect(mocks.runSubagentAnnounceFlow).not.toHaveBeenCalled();
1103+});
1104+10471105it("preserves run-mode keep entries past SESSION_RUN_TTL_MS sweep", async () => {
10481106mod.registerSubagentRun({
10491107runId: "run-keep-survives-ttl",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。