Commit Graph
10 Commits
Author SHA1 Message Date
nesquena-hermes 1633658fa5 test(#6717): assert the non-consecutive repeat condition
The production guard now ends the burst only on a non-consecutive repeat
(A -> B -> A), so a window needing a second re-measure is not mistaken for
oscillation. Update the structural assertion to that condition.
2026-09-24 12:57:14 +00:00
webtecnica 05b6d5b472 fix(perf): absolute burst cap + per-render provenance (#6717) 2026-08-30 21:29:25 -03:00
webtecnica e5742d5dda fix(perf): cycle-aware measurement burst tracking (#6654)
Replace the flat 2-render burst cap with cycle-aware tracking: unseen
monotonic window keys proceed (genuine convergence A->B->C->settled is
never capped), while repeated oscillating keys (A->B->A->B) terminate the
burst so the rAF/measure loop stays bounded. Thread an internal-measurement
provenance marker through both rAF layers into renderMessages() and reset
burst state on every unmarked (externally initiated) render trigger, so a
pending internal callback can never starve a legitimate new cycle.
2026-08-30 21:29:24 -03:00
webtecnica f88cc78286 fix(perf): per-burst retry budget lifecycle, reset only on external render (#6717) 2026-08-30 21:29:24 -03:00
webtecnica 4df32ea332 fix(perf): don't reset virtual measurement retry budget on window-key oscillation (#6654)
_scheduleMessageVirtualMeasurementRefresh() reset _messageVirtualMeasurementRetryCount
every time _messageVirtualMeasurementCycleKey changed. When WebKit alternates
between two measured window-metric sets (A -> B -> A -> B) after
getBoundingClientRect(), each key transition renewed the two-render budget and
the requestAnimationFrame/geometry-measurement loop never terminated
(WebContent ~30% CPU for minutes after session recovery).

The MESSAGE_VIRTUAL_MEASUREMENT_MAX_RERENDERS budget now caps the whole
convergence burst globally; the cycle-key branch only records the new key.
The budget still resets at the correct lifecycle boundaries:
_markMessageVirtualMeasurementsSettled() and _clearMessageVirtualHeightCache().

Adds a deterministic node-based regression test driving the real ui.js
function with alternating keys ['A','B','A','B'] (before: 4 scheduled
re-renders; after: 2), plus a stable-key guard and a structural test.
2026-08-30 21:29:24 -03:00
fe12eebbf3 perf(chat): virtualize long message transcripts (#500) (#4214)
* perf(chat): virtualize long message transcripts (#500)

* fix(chat): preserve virtual height cache on append (#500)

* fix(chat): bound virtual tail follow-up (#500)

* fix(chat): surface older history and bound virtual rerenders (#500)

* fix(chat): stabilize virtual history fallback (#500)

* fix(chat): preserve virtual compression anchors (#500)

* Keep virtualization regressions aligned with rebased sources (#500)

* fix(chat): preserve virtual heights across prepends (#500)

* test(update): isolate restart timing checks (#814)

* fix(chat): restore render contracts around virtual cache

* fix(chat): preserve legacy assistant anchor predicates

* fix(#3714): restore worklog-disclosure capture after HTML-cache early-return

Deep-review finding: the capture of _captureWorklogDetailDisclosureState was
moved before the HTML-cache fast-path return, failing the invariant test
test_render_rebuild_preserves_worklog_detail_disclosure_click_state (it must
not traverse the previous-session DOM when the cache path returns early).
Moved it back to just before inner.innerHTML='' (after the cache return).

Co-authored-by: Rod Boev <rod.boev@gmail.com>

* fix(#3714): restore Transparent Stream rehydration in HTML-cache fast path

Full-suite gate caught test_issue3820_chat_activity_display_mode failure: the
virtualization rewrite of the renderMessages HTML-cache fast-path block dropped
the _rehydrateTransparentStreamDom(inner) call (master has it; PR had 2 of 3
occurrences). On a cache-restore session switch, Transparent Stream controls
lost their property-assigned handlers. Restored the call in the same position
master has it (right after _sessionHtmlCacheSid=sid).

Co-authored-by: Rod Boev <rod.boev@gmail.com>

* fix(#3714): preserve live turn on scroll-rebuild even with zero streamed text

Opus ship-review residual (now fixed, not deferred): the live-turn re-attach
after a scroll-triggered virtualized rebuild was gated on _preservedLen>0, so a
turn showing only Activity/tool/worklog blocks with no streamed text yet (mid
tool-call) would not be preserved — scrolling up into history on a >80-row
transcript mid-stream could blink those live-only blocks for a frame. Broaden
the gate to also restore when the preserved turn has MORE structural blocks than
the rebuilt (lagging-S.messages) turn. Hoisted the _structuralCount helper above
the gate; whole-turn-vs-segment restore logic unchanged.

Co-authored-by: Rod Boev <rod.boev@gmail.com>

* chore(release): stamp v0.51.423 (Release OJ) for #500 transcript virtualization

---------

Co-authored-by: Rod Boev <rod.boev@gmail.com>
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
2026-06-14 19:11:32 -07:00
Hermes Agentandai-ag2026 8e1ac89baa Stage 397: PR #2692 — fix(ui): invalidate transcript cache on same-count content changes
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 17:14:37 +00:00
ai-ag2026 1559c70a41 fix: preserve chat scroll across final render 2026-05-09 02:15:35 +02:00
Michael Lam 311e69b0ba fix: preserve scroll on stream completion 2026-05-05 09:23:29 -07:00
Michael Lam b2f35a41e1 fix: window long session message rendering 2026-05-05 01:12:07 +00:00