Skip to content

Desktop: cold resume paints the REST transcript before a slow session.resume settles (salvage #90130) - #101227

Merged
teknium1 merged 1 commit into
mainfrom
salvage/cold-resume-paints-prefetched-history
Sep 2, 2026
Merged

teknium1 merged 1 commit into
mainfrom
salvage/cold-resume-paints-prefetched-history

Conversation

@teknium1

@teknium1 teknium1 commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Opening a persisted session whose runtime session.resume is slow (cold profile build: skills / MCP / memory) now paints the REST transcript as soon as it arrives instead of holding it off screen until the resume RPC settles.

Root cause: the prefetch and session.resume already ran concurrently, but the prefetched page was only applied after await resumePromise. A cold build could hold that await past the Bot Chat hydration budget, so a session with fully readable history sat on the loader and burned its retries. Later mitigations (retryHydrationTimeoutOnce, 60s hydration timeout) retry longer but never paint early.

Supersedes #90130 — reimplemented on current main with the same design (early paint under the isCurrentResume() guard, runtime path grafts only its live projection, reference-identity skip after resume). Credit to @alexandreroumieu-codeapprentice, co-authored on the commit.

Changes

  • use-session-actions/index.ts: publish the grafted REST snapshot when the prefetch resolves and isCurrentResume() holds (before await resumePromise); the post-resume chatMessageArraysEquivalent skip keeps reference identity when the acknowledgement changes nothing.
  • Same file: stamp the eagerly painted page with persisted-display transcript provenance on the runtime state, so the warm-path "hold unproven warm transcripts off the view" gate (b6eb17d) admits it on the next switch.
  • Same file: the post-rejection REST fallback skips the redundant re-publish when the early paint already shows the transcript.
  • use-session-actions.test.tsx: one new test — REST paints before a deferred session.resume settles and the painted array survives (same reference, latch clear) when that resume later rejects. The existing 500-message deferred-resume test now asserts pre-acknowledgement paint + identical reference afterwards.

Validation

Before (main) After
Electron e2e, session.resume stalled 25s (temporary backend shim, not committed) transcript never painted within 20s (loader) painted 150ms after the row click
New unit test fails ([] while resume pending) passes
e2e/large-session-resume.spec.ts (paint-count budget, one user row) 3 passed / 1 known-skip 3 passed / 1 known-skip
use-session-actions.test.tsx (96) + transcript-provenance.test.ts — all pass
tsc --noEmit, eslint on touched files — clean

Live repro: Electron e2e (built dist/, real backend, seeded session via RealSessionBuilder, session.resume handler stalled 25s via an env-gated sleep) — before: viewport stayed empty for the full 20s window on main; after: E2E stall user message 4 visible at 150ms while the resume RPC was still pending.

Infographic

Cold resume paints history first

…e session.resume settles

The REST prefetch and the gateway `session.resume` already ran concurrently,
but the prefetch result was held until the runtime resume settled. A cold
profile build (skills / MCP / memory) can keep `session.resume` pending past
the hydration budget while the complete transcript is already in hand, so a
Bot Chat sat on the loader and burned its retries with readable history
off screen.

- Publish the grafted REST snapshot as soon as the prefetch resolves and
  `isCurrentResume()` holds; the runtime path grafts only its live projection
  onto that same snapshot, and the post-resume `chatMessageArraysEquivalent`
  skip keeps reference identity when nothing changed (no second DOM build).
- Stamp the eagerly painted page with persisted-display provenance on the
  runtime state so the warm-path gate admits it on the next switch.
- REST fallback after a resume rejection skips the redundant re-publish when
  the early paint already shows the transcript.

Live repro (Electron e2e, session.resume stalled 25s via a temporary
backend shim): main never painted within 20s; with this fix the transcript
painted 150ms after the row click.

Supersedes #90130.

Co-authored-by: Alexandre Roumieu <269586168+alexandreroumieu-codeapprentice@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

૮ >ﻌ< ა ci review

ran on bb6636c — fix(desktop): cold resume paints the prefetched REST transcr

⚠️ Warnings

OSV vulnerability scan · View job

13 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 2m1s vs 4m32s (-55.5%). 6 job(s) slower, 1 faster, 1 unchanged.

  • JS & TS checks / JS & TS checks: -32.0s
  • Check no case-colliding filenames / check-case-collisions: +31.0s
  • Profile artifact check / Reject profile archives: +6.0s
  • Check no committed infographics / check-no-committed-infographics: +4.0s
  • OSV scan / Scan lockfiles / osv-scan: +3.0s

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/desktop Electron desktop app (apps/desktop/*) area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Sep 2, 2026
@alt-glitch

Copy link
Copy Markdown

This was generated by AI during triage.

Supersedes #90130 with the same early REST-prefetch paint design rebased onto current main; related to #83802's broader resume-transcript recovery work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants