← Back to PRs

#19452: fix: skip stale responses in interrupt queue mode via generationId

by kisjovan open 2026-02-17 20:27 View on GitHub →
size: L
## Problem In interrupt queue mode, when a second message arrives while the first response is being generated/sent, the first response still gets delivered before the second (correct) response. This happens because the abort arrives too late — the response is already in the outbound pipeline. ## Solution Implements a `generationId` approach as discussed in #19426: 1. **`queue/state.ts`** — Added per-session generation counter (`SESSION_GENERATION_IDS` map) with `getSessionGenerationId`, `incrementSessionGenerationId`, and `isGenerationCurrent` helpers. 2. **`get-reply-run.ts`** — On interrupt (when clearing queue and aborting), increment the session's generationId. Capture it and pass to `runReplyAgent`. 3. **`agent-runner.ts`** — Before delivering the final response, check if the run's generationId still matches the session's latest. If superseded by a newer interrupt, skip sending and log the drop. ## Changes - 3 files changed, 45 insertions - Zero behavioral change for non-interrupt queue modes (generationId defaults to 0 and only increments on interrupt) Fixes #19426 <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR implements a `generationId` mechanism to suppress stale responses in interrupt queue mode. When a second message arrives while the first response is in the outbound pipeline, the first response is now dropped at the delivery point instead of being sent to the user. The approach — a per-session monotonic counter incremented on each interrupt, captured at run-start, and validated before delivery — is conceptually sound and well-scoped. Two issues were found: - **Missing `generationId` in all existing test call-sites (will break CI):** `generationId: number` was added as a required field on the `runReplyAgent` params type, but none of the existing tests in `agent-runner.runreplyagent.test.ts` or `agent-runner.misc.runreplyagent.test.ts` pass it. This produces TypeScript compilation errors. At JS runtime, the missing field is `undefined`, and `isGenerationCurrent(key, undefined)` always returns `false`, causing the stale-response guard to fire on every test run and drop all replies — breaking every test that checks the returned payload. Making `generationId` optional (defaulting to `0`) or adding `generationId: 0` to all existing test call-sites is required. - **`SESSION_GENERATION_IDS` is never cleaned up (memory leak):** The new module-level map accumulates an entry for every session that ever triggers an interrupt, but `clearSessionQueues` / `clearFollowupQueue` (called on abort, session reset, and subagent stop) only clean up `FOLLOWUP_QUEUES`, not `SESSION_GENERATION_IDS`. In a long-running gateway serving many sessions, this is an unbounded memory leak. The fix is to delete the map entry when the session's followup queue is cleared. <h3>Confidence Score: 2/5</h3> - Not safe to merge: the new required `generationId` parameter breaks all existing test call-sites and will cause TypeScript build failures; the missing cleanup path creates a memory leak in long-running processes. - The core logic of the generationId approach is correct, but two concrete defects block merging: (1) `generationId` is a required param not added to any existing test call-sites, breaking TypeScript compilation and making every omitted-param test assert on a dropped response; (2) `SESSION_GENERATION_IDS` has no cleanup path, leaking memory per session over time. - src/auto-reply/reply/agent-runner.ts (required param breaks all existing tests), src/auto-reply/reply/queue/cleanup.ts (SESSION_GENERATION_IDS never cleaned up), src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts and agent-runner.runreplyagent.test.ts (all call-sites missing generationId) <sub>Last reviewed commit: d5ecfa5</sub> <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs