Skip to content

fix(code): stop duplicating Auto transcript events on interrupt replay - #5157

Merged
Mason Daugherty (mdrxy) merged 5 commits into
mainfrom
open-swe/auto-mode-duplicate-events
Jul 29, 2026
Merged

fix(code): stop duplicating Auto transcript events on interrupt replay#5157
Mason Daugherty (mdrxy) merged 5 commits into
mainfrom
open-swe/auto-mode-duplicate-events

Conversation

@mdrxy

@mdrxy Mason Daugherty (mdrxy) commented Jul 29, 2026

Copy link
Copy Markdown
Member

Fixed duplicated Auto-mode approval/denial messages in the deepagents-code transcript after resuming a human approval.


AutoModeHITLMiddleware emits its sanitized transcript events (Auto fallback: human approval required …, Auto denied […], Auto classifier unavailable: …) over the custom stream writer before calling interrupt(). LangGraph restarts the entire after_model node when the user answers the approval, so every pre-interrupt emission ran a second time and the same line was rendered twice. Emissions now go through a bounded, LRU-evicted ledger keyed by thread + action batch, so a replay is a no-op while a later batch can still emit the same text. This also generalizes the existing per-invocation coalescing of N-tool batches.

Made by Open SWE

`interrupt()` restarts the whole `after_model` node when the user answers
an approval, so the Auto fallback/denial/unavailable events emitted before
it were rendered a second time in the transcript. Emit them through a
bounded, batch-scoped ledger so a replay is a no-op.

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
@github-actions github-actions Bot added dcode Related to `deepagents-code` fix A bug fix (PATCH) internal User is a member of the `langchain-ai` GitHub organization open-swe size: S 50-199 LOC labels Jul 29, 2026
@mdrxy
Mason Daugherty (mdrxy) marked this pull request as ready for review July 29, 2026 19:10
Mason Daugherty (mdrxy) and others added 3 commits July 29, 2026 15:10
…ives

The `fallback` event carrying `mode: "manual"` is a command, not just a
transcript line: the client persists Manual and repaints its status bar on
receipt. De-duplicating it by target tool-call IDs alone let an earlier
threshold notice on the same action batch suppress it, leaving the client
displaying Auto while the server had already fallen back to Manual. `mode` and
`reason` are now part of the de-duplication identity.

Also in the emission ledger:

- Bound pinned scopes. Scopes held across an unresolved `interrupt()` were
  exempt from eviction and never released when a user abandoned an approval, so
  the ledger grew for the life of the process. Pins are capped and refreshed on
  replay, keeping the ledger bounded overall.
- Release a pin on `BaseException`, not only `Exception`, so a cancelled run
  does not leak its scope.
- Give a runtime without a trusted thread key its own scope instead of a shared
  `-` bucket. Two threads with degraded keys collapsed into one scope and
  silently suppressed each other's fallback notice.
- Derive the scope once per node run and pass it down, rather than recomputing
  it inside `_human_review` from whatever message it was handed.
- Log suppressed emissions and pin evictions at debug; both failure modes
  otherwise present only as silence.
- Drop `tool_name` from denial payloads. One event stands for every call sharing
  a category and reason, so the field named an arbitrary member of the batch. No
  consumer reads it; the per-call detail is in each `ToolMessage`.
@github-actions github-actions Bot added size: L 500-999 LOC and removed size: S 50-199 LOC labels Jul 29, 2026
@mdrxy
Mason Daugherty (mdrxy) merged commit 5bbcf42 into main Jul 29, 2026
55 checks passed
@mdrxy
Mason Daugherty (mdrxy) deleted the open-swe/auto-mode-duplicate-events branch July 29, 2026 21:38
Marcelo5444 pushed a commit to Marcelo5444/deepagents that referenced this pull request Jul 30, 2026
langchain-ai#5157)

Fixed duplicated Auto-mode approval/denial messages in the
`deepagents-code` transcript after resuming a human approval.

---

`AutoModeHITLMiddleware` emits its sanitized transcript events (`Auto
fallback: human approval required …`, `Auto denied […]`, `Auto
classifier unavailable: …`) over the custom stream writer *before*
calling `interrupt()`. LangGraph restarts the entire `after_model` node
when the user answers the approval, so every pre-interrupt emission ran
a second time and the same line was rendered twice. Emissions now go
through a bounded, LRU-evicted ledger keyed by thread + action batch, so
a replay is a no-op while a later batch can still emit the same text.
This also generalizes the existing per-invocation coalescing of N-tool
batches.

