Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughUpdated history trimming and pruning logic in the agent module to treat assistant messages and their consecutive tool message groups as atomic units. Removal or collapsing operations now process entire groups together, preventing partial removal when a group would overlap protection boundaries. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/agent/history.rs (1)
99-109: Add a direct straddling-boundary regression test.This branch is the new behavior in
emergency_history_trim, but the shownemergency_history_trimtests insrc/agent/loop_.rsonly cover fully droppable histories. A case where anassistant + tool...run overlapskeep_recentwould lock in the new “skip, don’t split” rule.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/history.rs` around lines 99 - 109, Add a regression test for emergency_history_trim that covers the “straddling boundary” case: construct a history with an assistant message followed by tool_count tool messages such that the group partially overlaps the protected suffix (using history.len() and keep_recent to compute cutoff), call emergency_history_trim, and assert the group is left intact (no partial removal) and dropped counter reflects only fully-droppable groups; locate and extend the existing emergency_history_trim tests in loop_.rs and use the same helpers/setup, targeting the code paths around emergency_history_trim, i, tool_count, and dropped to ensure the skip-not-split behavior is enforced.src/agent/history_pruner.rs (1)
132-134: Preferdrainfor contiguous group removal.Both sites are deleting a contiguous range from a fixed index, so repeated
removejust shifts the tail N times and obscures the atomic-group intent.♻️ Proposed cleanup
- for _ in 0..tool_count { - messages.remove(i + 1); - } + drop(messages.drain(i + 1..=i + tool_count)); ... - for _ in 0..=tool_count { - messages.remove(i); - } + drop(messages.drain(i..=i + tool_count));Also applies to: 169-171
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/agent/history_pruner.rs` around lines 132 - 134, The loop that calls messages.remove(i + 1) tool_count times should be replaced with a single contiguous removal using messages.drain(start..end) to express atomic group deletion; compute start = i + 1 and end = start + tool_count and call messages.drain(start..end) (or drain_exact if available) instead of the repeated removes. Apply the same change at the second site that uses the same pattern (the block around the other occurrence referencing messages, tool_count, and i) so both contiguous-group deletions use drain for clarity and efficiency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/agent/history_pruner.rs`:
- Around line 132-134: The loop that calls messages.remove(i + 1) tool_count
times should be replaced with a single contiguous removal using
messages.drain(start..end) to express atomic group deletion; compute start = i +
1 and end = start + tool_count and call messages.drain(start..end) (or
drain_exact if available) instead of the repeated removes. Apply the same change
at the second site that uses the same pattern (the block around the other
occurrence referencing messages, tool_count, and i) so both contiguous-group
deletions use drain for clarity and efficiency.
In `@src/agent/history.rs`:
- Around line 99-109: Add a regression test for emergency_history_trim that
covers the “straddling boundary” case: construct a history with an assistant
message followed by tool_count tool messages such that the group partially
overlaps the protected suffix (using history.len() and keep_recent to compute
cutoff), call emergency_history_trim, and assert the group is left intact (no
partial removal) and dropped counter reflects only fully-droppable groups;
locate and extend the existing emergency_history_trim tests in loop_.rs and use
the same helpers/setup, targeting the code paths around emergency_history_trim,
i, tool_count, and dropped to ensure the skip-not-split behavior is enforced.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7d68f20b-61bb-45b7-b863-f51cd47b649f
📒 Files selected for processing (2)
src/agent/history.rssrc/agent/history_pruner.rs
|
@claude fix the nitpicks |
PR Reviewer Guide 🔍(Review updated until commit 7a4ae8f)Here are some key observations to aid the review process:
|
|
/review |
|
Persistent review updated to latest commit 7a4ae8f |
|
/review |
|
Persistent review updated to latest commit 7a4ae8f |
|
/review |
|
Persistent review updated to latest commit 7a4ae8f |
1 similar comment
|
Persistent review updated to latest commit 7a4ae8f |
User description
Summary
Addresses CodeRabbit review feedback from PR #74 — four issues where multi-tool groups (assistant + N consecutive tool messages) could be split at protection/keep_recent boundaries, orphaning tool messages and causing provider API errors.
history_pruner.rs): scan the full consecutive tool run before checking protection; only collapse when every message in the group is unprotectedhistory_pruner.rs): verify all tool messages in the group are unprotected before dropping; skip the entire group if any member is protectedhistory_pruner.rstests): relax the check to allowtoolpreceded bytool(valid in multi-tool groups), not just preceded byassistanthistory.rs): count the full tool run regardless of the keep_recent cutoff; only drop the group if it lies entirely before the protected suffixTest plan
history_prunertests pass (including multi-tool-group and realistic-pressure scenarios)cargo fmt --all -- --checkpassescargo clippy --lib -p hrafn -- -D warningspasses with zero warningschecks-on-pr.yml) should pass🤖 Generated with Claude Code
Summary by CodeRabbit
PR Type
Bug fix, Enhancement
Description
Phase 1 collapse checks full tool run protection
Phase 2 budget drop skips partially protected groups
Emergency trim handles atomic tool groups correctly
Test assertions updated for multi-tool sequences
Diagram Walkthrough
flowchart LR Start["Assistant Message"] --> Tools["Consecutive Tool Messages"] Tools --> Check{"All Unprotected?"} Check -->|"Yes"| Action["Collapse or Drop Group"] Check -->|"No"| Skip["Skip Entire Group"]File Walkthrough
history_pruner.rs
Atomic handling for multi-tool pruning phasessrc/agent/history_pruner.rs
toolpreceded bytoolhistory.rs
Atomic group awareness for emergency trimsrc/agent/history.rs
emergency_history_trimcounts full tool run regardless of cutoff