diff --git a/src/tui/tui-command-handlers.test.ts b/src/tui/tui-command-handlers.test.ts index 026b63350be..787e48da326 100644 --- a/src/tui/tui-command-handlers.test.ts +++ b/src/tui/tui-command-handlers.test.ts @@ -7,14 +7,18 @@ type SetSessionMock = ReturnType & ((key: string) => Promise function createHarness(params?: { sendChat?: ReturnType; + patchSession?: ReturnType; resetSession?: ReturnType; setSession?: SetSessionMock; loadHistory?: LoadHistoryMock; + refreshSessionInfo?: ReturnType; + applySessionInfoFromPatch?: ReturnType; setActivityStatus?: SetActivityStatusMock; isConnected?: boolean; activeChatRunId?: string | null; }) { const sendChat = params?.sendChat ?? vi.fn().mockResolvedValue({ runId: "r1" }); + const patchSession = params?.patchSession ?? vi.fn().mockResolvedValue({}); const resetSession = params?.resetSession ?? vi.fn().mockResolvedValue({ ok: true }); const setSession = params?.setSession ?? (vi.fn().mockResolvedValue(undefined) as SetSessionMock); const addUser = vi.fn(); @@ -24,6 +28,8 @@ function createHarness(params?: { const noteLocalBtwRunId = vi.fn(); const loadHistory = params?.loadHistory ?? (vi.fn().mockResolvedValue(undefined) as LoadHistoryMock); + const refreshSessionInfo = params?.refreshSessionInfo ?? vi.fn().mockResolvedValue(undefined); + const applySessionInfoFromPatch = params?.applySessionInfoFromPatch ?? vi.fn(); const setActivityStatus = params?.setActivityStatus ?? (vi.fn() as SetActivityStatusMock); const state = { currentSessionKey: "agent:main:main", @@ -33,7 +39,7 @@ function createHarness(params?: { }; const { handleCommand } = createCommandHandlers({ - client: { sendChat, resetSession } as never, + client: { sendChat, patchSession, resetSession } as never, chatLog: { addUser, addSystem } as never, tui: { requestRender } as never, opts: {}, @@ -41,14 +47,14 @@ function createHarness(params?: { deliverDefault: false, openOverlay: vi.fn(), closeOverlay: vi.fn(), - refreshSessionInfo: vi.fn(), + refreshSessionInfo: refreshSessionInfo as never, loadHistory, setSession, refreshAgents: vi.fn(), abortActive: vi.fn(), setActivityStatus, formatSessionKey: vi.fn(), - applySessionInfoFromPatch: vi.fn(), + applySessionInfoFromPatch: applySessionInfoFromPatch as never, noteLocalRunId, noteLocalBtwRunId, forgetLocalRunId: vi.fn(), @@ -59,12 +65,15 @@ function createHarness(params?: { return { handleCommand, sendChat, + patchSession, resetSession, setSession, addUser, addSystem, requestRender, loadHistory, + refreshSessionInfo, + applySessionInfoFromPatch, setActivityStatus, noteLocalRunId, noteLocalBtwRunId, @@ -202,4 +211,34 @@ describe("tui command handlers", () => { expect(addSystem).toHaveBeenCalledWith("not connected to gateway — message not sent"); expect(setActivityStatus).toHaveBeenLastCalledWith("disconnected"); }); + + it("rejects invalid /activation values before patching the session", async () => { + const { handleCommand, patchSession, addSystem } = createHarness(); + + await handleCommand("/activation sometimes"); + + expect(patchSession).not.toHaveBeenCalled(); + expect(addSystem).toHaveBeenCalledWith("usage: /activation "); + }); + + it("patches the session for valid /activation values", async () => { + const refreshSessionInfo = vi.fn().mockResolvedValue(undefined); + const applySessionInfoFromPatch = vi.fn(); + const patchSession = vi.fn().mockResolvedValue({ groupActivation: "always" }); + const { handleCommand, addSystem } = createHarness({ + patchSession, + refreshSessionInfo, + applySessionInfoFromPatch, + }); + + await handleCommand("/activation always"); + + expect(patchSession).toHaveBeenCalledWith({ + key: "agent:main:main", + groupActivation: "always", + }); + expect(addSystem).toHaveBeenCalledWith("activation set to always"); + expect(applySessionInfoFromPatch).toHaveBeenCalledWith({ groupActivation: "always" }); + expect(refreshSessionInfo).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/tui/tui-command-handlers.ts b/src/tui/tui-command-handlers.ts index f3fc095c101..fb23387bf66 100644 --- a/src/tui/tui-command-handlers.ts +++ b/src/tui/tui-command-handlers.ts @@ -1,5 +1,6 @@ import { randomUUID } from "node:crypto"; import type { Component, SelectItem, TUI } from "@mariozechner/pi-tui"; +import { normalizeGroupActivation } from "../auto-reply/group-activation.js"; import { formatThinkingLevels, normalizeUsageDisplay, @@ -440,12 +441,17 @@ export function createCommandHandlers(context: CommandHandlerContext) { chatLog.addSystem("usage: /activation "); break; } + const activation = normalizeGroupActivation(args); + if (!activation) { + chatLog.addSystem("usage: /activation "); + break; + } try { const result = await client.patchSession({ key: state.currentSessionKey, - groupActivation: args === "always" ? "always" : "mention", + groupActivation: activation, }); - chatLog.addSystem(`activation set to ${args}`); + chatLog.addSystem(`activation set to ${activation}`); applySessionInfoFromPatch(result); await refreshSessionInfo(); } catch (err) {