refs(#2264): Phase 4 — replace Session.messages: Vec<Message> with AppendLog#2579
refs(#2264): Phase 4 — replace Session.messages: Vec<Message> with AppendLog#2579encyc wants to merge 1 commit into
Conversation
…ith AppendLog AppendLog gains Deref<Target=Vec<Message>> + DerefMut + From/Into impls, making it a transparent drop-in for Vec<Message>. All existing .len(), .iter(), .push(), .remove(), .clone() calls work through Deref. - AppendLog: add Deref/DerefMut, From<Vec>/Into<Vec>, into_inner() - Remove explicit iter()/len()/is_empty()/as_slice() — Deref provides the correct return types (std::slice::Iter vs impl Iterator) - Session.messages: Vec<Message> → AppendLog - 10 assignment sites: add .into() or .into_inner() - 2 test assertions: compare &Vec references via &* deref
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Thanks @encyc for taking the time to contribute. This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in Please read |
| impl std::ops::DerefMut for AppendLog { | ||
| fn deref_mut(&mut self) -> &mut Self::Target { | ||
| &mut self.messages | ||
| } | ||
| } |
There was a problem hiding this comment.
DerefMut exposes the full Vec<Message> mutation API, silently defeating the append-only contract. Callers in the current codebase already reach through it to call .remove(0) (engine.rs:1821), .truncate(idx) (engine.rs:1139), .clear() (capacity_flow.rs:690), last_mut() (turn_loop.rs:1127), and .extend_from_slice() (session_manager.rs:745). The type's name and doc-comment still say "append-only", but there is no compile-time barrier left to prevent arbitrary removals or rewrites — any future call site can silently violate the invariant without the compiler warning. If the intent is for AppendLog to enforce the constraint, DerefMut should be removed and explicit methods added for each needed mutation. If unrestricted mutation is acceptable, the "append-only" branding in the doc-comment should be updated to avoid misleading future readers.
| impl std::ops::DerefMut for AppendLog { | |
| fn deref_mut(&mut self) -> &mut Self::Target { | |
| &mut self.messages | |
| } | |
| } | |
| // NOTE: DerefMut is intentionally omitted. Exposing &mut Vec<Message> | |
| // would allow callers to call .remove() / .truncate() / .clear() etc., | |
| // defeating the append-only invariant. Add explicit methods for each | |
| // permitted mutation instead (e.g. `truncate`, `clear`, `remove_first`). | |
| // | |
| // impl std::ops::DerefMut for AppendLog { … } ← deliberately absent |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| // so makes the API prefix differ from the bytes sent in earlier turns | ||
| // and destroys DeepSeek's KV prefix cache reuse. | ||
| self.session.messages.clone() | ||
| self.session.messages.clone().into_inner() |
There was a problem hiding this comment.
clone().into_inner() allocates a full AppendLog clone just to immediately unwrap it into Vec<Message>. Since Deref<Target = Vec<Message>> is now implemented, the inner Vec can be cloned directly without constructing the intermediate AppendLog.
| self.session.messages.clone().into_inner() | |
| (*self.session.messages).clone() |
Refs #2264 (Phase 4 — AppendLog backing store).
Summary
Replaces
Session.messages: Vec<Message>withAppendLog, theappend-only wrapper introduced in Phase 1.
AppendLognow implementsDeref<Target=Vec<Message>>+DerefMut+From/Into, makingit a transparent drop-in — all existing
.len(),.iter(),.push(),.remove(),.clone()calls work without change.AppendLog changes
Deref/DerefMutfor transparent Vec accessFrom<Vec<Message>>andInto<Vec<Message>>for conversionsinto_inner()for explicit unwrappingiter()/len()/is_empty()/as_slice()— Derefprovides
std::slice::Iter(not opaqueimpl Iterator)Files
prompt_zones.rssession.rsengine.rsturn_loop.rscapacity_flow.rstests.rsTesting
Greptile Summary
This PR wires
AppendLog(from Phase 1) as the backing store forSession.messages, replacing the rawVec<Message>. The conversion is kept transparent by addingDeref<Target=Vec<Message>>,DerefMut,From/Into, andinto_inner(), so all existing call sites continue to compile with minimal mechanical changes.AppendLoginprompt_zones.rsgainsDeref,DerefMut, and theFrom/Intopair; the redundant explicit methods (len,is_empty,iter,as_slice) are removed in favour of slice auto-deref.Session.messagesinsession.rsis retyped toAppendLog; eight assignment sites inengine.rs,capacity_flow.rs, andturn_loop.rsadd.into()to convertVec<Message>results intoAppendLog.&*to explicitly derefAppendLogto&Vec<Message>for comparison.Confidence Score: 4/5
Safe to merge — the mechanical conversions are all correct and cargo check is clean. The only concern is a design gap in prompt_zones.rs that future contributors should be aware of.
All Vec to AppendLog assignment sites are converted correctly, type inference via From/Into is sound, and the test updates are accurate. The one open question is DerefMut: it fully exposes the inner Vec for arbitrary mutation (remove, truncate, clear, last_mut), so the append-only contract is documented but not enforced at the type level. Existing callers already depend on those mutations, so no behaviour changes with this PR, but the abstraction is now leaky and could mislead future contributors into thinking the type guards against removals or rewrites.
crates/tui/src/prompt_zones.rs — the DerefMut implementation and its interaction with the append-only doc-comment.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["result.messages: Vec<Message>"] -->|".into()"| B["AppendLog"] B -->|"Deref"| C["&Vec<Message> (read-only callers)"] B -->|"DerefMut"| D["&mut Vec<Message> (remove / truncate / clear / last_mut)"] B -->|".clone().into() or .clone().into_inner()"| E["Vec<Message> (SessionUpdated / API calls)"] B -->|"into_inner()"| F["Vec<Message> (consumed)"] G["Session.messages: AppendLog"] --- BReviews (1): Last reviewed commit: "refs(#2264): Phase 4 — replace Session.m..." | Re-trigger Greptile