fix(regression): hydrate node tool event metadata

This commit is contained in:
Tak Hoffman 2026-03-27 21:00:07 -05:00
parent 72ba2b3653
commit 8aace2b448
No known key found for this signature in database
2 changed files with 68 additions and 1 deletions

View File

@ -781,6 +781,69 @@ describe("agent event handler", () => {
resetAgentRunContextForTest();
});
it("hydrates node session tool events with session ownership metadata", () => {
const { nodeSendToSession, handler } = createHarness({
resolveSessionKeyForRun: () => "session-1",
});
vi.mocked(loadGatewaySessionRow).mockReturnValue({
key: "session-1",
kind: "direct",
spawnedBy: "agent:main:main",
spawnedWorkspaceDir: "/tmp/subagent",
forkedFromParent: true,
spawnDepth: 2,
subagentRole: "orchestrator",
subagentControlScope: "children",
lastThreadId: 42,
fastMode: true,
verboseLevel: "on",
updatedAt: 1_200,
});
registerAgentRunContext("run-tool-node", { sessionKey: "session-1", verboseLevel: "on" });
handler({
runId: "run-tool-node",
seq: 1,
stream: "tool",
ts: 1_234,
data: {
phase: "start",
name: "exec",
toolCallId: "tool-node-1",
args: { command: "echo hi" },
},
});
expect(nodeSendToSession).toHaveBeenCalledWith(
"session-1",
"agent",
expect.objectContaining({
runId: "run-tool-node",
sessionKey: "session-1",
spawnedBy: "agent:main:main",
spawnedWorkspaceDir: "/tmp/subagent",
forkedFromParent: true,
spawnDepth: 2,
subagentRole: "orchestrator",
subagentControlScope: "children",
lastThreadId: 42,
fastMode: true,
verboseLevel: "on",
stream: "tool",
ts: 1_234,
data: expect.objectContaining({
phase: "start",
name: "exec",
toolCallId: "tool-node-1",
args: { command: "echo hi" },
}),
}),
);
resetAgentRunContextForTest();
});
it("broadcasts terminal session status to session subscribers on lifecycle end", () => {
const { broadcastToConnIds, sessionEventSubscribers, handler } = createHarness({
resolveSessionKeyForRun: () => "session-finished",

View File

@ -803,7 +803,11 @@ export function createAgentEventHandler({
// Send tool events to node/channel subscribers only when verbose is enabled;
// WS clients already received the event above via broadcastToConnIds.
if (!isToolEvent || toolVerbose !== "off") {
nodeSendToSession(sessionKey, "agent", isToolEvent ? toolPayload : agentPayload);
nodeSendToSession(
sessionKey,
"agent",
isToolEvent ? { ...toolPayload, ...buildSessionEventSnapshot(sessionKey) } : agentPayload,
);
}
if (!isAborted && evt.stream === "assistant" && typeof evt.data?.text === "string") {
emitChatDelta(sessionKey, clientRunId, evt.runId, evt.seq, evt.data.text, evt.data.delta);