diff --git a/src/gateway/chat-abort.test.ts b/src/gateway/chat-abort.test.ts index 5d74382e624..5a1d464022e 100644 --- a/src/gateway/chat-abort.test.ts +++ b/src/gateway/chat-abort.test.ts @@ -505,6 +505,26 @@ describe("resolveInFlightRunSnapshot", () => { ).toEqual({ runId: "run-a", text: "main agent global text" }); }); + it("resolves bare global history snapshots to the default agent", () => { + const controllers = new Map([ + ["run-main", inFlightEntry("global", { agentId: "main", startedAtMs: 1_000 })], + ["run-work", inFlightEntry("global", { agentId: "work", startedAtMs: 2_000 })], + ]); + const buffers = new Map([ + ["run-main", "main default text"], + ["run-work", "work global text"], + ]); + + expect( + snap({ + chatAbortControllers: controllers, + chatRunBuffers: buffers, + sessionKey: "global", + defaultAgentId: "main", + }), + ).toEqual({ runId: "run-main", text: "main default text" }); + }); + it("prefers the newest startedAtMs when several runs match the same session+agent", () => { // A fast restart/retry/stale-controller race can leave two active entries for // the same key; selection must not depend on Map insertion order. Insert the diff --git a/src/gateway/chat-abort.ts b/src/gateway/chat-abort.ts index cf8521117f8..7573480e0ca 100644 --- a/src/gateway/chat-abort.ts +++ b/src/gateway/chat-abort.ts @@ -191,12 +191,17 @@ export function resolveInFlightRunSnapshot(params: { if (entry.sessionKey !== key) { return false; } - if (key !== "global" || params.agentId === undefined) { + if (key !== "global") { return true; } + const requestedAgentId = + normalizeActiveAgentId(params.agentId) ?? normalizeActiveAgentId(params.defaultAgentId); + if (!requestedAgentId) { + return false; + } const runAgentId = normalizeActiveAgentId(entry.agentId) ?? normalizeActiveAgentId(params.defaultAgentId); - return runAgentId === normalizeActiveAgentId(params.agentId); + return runAgentId === requestedAgentId; }; // Some callers/tests run without populated run state; guard like // collectTrackedActiveSessionRuns so a missing map is a no-op, not a throw. diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 190011ec7b0..04457ef5397 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -2533,14 +2533,15 @@ export const chatHandlers: GatewayRequestHandlers = { agentId: selectedAgent.agentId, modelCatalog, }); + const defaultAgentId = resolveDefaultAgentId(cfg); + const activeRunAgentId = + canonicalKey === "global" ? (selectedAgent.agentId ?? defaultAgentId) : selectedAgent.agentId; sessionInfo.hasActiveRun = hasTrackedActiveSessionRun({ context, requestedKey: sessionKey, canonicalKey, - ...(canonicalKey === "global" && selectedAgent.agentId - ? { agentId: selectedAgent.agentId } - : {}), - defaultAgentId: resolveDefaultAgentId(cfg), + ...(activeRunAgentId ? { agentId: activeRunAgentId } : {}), + defaultAgentId, }); const defaults = getSessionDefaults(cfg, modelCatalog, { allowPluginNormalization: false }); const thinkingLevel = sessionInfo.thinkingLevel ?? sessionInfo.thinkingDefault; @@ -2554,8 +2555,8 @@ export const chatHandlers: GatewayRequestHandlers = { chatRunBuffers: context.chatRunBuffers, requestedSessionKey: sessionKey, canonicalSessionKey: resolveSessionStoreKey({ cfg, sessionKey }), - agentId: requestedAgentId, - defaultAgentId: resolveDefaultAgentId(cfg), + agentId: activeRunAgentId, + defaultAgentId, }); const boundedInFlightRun = boundInFlightRunSnapshotForChatHistory({ snapshot: inFlightRun,