diff --git a/ui/src/ui/chat/slash-command-executor.node.test.ts b/ui/src/ui/chat/slash-command-executor.node.test.ts index b915ea403ea..2e47b79aa43 100644 --- a/ui/src/ui/chat/slash-command-executor.node.test.ts +++ b/ui/src/ui/chat/slash-command-executor.node.test.ts @@ -141,4 +141,39 @@ describe("executeSlashCommand /kill", () => { sessionKey: "agent:main:subagent:two", }); }); + + it("treats the legacy main session key as the default agent scope", async () => { + const request = vi.fn(async (method: string, _payload?: unknown) => { + if (method === "sessions.list") { + return { + sessions: [ + row("main"), + row("agent:main:subagent:one"), + row("agent:main:subagent:two"), + row("agent:other:subagent:three"), + ], + }; + } + if (method === "chat.abort") { + return { ok: true, aborted: true }; + } + throw new Error(`unexpected method: ${method}`); + }); + + const result = await executeSlashCommand( + { request } as unknown as GatewayBrowserClient, + "main", + "kill", + "all", + ); + + expect(result.content).toBe("Aborted 2 sub-agent sessions."); + expect(request).toHaveBeenNthCalledWith(1, "sessions.list", {}); + expect(request).toHaveBeenNthCalledWith(2, "chat.abort", { + sessionKey: "agent:main:subagent:one", + }); + expect(request).toHaveBeenNthCalledWith(3, "chat.abort", { + sessionKey: "agent:main:subagent:two", + }); + }); }); diff --git a/ui/src/ui/chat/slash-command-executor.ts b/ui/src/ui/chat/slash-command-executor.ts index d0c4b01e3cf..c7ddced286d 100644 --- a/ui/src/ui/chat/slash-command-executor.ts +++ b/ui/src/ui/chat/slash-command-executor.ts @@ -3,7 +3,12 @@ * Calls gateway RPC methods and returns formatted results. */ -import { isSubagentSessionKey, parseAgentSessionKey } from "../../../../src/routing/session-key.js"; +import { + DEFAULT_AGENT_ID, + DEFAULT_MAIN_KEY, + isSubagentSessionKey, + parseAgentSessionKey, +} from "../../../../src/routing/session-key.js"; import type { GatewayBrowserClient } from "../gateway.ts"; import type { AgentsListResult, @@ -350,6 +355,9 @@ function resolveKillTargets( const keys = new Set(); const normalizedCurrentSessionKey = currentSessionKey.trim().toLowerCase(); const currentParsed = parseAgentSessionKey(normalizedCurrentSessionKey); + const currentAgentId = + currentParsed?.agentId ?? + (normalizedCurrentSessionKey === DEFAULT_MAIN_KEY ? DEFAULT_AGENT_ID : undefined); for (const session of sessions) { const key = session?.key?.trim(); if (!key || !isSubagentSessionKey(key)) { @@ -360,7 +368,7 @@ function resolveKillTargets( const belongsToCurrentSession = isWithinCurrentSessionSubtree( normalizedKey, normalizedCurrentSessionKey, - currentParsed?.agentId, + currentAgentId, parsed?.agentId, ); const isMatch =