Skip to content

fix(auto-reply): wire get-reply-run.ts queue-mode gates to session-run-registry — interrupt now actually interrupts#2470

Merged
alexey-pelykh merged 1 commit intomainfrom
fix/2342-get-reply-run-queue-gates
Apr 22, 2026
Merged

fix(auto-reply): wire get-reply-run.ts queue-mode gates to session-run-registry — interrupt now actually interrupts#2470
alexey-pelykh merged 1 commit intomainfrom
fix/2342-get-reply-run-queue-gates

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

src/auto-reply/reply/get-reply-run.ts (hot path for every inbound auto-reply) had hardcoded const isActive = false; const isStreaming = false; at the queue-mode gate — collapsing every user-configured queue mode to the "no run active" branch. A user who set queue.mode: interrupt got silently downgraded: interrupt mode never actually interrupted the running CLI subprocess.

Same family as #2460 / #2461 / #2462 — completes the session-run-registry wiring sweep from ChannelBridge audit #2089.

Fix

  • Wire isActive to isSessionRunActive(queueKey) from session-run-registry.ts (registry is populated by ChannelBridge at register/unregister sites).
  • Wire interrupt queue mode to killSessionRun(queueKey) — dispatches abortController.abort() or SIGTERM when a new interrupt-mode message arrives while a run is active.
  • Delete the dead sessionLaneKey / laneSize / clearCommandLane block — command-queue.ts lanes are main/cron/subagent/nested, not session-keyed (issue explicitly flagged this as dead regardless of Pi-embedded stubs).
  • Drop isStreaming entirely. CLI runtimes are binary: active = streaming. The distinction was Pi-embedded-era. Removed from RunPreparedReplyParams / runReplyAgent contract and deleted the shouldSteer && isStreaming dead branch at agent-runner.ts:193-200 (inside: const steered = false made the block unreachable anyway).
  • Drop unused shouldSteer from runReplyAgent contract (only consumer was the deleted dead branch).

Changes

File What
src/auto-reply/reply/get-reply-run.ts +isSessionRunActive + killSessionRun import; -clearCommandLane/getQueueSize imports; replaced hardcoded isActive/isStreaming with registry call; interrupt-mode gate calls killSessionRun; removed dead lane block and shouldSteer local
src/auto-reply/reply/agent-runner.ts Dropped isStreaming and shouldSteer from params; deleted dead shouldSteer && isStreaming branch (9 lines)
3 test files Stripped stale isStreaming: false and shouldSteer: false fixtures (contract-removed fields)

5 files / +6 / -53.

Why CLI runtimes are binary (no isStreaming)

AgentRuntime.execute (src/middleware/types.ts:7) returns AsyncIterable<AgentEvent>. The subprocess is either iterating events (active + streaming) or not (inactive). There's no "request in flight, not yet streaming" state the way Pi-embedded had. Collapsing to isActive alone is accurate.

Verification

  • pnpm check (format + tsgo + lint + lint:tmp:no-random-messaging + lint:no-remoteclaw-ai) → exit 0
  • pnpm test (full parallel suite) → 800 files / 7010 passed / 3 skipped — no regression
  • Rescan: git grep "isEmbeddedPiRunActive\|isEmbeddedPiRunStreaming\|resolveEmbeddedSessionLane" src/ → zero hits
  • Rescan: git grep "isStreaming" src/auto-reply/ → zero hits

Test plan

  • pnpm check exit 0
  • pnpm test full suite green (7010 passed)
  • CI green on all 11 required checks

Context

Closes #2342

Refs: #2089, #2088

🤖 Generated with Claude Code

…n-registry — interrupt now actually interrupts (#2342)

`src/auto-reply/reply/get-reply-run.ts` (hot path for every inbound
auto-reply) had hardcoded `const isActive = false; const isStreaming =
false;` at the queue-mode gate. This collapsed every user-configured
queue mode to the "no run active" branch, breaking `interrupt` /
`steer` / `steer-backlog` / `collect` semantics. A user who set
`queue.mode: interrupt` in their config got silently downgraded — the
interrupt mode never actually interrupted a running CLI subprocess.

## Fix

- Wire `isActive` to `isSessionRunActive(queueKey)` from
  `src/agents/session-run-registry.js` (the registry populated by
  `ChannelBridge` at register/unregister sites).
- Wire `interrupt` queue mode to `killSessionRun(queueKey)` — when
  `isActive` is true and mode is `interrupt`, dispatch
  `abortController.abort()` or `SIGTERM` to the running subprocess
  before starting the new run.
- Delete the dead `sessionLaneKey` / `laneSize` / `clearCommandLane`
  block at lines 402-408 — the issue noted (and grep confirmed)
  `command-queue.ts` lanes are `main`/`cron`/`subagent`/`nested`;
  there is no session-keyed lane that this code populates.
- Drop `isStreaming` entirely. CLI runtimes don't expose a "streaming"
  state distinct from "active" — the distinction was Pi-embedded-era.
  Binary: active = streaming. Removed the param from
  `RunPreparedReplyParams` / `runReplyAgent`'s contract and deleted
  the dead `shouldSteer && isStreaming` branch at `agent-runner.ts:193-200`
  (inside that branch `const steered = false` made the inner block
  unreachable anyway).
- Drop unused `shouldSteer` from `runReplyAgent` contract and the
  local declaration in `get-reply-run.ts` (only consumer was the
  deleted dead branch).

## Changes

- `src/auto-reply/reply/get-reply-run.ts`:
  - Import `isSessionRunActive`, `killSessionRun` from
    `../../agents/session-run-registry.js`.
  - Drop unused `clearCommandLane`, `getQueueSize` imports.
  - Replace hardcoded `isActive = false` with registry call.
  - Replace hardcoded interrupt-mode no-op with
    `killSessionRun(queueKey)`.
  - Delete `shouldSteer` local + `isStreaming` pass-through.
- `src/auto-reply/reply/agent-runner.ts`: remove `isStreaming`,
  `shouldSteer` from `runReplyAgent` params; delete the
  `shouldSteer && isStreaming` dead branch (9 lines).
- Test fixtures (`agent-runner.media-paths.test.ts`,
  `agent-runner.misc.runreplyagent.test.ts`,
  `agent-runner.runreplyagent.e2e.test.ts`): remove stale
  `isStreaming: false` and `shouldSteer: false` properties that
  no longer exist on the contract.

## Verification

- `pnpm check` (format + tsgo + lint + project-specific lints) → exit 0
- `pnpm test` (full parallel suite) → **800 files / 7010 passed /
  3 skipped** — no regression
- Rescan: `git grep "isEmbeddedPiRunActive\|isEmbeddedPiRunStreaming\|resolveEmbeddedSessionLane"`
  in `src/` returns zero hits.
- Rescan: `git grep "isStreaming"` in `src/auto-reply/` returns zero
  hits (test fixtures cleaned).

Closes #2342

Refs: #2089, #2088

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexey-pelykh alexey-pelykh merged commit cd44294 into main Apr 22, 2026
15 checks passed
@alexey-pelykh alexey-pelykh deleted the fix/2342-get-reply-run-queue-gates branch April 22, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(auto-reply): wire get-reply-run.ts queue-mode gates to session-run-registry

1 participant