fix(tui): normalize session key to lowercase to match gateway canonicalization

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
This commit is contained in:
lynn 2026-03-04 13:50:21 +08:00 committed by Altay
parent 26e014311f
commit d3bfd84aa3
No known key found for this signature in database
2 changed files with 23 additions and 2 deletions

View File

@ -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", () => {

View File

@ -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): {