Made by [Open
SWE](https://openswe.vercel.app/agents/2c64987a-3e83-05bc-66fc-c20f43dd845e)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
> [!CAUTION]
> Merging this PR will automatically publish to **PyPI** and create a
**GitHub release**.

For the full release process, see
[`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md).

---

_Release notes preview: keep this section in sync with the package
`CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`,
not this PR description — keep them aligned anyway so the PR stays an
accurate historical record for reviewers and anyone returning later._

---


##
[0.1.50](deepagents-code==0.1.49...deepagents-code==0.1.50)
(2026-07-30)

### Highlights

- Added project hooks workspace trust and expanded Hooks v2 support with
client and server lifecycle events plus runtime feedback
([#5105](#5105),
[#5104](#5104),
[#4997](#4997),
[#5045](#5045)).
- Added an option to mute the “YOLO is active” toast
([#5103](#5103)).
- Made the splash screen `thread` ID clickable to copy it
([#5173](#5173)).
- Show `ask_user` answers directly on the answered tool row
([#5100](#5100)).
- Show a toast when submitting an empty required `ask_user` answer
([#5095](#5095)).
- Added thread message counts to the Debug Console
([#5117](#5117)).

### Fixes and improvements

- Gated Hooks v2 behind `DEEPAGENTS_CODE_EXPERIMENTAL` and improved hook
resume stability across identity and Command tool results
([#5146](#5146),
[#5176](#5176)).
- Kept server hook state out of task results
([#5164](#5164)).
- Stopped duplicate Auto transcript events during interrupt replay
([#5157](#5157)).
- Kept `/update` and `/install --package` prompts responsive
([#5127](#5127)).
- Refreshed the `/threads` cache after each turn
([#5174](#5174)).
- Anchored toasts above the chat input and added a toast when media is
dropped into a free-text question
([#5101](#5101),
[#5099](#5099)).
- Improved thread status message styling and links
([#5118](#5118)).
- Made resume hints echo the launched command name
([#5119](#5119)).
- Scoped selection copy to the clicked screen
([#5140](#5140)).
- Ignored mouse hits on detached widgets
([#5114](#5114)).

_End release notes preview._

---

> [!NOTE]
> A **New Contributors** section is appended to the GitHub release notes
automatically at publish time (see [Release
Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline),
step 2).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
Mason Daugherty (mdrxy) added a commit that referenced this pull request Jul 30, 2026
#5157)

Fixed duplicated Auto-mode approval/denial messages in the
`deepagents-code` transcript after resuming a human approval.

---

`AutoModeHITLMiddleware` emits its sanitized transcript events (`Auto
fallback: human approval required …`, `Auto denied […]`, `Auto
classifier unavailable: …`) over the custom stream writer *before*
calling `interrupt()`. LangGraph restarts the entire `after_model` node
when the user answers the approval, so every pre-interrupt emission ran
a second time and the same line was rendered twice. Emissions now go
through a bounded, LRU-evicted ledger keyed by thread + action batch, so
a replay is a no-op while a later batch can still emit the same text.
This also generalizes the existing per-invocation coalescing of N-tool
batches.

Made by [Open
SWE](https://openswe.vercel.app/agents/2c64987a-3e83-05bc-66fc-c20f43dd845e)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 30, 2026
> [!CAUTION]
> Merging this PR will automatically publish to **PyPI** and create a
**GitHub release**.

For the full release process, see
[`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md).

---

_Release notes preview: keep this section in sync with the package
`CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`,
not this PR description — keep them aligned anyway so the PR stays an
accurate historical record for reviewers and anyone returning later._

---


##
[0.1.50](deepagents-code==0.1.49...deepagents-code==0.1.50)
(2026-07-30)

### Highlights

- Added project hooks workspace trust and expanded Hooks v2 support with
client and server lifecycle events plus runtime feedback
([#5105](#5105),
[#5104](#5104),
[#4997](#4997),
[#5045](#5045)).
- Added an option to mute the “YOLO is active” toast
([#5103](#5103)).
- Made the splash screen `thread` ID clickable to copy it
([#5173](#5173)).
- Show `ask_user` answers directly on the answered tool row
([#5100](#5100)).
- Show a toast when submitting an empty required `ask_user` answer
([#5095](#5095)).
- Added thread message counts to the Debug Console
([#5117](#5117)).

### Fixes and improvements

- Gated Hooks v2 behind `DEEPAGENTS_CODE_EXPERIMENTAL` and improved hook
resume stability across identity and Command tool results
([#5146](#5146),
[#5176](#5176)).
- Kept server hook state out of task results
([#5164](#5164)).
- Stopped duplicate Auto transcript events during interrupt replay
([#5157](#5157)).
- Kept `/update` and `/install --package` prompts responsive
([#5127](#5127)).
- Refreshed the `/threads` cache after each turn
([#5174](#5174)).
- Anchored toasts above the chat input and added a toast when media is
dropped into a free-text question
([#5101](#5101),
[#5099](#5099)).
- Improved thread status message styling and links
([#5118](#5118)).
- Made resume hints echo the launched command name
([#5119](#5119)).
- Scoped selection copy to the clicked screen
([#5140](#5140)).
- Ignored mouse hits on detached widgets
([#5114](#5114)).

_End release notes preview._

---

> [!NOTE]
> A **New Contributors** section is appended to the GitHub release notes
automatically at publish time (see [Release
Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline),
step 2).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dcode Related to `deepagents-code` fix A bug fix (PATCH) internal User is a member of the `langchain-ai` GitHub organization open-swe size: L 500-999 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant