fix(acp): kept hub job-wait results visible

Only a peer-scoped wait (from, no ids) is internal messaging; bare and ids waits settle on background-job delivery whose snapshot is the job result.

Fixes #6872
This commit is contained in:
roboomp
2026-07-28 07:34:49 +00:00
parent b38472b111
commit 0c04e86efd
2 changed files with 59 additions and 1 deletions
@@ -165,7 +165,10 @@ function isInternalHubMessageTool(toolName: string, args: unknown): boolean {
case "send":
return typeof Reflect.get(hubArgs, "to") === "string";
case "wait":
return typeof Reflect.get(hubArgs, "name") !== "string";
// A bare wait or an `ids` wait settles on background-job delivery,
// whose snapshot IS the job result (hub.md) — keep those visible.
// Only a peer-scoped wait (`from`, no jobs) is internal messaging.
return typeof Reflect.get(hubArgs, "from") === "string" && Reflect.get(hubArgs, "ids") === undefined;
default:
return false;
}
@@ -302,6 +302,61 @@ describe("ACP event mapper", () => {
);
});
it("keeps background job-wait results visible over ACP", () => {
const events = [
{
type: "tool_execution_start",
toolCallId: "tc-hub-job-wait",
toolName: "hub",
args: { op: "wait", ids: ["bash_a1b2c3"] },
},
{
type: "tool_execution_end",
toolCallId: "tc-hub-job-wait",
toolName: "hub",
isError: false,
result: { content: [{ type: "text", text: "job output" }] },
},
] satisfies AgentSessionEvent[];
const updates = events.flatMap(event =>
mapAgentSessionEventToAcpSessionUpdates(event, "session-1", {
getToolArgs: () => ({ op: "wait", ids: ["bash_a1b2c3"] }),
}),
);
expect(updates.map(update => update.update.sessionUpdate)).toEqual(["tool_call", "tool_call_update"]);
});
it("keeps a bare Hub wait visible so job deliveries reach ACP", () => {
const updates = mapAgentSessionEventToAcpSessionUpdates(
{
type: "tool_execution_start",
toolCallId: "tc-hub-bare-wait",
toolName: "hub",
args: { op: "wait" },
},
"session-1",
);
expect(updates).toHaveLength(1);
expect(updates[0]?.update.sessionUpdate).toBe("tool_call");
});
it("hides a peer-scoped Hub wait from ACP", () => {
const updates = mapAgentSessionEventToAcpSessionUpdates(
{
type: "tool_execution_start",
toolCallId: "tc-hub-peer-wait",
toolName: "hub",
args: { op: "wait", from: "Scout" },
},
"session-1",
);
expect(updates).toEqual([]);
});
it("uses command text for a new command tool even when intent is generic", () => {
const updates = mapAgentSessionEventToAcpSessionUpdates(
{