























@@ -551,6 +551,57 @@ describe("subagent registry seam flow", () => {
551551expect(replacement?.endedAt).toBeUndefined();
552552});
553553554+it("announces blocked agent.wait snapshots as errors instead of success", async () => {
555+mocks.callGateway.mockImplementation(async (request: { method?: string }) => {
556+if (request.method === "agent.wait") {
557+return {
558+status: "ok",
559+startedAt: 100,
560+endedAt: 250,
561+livenessState: "blocked",
562+error: "Context overflow: prompt too large for the model.",
563+};
564+}
565+return {};
566+});
567+568+mod.registerSubagentRun({
569+runId: "run-blocked-wait",
570+childSessionKey: "agent:main:subagent:child",
571+requesterSessionKey: "agent:main:main",
572+requesterDisplayKey: "main",
573+task: "overflow wait",
574+cleanup: "keep",
575+expectsCompletionMessage: true,
576+});
577+578+await waitForFast(() => {
579+expect(mocks.runSubagentAnnounceFlow).toHaveBeenCalledTimes(1);
580+});
581+const announceParams = expectRecordFields(
582+getMockCallArg(mocks.runSubagentAnnounceFlow, 0, 0, "blocked wait announce"),
583+{ childRunId: "run-blocked-wait" },
584+"blocked wait announce params",
585+);
586+expectRecordFields(
587+announceParams.outcome,
588+{
589+status: "error",
590+error: "Context overflow: prompt too large for the model.",
591+startedAt: 100,
592+endedAt: 250,
593+elapsedMs: 150,
594+},
595+"blocked wait announce outcome",
596+);
597+598+const run = mod
599+.listSubagentRunsForRequester("agent:main:main")
600+.find((entry) => entry.runId === "run-blocked-wait");
601+expect(run?.endedReason).toBe("subagent-error");
602+expect(run?.outcome?.status).toBe("error");
603+});
604+554605it("reconciles stale active runs from persisted terminal session state during sweep", async () => {
555606mocks.callGateway.mockImplementation(async (request: { method?: string }) => {
556607if (request.method === "agent.wait") {
@@ -793,6 +844,79 @@ describe("subagent registry seam flow", () => {
793844expect(run?.cleanupCompletedAt).toBeTypeOf("number");
794845});
795846847+it("announces blocked lifecycle end events as errors instead of success", async () => {
848+mocks.callGateway.mockImplementation(async (request: { method?: string }) => {
849+if (request.method === "agent.wait") {
850+return { status: "pending" };
851+}
852+return {};
853+});
854+855+mod.registerSubagentRun({
856+runId: "run-blocked-end",
857+childSessionKey: "agent:main:subagent:child",
858+requesterSessionKey: "agent:main:main",
859+requesterDisplayKey: "main",
860+task: "overflow task",
861+cleanup: "keep",
862+expectsCompletionMessage: true,
863+});
864+865+const lastOnAgentEventCall = mocks.onAgentEvent.mock.calls[
866+mocks.onAgentEvent.mock.calls.length - 1
867+] as unknown as
868+| [(evt: { runId: string; stream: string; data: Record<string, unknown> }) => void]
869+| undefined;
870+const lifecycleHandler = lastOnAgentEventCall?.[0];
871+expect(lifecycleHandler).toBeTypeOf("function");
872+873+lifecycleHandler?.({
874+runId: "run-blocked-end",
875+stream: "lifecycle",
876+data: {
877+phase: "start",
878+startedAt: 10,
879+},
880+});
881+lifecycleHandler?.({
882+runId: "run-blocked-end",
883+stream: "lifecycle",
884+data: {
885+phase: "end",
886+startedAt: 10,
887+endedAt: 20,
888+livenessState: "blocked",
889+error: "Context overflow: prompt too large for the model.",
890+},
891+});
892+893+await waitForFast(() => {
894+expect(mocks.runSubagentAnnounceFlow).toHaveBeenCalledTimes(1);
895+});
896+const announceParams = expectRecordFields(
897+getMockCallArg(mocks.runSubagentAnnounceFlow, 0, 0, "blocked announce"),
898+{ childRunId: "run-blocked-end" },
899+"blocked announce params",
900+);
901+expectRecordFields(
902+announceParams.outcome,
903+{
904+status: "error",
905+error: "Context overflow: prompt too large for the model.",
906+startedAt: 10,
907+endedAt: 20,
908+elapsedMs: 10,
909+},
910+"blocked announce outcome",
911+);
912+913+const run = mod
914+.listSubagentRunsForRequester("agent:main:main")
915+.find((entry) => entry.runId === "run-blocked-end");
916+expect(run?.endedReason).toBe("subagent-error");
917+expect(run?.outcome?.status).toBe("error");
918+});
919+796920it("preserves run-mode keep entries past SESSION_RUN_TTL_MS sweep", async () => {
797921mod.registerSubagentRun({
798922runId: "run-keep-survives-ttl",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。