[PR #169] [MERGED] fix(middleware): avoid unnecessary REMOVE_ALL_MESSAGES in PatchToolCallsMiddleware #175

Closed
opened 2026-02-16 06:17:21 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/deepagentsjs/pull/169
Author: @christian-bromann
Created: 2/2/2026
Status: Merged
Merged: 2/3/2026
Merged by: @christian-bromann

Base: mainHead: cb/improve-dangling-toolcall-fix


📝 Commits (4)

  • 3fcd246 fix(middleware): avoid unnecessary REMOVE_ALL_MESSAGES in PatchToolCallsMiddleware
  • 92fb2b2 retrigger
  • dd4ca3f fix test
  • c8f0576 add changeset

📊 Changes

4 files changed (+145 additions, -102 deletions)

View changed files

.changeset/easy-oranges-watch.md (+5 -0)
📝 libs/deepagents/src/middleware/index.test.ts (+2 -15)
📝 libs/deepagents/src/middleware/patch_tool_calls.test.ts (+129 -87)
📝 libs/deepagents/src/middleware/patch_tool_calls.ts (+9 -0)

📄 Description

Summary

  • Fix PatchToolCallsMiddleware to only trigger REMOVE_ALL_MESSAGES when there are actually dangling tool calls to patch
  • Add comprehensive test coverage for the middleware

Problem

The PatchToolCallsMiddleware was unconditionally returning REMOVE_ALL_MESSAGES on every request, even when no patching was needed. This caused:

  • Unnecessary frontend re-renders when using useStream with fetchStateHistory: true
  • UI flickering as the message list briefly empties then repopulates
  • Scroll position jumps in auto-scroll implementations

The SSE stream would emit:

  1. { id: "__remove_all__", type: "remove" }
  2. { messages: [] } (empty)
  3. { messages: [...all messages] } (restored)

Solution

Added a needsPatch flag that tracks whether any dangling tool calls were found during iteration. The middleware now returns early without modifying state when no patching is needed.

if (!needsPatch) {
  return; // Early exit - no state modification
}

Fixes #127


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/deepagentsjs/pull/169 **Author:** [@christian-bromann](https://github.com/christian-bromann) **Created:** 2/2/2026 **Status:** ✅ Merged **Merged:** 2/3/2026 **Merged by:** [@christian-bromann](https://github.com/christian-bromann) **Base:** `main` ← **Head:** `cb/improve-dangling-toolcall-fix` --- ### 📝 Commits (4) - [`3fcd246`](https://github.com/langchain-ai/deepagentsjs/commit/3fcd246128b8b6592dce89d1adee26bfb1699246) fix(middleware): avoid unnecessary REMOVE_ALL_MESSAGES in PatchToolCallsMiddleware - [`92fb2b2`](https://github.com/langchain-ai/deepagentsjs/commit/92fb2b297be0afa3cb069458d9ba39765e912e7b) retrigger - [`dd4ca3f`](https://github.com/langchain-ai/deepagentsjs/commit/dd4ca3fb6e167d855a5876e4296fcc8372d9035b) fix test - [`c8f0576`](https://github.com/langchain-ai/deepagentsjs/commit/c8f057608970ffb7bddc697998df3a955f1d0681) add changeset ### 📊 Changes **4 files changed** (+145 additions, -102 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/easy-oranges-watch.md` (+5 -0) 📝 `libs/deepagents/src/middleware/index.test.ts` (+2 -15) 📝 `libs/deepagents/src/middleware/patch_tool_calls.test.ts` (+129 -87) 📝 `libs/deepagents/src/middleware/patch_tool_calls.ts` (+9 -0) </details> ### 📄 Description ## Summary - Fix `PatchToolCallsMiddleware` to only trigger `REMOVE_ALL_MESSAGES` when there are actually dangling tool calls to patch - Add comprehensive test coverage for the middleware ## Problem The `PatchToolCallsMiddleware` was unconditionally returning `REMOVE_ALL_MESSAGES` on every request, even when no patching was needed. This caused: - Unnecessary frontend re-renders when using `useStream` with `fetchStateHistory: true` - UI flickering as the message list briefly empties then repopulates - Scroll position jumps in auto-scroll implementations The SSE stream would emit: 1. `{ id: "__remove_all__", type: "remove" }` 2. `{ messages: [] }` (empty) 3. `{ messages: [...all messages] }` (restored) ## Solution Added a `needsPatch` flag that tracks whether any dangling tool calls were found during iteration. The middleware now returns early without modifying state when no patching is needed. ```typescript if (!needsPatch) { return; // Early exit - no state modification } ``` Fixes #127 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-16 06:17:21 -05:00
yindo closed this issue 2026-02-16 06:17:21 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagentsjs#175