diff --git a/src/agents/tools/sessions-helpers.ts b/src/agents/tools/sessions-helpers.ts index 63c87e16884..06dea0b279e 100644 --- a/src/agents/tools/sessions-helpers.ts +++ b/src/agents/tools/sessions-helpers.ts @@ -52,6 +52,9 @@ export type SessionListRow = { key: string; kind: SessionKind; channel: string; + origin?: { + provider?: string; + }; spawnedBy?: string; label?: string; displayName?: string; diff --git a/src/agents/tools/sessions-list-tool.ts b/src/agents/tools/sessions-list-tool.ts index cea07e09f1e..179ad9f6c60 100644 --- a/src/agents/tools/sessions-list-tool.ts +++ b/src/agents/tools/sessions-list-tool.ts @@ -137,6 +137,12 @@ export function createSessionsListTool(opts?: { }); const entryChannel = typeof entry.channel === "string" ? entry.channel : undefined; + const entryOrigin = + entry.origin && typeof entry.origin === "object" + ? (entry.origin as Record) + : undefined; + const originChannel = + typeof entryOrigin?.provider === "string" ? entryOrigin.provider : undefined; const deliveryContext = entry.deliveryContext && typeof entry.deliveryContext === "object" ? (entry.deliveryContext as Record) @@ -155,7 +161,7 @@ export function createSessionsListTool(opts?: { const derivedChannel = deriveChannel({ key, kind, - channel: entryChannel, + channel: entryChannel ?? originChannel, lastChannel, }); diff --git a/src/agents/tools/sessions.test.ts b/src/agents/tools/sessions.test.ts index 877b00eae6f..f324d43b775 100644 --- a/src/agents/tools/sessions.test.ts +++ b/src/agents/tools/sessions.test.ts @@ -432,6 +432,38 @@ describe("sessions_list transcriptPath resolution", () => { }); }); +describe("sessions_list channel derivation", () => { + beforeEach(() => { + callGatewayMock.mockClear(); + loadConfigMock.mockReturnValue({ + session: { scope: "per-sender", mainKey: "main" }, + tools: { + agentToAgent: { enabled: true }, + sessions: { visibility: "all" }, + }, + }); + }); + + it("falls back to origin.provider when the legacy top-level channel field is missing", async () => { + callGatewayMock.mockResolvedValueOnce({ + path: "/tmp/sessions.json", + sessions: [ + { + key: "agent:main:discord:group:ops", + kind: "group", + origin: { provider: "discord" }, + }, + ], + }); + + const result = await executeMainSessionsList(); + + expect(result.details).toMatchObject({ + sessions: [{ key: "agent:main:discord:group:ops", channel: "discord" }], + }); + }); +}); + describe("sessions_send gating", () => { beforeEach(() => { callGatewayMock.mockClear();