diff --git a/src/auto-reply/reply/commands-subagents-spawn-action.test.ts b/src/auto-reply/reply/commands-subagents-spawn-action.test.ts index 702eeaf7018..32292a9c634 100644 --- a/src/auto-reply/reply/commands-subagents-spawn-action.test.ts +++ b/src/auto-reply/reply/commands-subagents-spawn-action.test.ts @@ -234,6 +234,78 @@ describe("subagents spawn action", () => { ); }); + it("prefers the requester-key session entry for group metadata", async () => { + spawnSubagentDirectMock.mockResolvedValue(acceptedResult()); + await handleSubagentsSpawnAction( + buildContext({ + requesterKey: "agent:main:target", + sessionEntry: { + sessionId: "wrapper-session", + updatedAt: Date.now(), + groupId: "wrapper-group", + groupChannel: "#wrapper", + space: "wrapper-space", + }, + }), + ); + const call = spawnSubagentDirectMock.mock.calls.at(-1); + expect(call?.[1]).toEqual( + expect.objectContaining({ + agentSessionKey: "agent:main:target", + agentGroupId: "wrapper-group", + agentGroupChannel: "#wrapper", + agentGroupSpace: "wrapper-space", + }), + ); + + spawnSubagentDirectMock.mockClear(); + await handleSubagentsSpawnAction( + { + ...buildContext({ + requesterKey: "agent:main:target", + sessionEntry: { + sessionId: "wrapper-session", + updatedAt: Date.now(), + groupId: "wrapper-group", + groupChannel: "#wrapper", + space: "wrapper-space", + }, + }), + params: { + ...buildContext({ + requesterKey: "agent:main:target", + sessionEntry: { + sessionId: "wrapper-session", + updatedAt: Date.now(), + groupId: "wrapper-group", + groupChannel: "#wrapper", + space: "wrapper-space", + }, + }).params, + sessionStore: { + "agent:main:target": { + sessionId: "target-session", + updatedAt: Date.now(), + groupId: "target-group", + groupChannel: "#target", + space: "target-space", + }, + }, + }, + }, + ); + + expect(spawnSubagentDirectMock).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + agentSessionKey: "agent:main:target", + agentGroupId: "target-group", + agentGroupChannel: "#target", + agentGroupSpace: "target-space", + }), + ); + }); + it("falls back to OriginatingTo when command.to is missing", async () => { spawnSubagentDirectMock.mockResolvedValue(acceptedResult()); await handleSubagentsSpawnAction( diff --git a/src/auto-reply/reply/commands-subagents/action-spawn.ts b/src/auto-reply/reply/commands-subagents/action-spawn.ts index 9cd8f5908dd..09b2c783ba7 100644 --- a/src/auto-reply/reply/commands-subagents/action-spawn.ts +++ b/src/auto-reply/reply/commands-subagents/action-spawn.ts @@ -7,6 +7,7 @@ export async function handleSubagentsSpawnAction( ctx: SubagentsCommandContext, ): Promise { const { params, requesterKey, restTokens } = ctx; + const requesterSessionEntry = params.sessionStore?.[requesterKey] ?? params.sessionEntry; const agentId = restTokens[0]; const taskParts: string[] = []; @@ -51,9 +52,9 @@ export async function handleSubagentsSpawnAction( agentAccountId: params.ctx.AccountId, agentTo: normalizedTo, agentThreadId: params.ctx.MessageThreadId, - agentGroupId: params.sessionEntry?.groupId ?? null, - agentGroupChannel: params.sessionEntry?.groupChannel ?? null, - agentGroupSpace: params.sessionEntry?.space ?? null, + agentGroupId: requesterSessionEntry?.groupId ?? null, + agentGroupChannel: requesterSessionEntry?.groupChannel ?? null, + agentGroupSpace: requesterSessionEntry?.space ?? null, }, ); if (result.status === "accepted") {