From a0f4fb2c15afc1433eb607eaa293c655fc539804 Mon Sep 17 00:00:00 2001 From: Frank Yang Date: Fri, 24 Apr 2026 15:41:17 +0800 Subject: [PATCH] fix: normalize blank agent session ids --- src/agents/command/session.ts | 17 +++++++++-------- src/commands/agent/session.test.ts | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/agents/command/session.ts b/src/agents/command/session.ts index 6908142efc9..c67cd56ab3a 100644 --- a/src/agents/command/session.ts +++ b/src/agents/command/session.ts @@ -143,9 +143,10 @@ export function resolveSessionKeyForRequest(opts: { const scope = sessionCfg?.scope ?? "per-sender"; const mainKey = normalizeMainKey(sessionCfg?.mainKey); const requestedAgentId = opts.agentId?.trim() ? normalizeAgentId(opts.agentId) : undefined; + const requestedSessionId = opts.sessionId?.trim() || undefined; const explicitSessionKey = opts.sessionKey?.trim() || - (!opts.sessionId + (!requestedSessionId ? resolveExplicitAgentSessionKey({ cfg: opts.cfg, agentId: requestedAgentId, @@ -168,23 +169,23 @@ export function resolveSessionKeyForRequest(opts: { // by the shared gateway/session resolver helpers instead of whichever store happens to be scanned // first. if ( - opts.sessionId && + requestedSessionId && !explicitSessionKey && - (!sessionKey || sessionStore[sessionKey]?.sessionId !== opts.sessionId) + (!sessionKey || sessionStore[sessionKey]?.sessionId !== requestedSessionId) ) { const { matches, primaryStoreMatches, storeByKey } = collectSessionIdMatchesForRequest({ cfg: opts.cfg, sessionStore, storePath, storeAgentId, - sessionId: opts.sessionId, + sessionId: requestedSessionId, searchOtherAgentStores: requestedAgentId === undefined, }); - const preferredSelection = resolveSessionIdMatchSelection(matches, opts.sessionId); + const preferredSelection = resolveSessionIdMatchSelection(matches, requestedSessionId); const currentStoreSelection = preferredSelection.kind === "selected" ? preferredSelection - : resolveSessionIdMatchSelection(primaryStoreMatches, opts.sessionId); + : resolveSessionIdMatchSelection(primaryStoreMatches, requestedSessionId); if (currentStoreSelection.kind === "selected") { const preferred = storeByKey.get(currentStoreSelection.sessionKey); if (preferred) { @@ -194,9 +195,9 @@ export function resolveSessionKeyForRequest(opts: { } } - if (opts.sessionId && !sessionKey) { + if (requestedSessionId && !sessionKey) { sessionKey = buildExplicitSessionIdSessionKey({ - sessionId: opts.sessionId, + sessionId: requestedSessionId, agentId: opts.agentId, }); } diff --git a/src/commands/agent/session.test.ts b/src/commands/agent/session.test.ts index dc1c99fa4ad..dd02bbab73c 100644 --- a/src/commands/agent/session.test.ts +++ b/src/commands/agent/session.test.ts @@ -126,6 +126,25 @@ describe("resolveSessionKeyForRequest", () => { expect(result.storePath).toBe(MYBOT_STORE_PATH); }); + it("treats whitespace --session-id as absent when resolving --agent", async () => { + setupMainAndMybotStorePaths(); + mocks.resolveExplicitAgentSessionKey.mockReturnValue("agent:mybot:main"); + mockStoresByPath({ + [MYBOT_STORE_PATH]: { + "agent:mybot:main": { sessionId: "existing-session-id", updatedAt: 1 }, + }, + }); + + const result = resolveSessionKeyForRequest({ + cfg: baseCfg, + agentId: "mybot", + sessionId: " ", + }); + + expect(result.sessionKey).toBe("agent:mybot:main"); + expect(result.storePath).toBe(MYBOT_STORE_PATH); + }); + it("does not search other agent stores when --agent scopes --session-id", async () => { setupMainAndMybotStorePaths(); mockStoresByPath({