acpmux: open long chats from the end of their log, with a size cap (cx-2lv1k)
Opening a long chat no longer reads its whole event log. A tail page, or an older page while scrolling up, now reads only the segments it needs, and a new maxBytes caps how much one page sends, so a remote session's open stays small however long or heavy the chat is.
What changes
- Pages from the end read from the end.
- Before,
_acpmux/attachand_acpmux/eventswithbeforeSeqparsed every segment from the first one while keeping a ring of the last N records, so opening a chat cost as much as reading all of it. On cmux server that cost is paid on every open. Store::scan_backnow walks segments newest first. It skips a segment whose first record is already at or past the cursor, after reading one line, and parses lines in reverse until the page is full. The in-memory store gets the same order from its existing scan.
- Before,
maxByteson attach and events. A page ends once its records' JSON reaches the cap, always holding at least one record, and reportshasMore. Without the parameter, pages are unchanged. The pane starts sending it in #20536.- Unchanged:
hasMoresemantics, filters and forward paging. The existing paging test intranscript_events.rscovers them.
Evidence
tail_pages_read_only_the_newest_segments: a session spread over many small segments still returns the right newest page and the page before it when its oldest segment can't be read. Red on 8735797 (hosted Linux): the newest-N scan reads that segment and fails.opening_a_long_chat_stays_within_its_payload_budget: a 5000-turn chat with 4 KB tool outputs, opened the way the pane opens it. The serialized attach reply, which is what a remote client downloads, must be at most 160 KiB, end on the latest record and sayhasMore. Red on 2a28fb2, where attach ignoresmaxBytes.- Green: the
transcript_events::module on hosted Linux and macOS at the head, with results in the PR checks.
Measured
history_page_cost (an ignored measurement in the same file): 3000 turns, 183,006 records, 60.6 MiB in 8 MiB segments. Debug build on the fleet, before (bcf6bb7) and after (e02fe59):
| before | after | |
|---|---|---|
| Open (attach, newest 400) | 218 ms | 3โ4 ms |
| Older page from mid-history | 109 ms | 9 ms |
| Older page near the start | 13 ms | 18 ms |
| Whole log, for reference | 170 ms | 179 ms |
A page near the start reads every later segment's first line, then the segments it needs, so it costs about what it did. The fleet's Rust step can't pass --ignored, so both runs used a measurement-only copy that writes its numbers to a file, branch op-next-replay/history-cost-measure; this PR doesn't include it.
Changelog
- Fixed: Long agent chats open quickly instead of reading their whole history first, which mattered most for remote sessions.
๐ค Generated with Claude Code