From d3bfd84aa3538ce729e7257c2c820a44caec312c Mon Sep 17 00:00:00 2001 From: lynn Date: Wed, 4 Mar 2026 13:50:21 +0800 Subject: [PATCH] fix(tui): normalize session key to lowercase to match gateway canonicalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gateway canonicalizes all session keys to lowercase via resolveSessionStoreKey, but resolveTuiSessionKey was returning the raw user input unchanged. This meant launching the TUI with an uppercase session name (e.g. --session agent:main:Test1) caused all real-time events to be silently dropped — the TUI subscribed using "agent:main:Test1" while the gateway emitted under "agent:main:test1". Messages were still saved correctly (the write path also goes through resolveSessionStoreKey), so history showed up on restart, but nothing appeared while the session was live. Fix by lowercasing the returned key on both return paths that previously preserved original casing. The empty-input path via buildAgentMainSessionKey already normalizes through normalizeAgentId/normalizeMainKey, so no change needed there. Fixes #33866 --- src/tui/tui.test.ts | 21 +++++++++++++++++++++ src/tui/tui.ts | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/tui/tui.test.ts b/src/tui/tui.test.ts index 9b46da66a99..2882cebcd64 100644 --- a/src/tui/tui.test.ts +++ b/src/tui/tui.test.ts @@ -74,6 +74,27 @@ describe("resolveTuiSessionKey", () => { }), ).toBe("agent:ops:incident"); }); + + it("lowercases session keys with uppercase characters", () => { + // Uppercase in agent-prefixed form + expect( + resolveTuiSessionKey({ + raw: "agent:main:Test1", + sessionScope: "global", + currentAgentId: "main", + sessionMainKey: "agent:main:main", + }), + ).toBe("agent:main:test1"); + // Uppercase in bare form (prefixed by currentAgentId) + expect( + resolveTuiSessionKey({ + raw: "Test1", + sessionScope: "global", + currentAgentId: "main", + sessionMainKey: "agent:main:main", + }), + ).toBe("agent:main:test1"); + }); }); describe("resolveGatewayDisconnectState", () => { diff --git a/src/tui/tui.ts b/src/tui/tui.ts index 847245b3b67..fe365477d91 100644 --- a/src/tui/tui.ts +++ b/src/tui/tui.ts @@ -203,9 +203,9 @@ export function resolveTuiSessionKey(params: { return trimmed; } if (trimmed.startsWith("agent:")) { - return trimmed; + return trimmed.toLowerCase(); } - return `agent:${params.currentAgentId}:${trimmed}`; + return `agent:${params.currentAgentId}:${trimmed.toLowerCase()}`; } export function resolveGatewayDisconnectState(reason?: string): {