Skip to content

fix(loop): prevent compaction from splitting tool_call/tool_result pairs - #45

Merged
angel-manuel merged 1 commit into
masterfrom
fix/compaction-tool-pair-atomicity
Apr 17, 2026
Merged

angel-manuel merged 1 commit into
masterfrom
fix/compaction-tool-pair-atomicity

Conversation

@angel-manuel

Copy link
Copy Markdown
Contributor

Summary

  • Compaction split messages purely by count (len - keep_recent), so an assistant message with tool_calls could land in the summary while its matching Role::Tool responses stayed in recent — producing histories with dangling tool_call_ids that providers reject.
  • find_safe_split walks the proposed split backward until no unanswered tool call straddles the boundary. If no safe split exists above start, the existing guard skips compaction entirely.
  • 5 new unit tests covering: no tool calls, single-pair straddle, multi-call chain, walk-back into system prompt, earlier completed pair unaffected.

Test plan

  • cargo test -p overloop --lib compaction — 9 tests pass (4 existing + 5 new)
  • Full suite: 422 tests pass, pre-commit hooks green
  • cargo clippy clean

🤖 Generated with Claude Code

@sentry

sentry Bot commented Apr 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.95%. Comparing base (349b5f5) to head (fa16535).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #45      +/-   ##
==========================================
+ Coverage   91.81%   91.95%   +0.13%     
==========================================
  Files          50       50              
  Lines        6685     6798     +113     
==========================================
+ Hits         6138     6251     +113     
  Misses        547      547              
Files with missing lines Coverage Δ
loop/src/compaction.rs 97.95% <100.00%> (+1.74%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The compactor split messages purely by count, so an assistant message
with tool_calls could end up in the summary while its matching
Role::Tool responses stayed in recent (or vice versa).  This produces
histories with dangling tool_call_ids that providers reject.

Walk the proposed split backward until no unanswered tool_call
straddles the boundary.  If no safe split exists above `start`, the
caller's existing guard skips compaction entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@angel-manuel
angel-manuel force-pushed the fix/compaction-tool-pair-atomicity branch from ad66df2 to fa16535 Compare April 17, 2026 11:13
@angel-manuel
angel-manuel merged commit a644966 into master Apr 17, 2026
8 checks passed
@angel-manuel
angel-manuel deleted the fix/compaction-tool-pair-atomicity branch April 17, 2026 11:19
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