Skip to content

feat: preserve ToolMessage instances through conversation compaction - #414

Merged
avoidwork merged 2 commits into
mainfrom
feat/fix-toolmessage-loss-compaction
Jun 22, 2026
Merged

feat: preserve ToolMessage instances through conversation compaction#414
avoidwork merged 2 commits into
mainfrom
feat/fix-toolmessage-loss-compaction

Conversation

@avoidwork

@avoidwork avoidwork commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Description

Fixes ToolMessage instances being incorrectly converted to AIMessage during conversation compaction in the ReAct agent.

Type of Change

  • Bugfix (non-breaking change which fixes an issue)

What Was Implemented

  • src/agent/react.js — Added ToolMessage case in message rebuild logic for both callReactAgent (line 196) and callReactAgentStreaming (line 502), ensuring tool messages survive compaction
  • tests/unit/react_agent.test.js — Added 2 new tests verifying ToolMessage preservation through compaction in both streaming and non-streaming paths

Root Cause

When compactConversation triggered a context length error, the message rebuild logic only handled system, user, and fallback to AIMessage. Messages with role "tool" were incorrectly reconstructed as AIMessage instances, causing tool results to be lost.

Testing

  • 2 new unit tests added (toolmessage compaction preservation)
  • All 1178 tests pass
  • Lint clean (oxlint + oxfmt)

Coverage

  • 100% line coverage maintained
  • npm run lint passes
  • Tests pass with coverage

Related

Addresses ToolMessage instances being incorrectly converted to AIMessage during conversation compaction.

@avoidwork avoidwork self-assigned this Jun 22, 2026
- Add ToolMessage case in callReactAgent message rebuild (lines 195-196)
- Add ToolMessage case in callReactAgentStreaming message rebuild (lines 501-502)
- Write tests verifying ToolMessage preservation in both paths
- All 1178 tests pass, lint clean
@avoidwork

Copy link
Copy Markdown
Owner Author

Implementation Complete

All tasks have been implemented and verified:

  • Fix message rebuild in callReactAgent (ToolMessage case added)
  • Fix message rebuild in callReactAgentStreaming (ToolMessage case added)
  • Write unit tests for both paths
  • All 1178 tests pass
  • Lint clean

The fix ensures ToolMessage instances are preserved during conversation compaction in both streaming and non-streaming modes. Previously, tool messages were incorrectly converted to AIMessage during compaction, causing tool results to be lost.

Changes:

  • src/agent/react.js: Added ToolMessage case in message rebuild logic (both callReactAgent and callReactAgentStreaming)
  • tests/unit/react_agent.test.js: Added 2 new tests verifying ToolMessage preservation

Archived: openspec/changes/archive/2026-06-22-fix-toolmessage-loss-compaction/

@avoidwork avoidwork changed the title feat: add OpenSpec proposal for ToolMessage compaction fix feat: preserve ToolMessage instances through conversation compaction Jun 22, 2026
@avoidwork

Copy link
Copy Markdown
Owner Author

Audit Results

Goal Fulfillment

  • Goal: Preserve ToolMessage instances during conversation compaction
  • Implementation correctly handles m.role === "tool" in both callReactAgent and callReactAgentStreaming
  • Tool results are preserved through compaction cycles

Spec Compliance

  • Requirement: ToolMessage instances SHALL be preserved during compaction
  • Scenario 1: ToolMessage preserved in callReactAgent — verified via unit test
  • Scenario 2: ToolMessage preserved in callReactAgentStreaming — verified via unit test
  • Scenario 3: Tool results available after compaction — implicit in preserved instances

Task Completion

Task Status
1.1 Fix message rebuild in callReactAgent ✅ Complete
2.1 Fix message rebuild in callReactAgentStreaming ✅ Complete
3.1 Write test for callReactAgent ✅ Complete
3.2 Write test for callReactAgentStreaming ✅ Complete
4.1 Run existing test suite ✅ 1178 pass, 0 fail
4.2 Run lint ✅ Clean

Quality Check

  • Code review: Changes are minimal, focused, and follow existing patterns
  • No regressions: All 1178 existing tests pass
  • Coverage: New tests cover both code paths (non-streaming + streaming)
  • Edge cases: The fix handles the exact scenario where compaction rebuilds messages from the conversation array
  • No forbidden patterns: No console.log, no hardcoded secrets, conventional commit style applied

Verdict

All checks passed. Implementation is correct and complete.

@avoidwork
avoidwork merged commit da959d2 into main Jun 22, 2026
2 checks passed
@avoidwork
avoidwork deleted the feat/fix-toolmessage-loss-compaction branch June 22, 2026 19:07
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.

1 participant