fix: hide internal agent snapshots from chat history

This commit is contained in:
Peter Steinberger
2026-06-01 02:12:36 +01:00
parent 5c4b2d5e39
commit 2b8bf5f214
2 changed files with 23 additions and 4 deletions

View File

@@ -360,6 +360,7 @@ describe("resolveInFlightRunSnapshot", () => {
aborted?: boolean;
projectSessionActive?: boolean;
startedAtMs?: number;
kind?: ChatAbortControllerEntry["kind"];
},
): ChatAbortControllerEntry => {
const now = Date.now();
@@ -376,6 +377,7 @@ describe("resolveInFlightRunSnapshot", () => {
startedAtMs,
expiresAtMs: startedAtMs + 10_000,
projectSessionActive: opts?.projectSessionActive ?? true,
kind: opts?.kind,
};
};
@@ -446,6 +448,18 @@ describe("resolveInFlightRunSnapshot", () => {
}
});
it("ignores hidden agent runs that are not visible chat sends", () => {
expect(
snap({
chatAbortControllers: new Map([
["run-agent", inFlightEntry("agent:main:s", { kind: "agent" })],
]),
chatRunBuffers: new Map([["run-agent", "hidden partial"]]),
sessionKey: "agent:main:s",
}),
).toBeUndefined();
});
it("treats an entry with undefined projectSessionActive as active (sessions.list contract)", () => {
const entry = inFlightEntry("agent:main:s");
delete (entry as { projectSessionActive?: boolean }).projectSessionActive;

View File

@@ -175,9 +175,10 @@ function normalizeActiveAgentId(agentId: string | undefined): string | undefined
* key, so accept a match on EITHER `requestedSessionKey` or `canonicalSessionKey`,
* scoping the shared "global" session by agent. Only runs still projected active
* (`projectSessionActive !== false`, matching sessions.list; the terminal lifecycle
* flips it to false) and not aborted are returned, so a finalized run — already in
* persisted history — is not duplicated and a stale run cannot leave the client
* stuck in `streaming`.
* flips it to false), not aborted, and visible chat-send runs are returned, so a
* finalized run — already in persisted history — is not duplicated and hidden
* agent runs cannot be adopted by chat clients that will not receive their final
* events.
*/
export function resolveInFlightRunSnapshot(params: {
chatAbortControllers: Map<string, ChatAbortControllerEntry>;
@@ -218,7 +219,11 @@ export function resolveInFlightRunSnapshot(params: {
// Active unless explicitly projected inactive — mirrors sessions.list's
// collectTrackedActiveSessionRuns (`projectSessionActive !== false`), so a run
// that indicator shows active is never silently dropped here.
if (entry.projectSessionActive === false || entry.controller.signal.aborted) {
if (
entry.projectSessionActive === false ||
entry.controller.signal.aborted ||
entry.kind === "agent"
) {
continue;
}
if (