From db0f957abae8a07b95409f31037731b7ca5e1d4e Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Tue, 24 Mar 2026 14:59:16 -0500 Subject: [PATCH] fix: surface finished subagent send targets --- .../commands-subagents/action-send.test.ts | 66 +++++++++++++++++++ .../reply/commands-subagents/action-send.ts | 3 + 2 files changed, 69 insertions(+) create mode 100644 src/auto-reply/reply/commands-subagents/action-send.test.ts diff --git a/src/auto-reply/reply/commands-subagents/action-send.test.ts b/src/auto-reply/reply/commands-subagents/action-send.test.ts new file mode 100644 index 00000000000..54245f67767 --- /dev/null +++ b/src/auto-reply/reply/commands-subagents/action-send.test.ts @@ -0,0 +1,66 @@ +import { describe, expect, it, vi } from "vitest"; + +const { sendControlledSubagentMessage, steerControlledSubagentRun } = vi.hoisted(() => ({ + sendControlledSubagentMessage: vi.fn(), + steerControlledSubagentRun: vi.fn(), +})); + +vi.mock("../../../agents/subagent-control.js", () => ({ + sendControlledSubagentMessage, + steerControlledSubagentRun, +})); + +vi.mock("./shared.js", () => ({ + COMMAND: "/subagents", + resolveCommandSubagentController: () => ({ + controllerSessionKey: "agent:main:main", + callerSessionKey: "agent:main:main", + callerIsSubagent: false, + controlScope: "children", + }), + resolveSubagentEntryForToken: () => ({ + entry: { + runId: "run-target", + childSessionKey: "agent:main:subagent:worker", + requesterSessionKey: "agent:main:main", + requesterDisplayKey: "main", + controllerSessionKey: "agent:main:main", + task: "worker task", + cleanup: "keep", + createdAt: Date.now() - 5_000, + startedAt: Date.now() - 4_000, + }, + }), + stopWithText: (text: string) => ({ + shouldContinue: false, + reply: { text }, + }), +})); + +import { handleSubagentsSendAction } from "./action-send.js"; + +describe("handleSubagentsSendAction", () => { + it("surfaces finished-state text instead of reporting a fake successful send", async () => { + sendControlledSubagentMessage.mockResolvedValueOnce({ + status: "done", + runId: "run-stale", + text: "worker task is already finished.", + }); + + const result = await handleSubagentsSendAction( + { + params: { cfg: {} }, + handledPrefix: "/subagents", + requesterKey: "agent:main:main", + runs: [], + restTokens: ["1", "continue"], + } as never, + false, + ); + + expect(result).toEqual({ + shouldContinue: false, + reply: { text: "worker task is already finished." }, + }); + }); +}); diff --git a/src/auto-reply/reply/commands-subagents/action-send.ts b/src/auto-reply/reply/commands-subagents/action-send.ts index 9414313b381..e360a2e975c 100644 --- a/src/auto-reply/reply/commands-subagents/action-send.ts +++ b/src/auto-reply/reply/commands-subagents/action-send.ts @@ -75,6 +75,9 @@ export async function handleSubagentsSendAction( if (result.status === "forbidden") { return stopWithText(`⚠️ ${result.error ?? "send failed"}`); } + if (result.status === "done") { + return stopWithText(result.text); + } return stopWithText( result.replyText ?? `✅ Sent to ${formatRunLabel(targetResolution.entry)} (run ${result.runId.slice(0, 8)}).`,