Skip to content

fix(desktop): clarify partial transcript ranges - #3880

Merged
Astro-Han merged 2 commits into
apache:mainfrom
Sun-GLiang:fix/3875-partial-history-range-notice
Aug 29, 2026
Merged

fix(desktop): clarify partial transcript ranges#3880
Astro-Han merged 2 commits into
apache:mainfrom
Sun-GLiang:fix/3875-partial-history-range-notice

Conversation

@Sun-GLiang

@Sun-GLiang Sun-GLiang commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • explain when Desktop is displaying a bounded historical transcript range instead of the complete conversation
  • keep "Return to latest" as the primary recovery action and expose the notice as persistent screen-reader status
  • distinguish resident and unloaded prompt-rail landmarks while keeping unloaded prompts navigable
  • preserve the existing 512 KiB range budget and avoid full-history hydration

Before / After

Before

  • Navigating to an older prompt replaced the visible conversation with a bounded historical range without explaining that the range was partial.
  • Newer persisted messages disappeared from the conversation body, and unloaded prompt-rail landmarks looked the same as resident ones.
  • Users had to infer from the standalone “Return to latest” button that the missing messages were still saved.

After

  • A persistent accessible notice explicitly states that the user is viewing an earlier part of the conversation and that newer messages remain saved but are not currently loaded.
  • “Return to latest” remains the primary action and the notice disappears only after the latest range loads successfully.
  • Prompt-rail landmarks visually and accessibly distinguish resident prompts from unloaded prompts while keeping sparse-range navigation available.
  • Transcript loading remains bounded to the existing 512 KiB range budget; no full-history hydration is introduced.

Fixes #3875

Visual evidence

Production-faithful Storybook shell, captured at 1440 × 900 with the same bounded historical transcript state:

Before After
Only the standalone “返回最新消息” action hints that newer messages are omitted; every prompt-rail landmark is rendered alike. The persistent notice explains that this is an earlier range and that newer messages remain saved; unloaded rail landmarks are outlined.
Before: partial range with only Return to latest After: explicit partial-history notice and sparse rail states

Verification

  • npm --workspace @maka/ui test — 235 tests passed
  • node --test apps/desktop/dist/main/__tests__/desktop-transcript-range-store.test.js — 16 tests passed
  • npm run build
  • npm run typecheck
  • npm run lint
  • npm run format:check
  • git diff --check

The regression coverage includes an eight-turn transcript larger than DESKTOP_TRANSCRIPT_RANGE_MAX_BYTES, historical and intermediate prompt navigation, return to latest, renderer range bounds, accessible notice markup, and resident/unloaded prompt-rail semantics.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Maka analyzed the issue, implemented the UI and regression coverage, and ran the listed validation commands.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Sun-GLiang
Sun-GLiang force-pushed the fix/3875-partial-history-range-notice branch 2 times, most recently from d481f85 to 9eb99b9 Compare August 26, 2026 08:35
@M4n5ter
M4n5ter force-pushed the fix/3875-partial-history-range-notice branch 2 times, most recently from ba2a115 to efb4ff5 Compare August 26, 2026 09:44
@M4n5ter
M4n5ter force-pushed the fix/3875-partial-history-range-notice branch from efb4ff5 to 6d33618 Compare August 26, 2026 09:51
@github-actions github-actions Bot added the effort/M Under 500 readable lines label Aug 27, 2026

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making bounded transcript history clearer without bringing back full-history hydration.

The notice now explains when newer durable history exists, while “Return to latest” preserves the direct recovery path. Building the prompt rail from the existing landmark index also keeps navigation anchored to the current authority: non-resident prompts become loadable targets rather than a second copy of transcript state.

I verified exact head 424bb1a69e33607c7c603a7ad384967b62f9b535: the UI suite passes 237 tests, the transcript range-store suite passes 16 tests, and Desktop typecheck, changed-file Biome, git diff --check, and the hosted test check all pass. I found no P0–P3 issues and no code or tests that should be removed.

Review analysis was assisted by Codex; Astro-Han reviewed the result and owns this approval.

简体中文

谢谢在不恢复全历史加载的前提下,把有界 transcript 的状态解释清楚。

现在提示会明确说明仍有较新的持久化历史,“Return to latest”也保留了直接返回最新范围的路径。Prompt rail 继续以现有 landmark index 为唯一导航来源,未加载的 prompt 只是可加载目标,没有复制出第二份 transcript 状态。

我验证了精确 head 424bb1a69e33607c7c603a7ad384967b62f9b535:UI suite 237 项、transcript range-store suite 16 项全部通过;Desktop typecheck、改动文件的 Biome、git diff --check 和 GitHub test 也通过。没有发现 P0–P3 问题,也没有应删除的代码或测试。

本次审查分析由 Codex 协助;Astro-Han 审阅了结果并对本次 Approve 负责。

onReturnToLatest,
}: TranscriptHistoryNoticeProps) {
return (
<div

@Astro-Han Astro-Han Aug 29, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making this state understandable. [P3, non-blocking] One visual suggestion: this is a navigation-position state rather than a warning, so the full-width bordered block feels a little heavier than necessary.

Could we make it a quiet, single-line Astryx composition inside the reading column, using HStack, secondary Text, and a small ghost Button? “Viewing earlier messages” with “Return to latest” should be enough. I would also avoid exposing “saved but not loaded” or teaching loaded residency through hollow rail ticks, since those are implementation details.

This does not need to block the PR.

简体中文

谢谢把这个状态解释清楚。[P3,非阻塞] 有一个视觉上的建议:这是对话浏览位置的状态,不是警告,所以现在通栏、描边的区块稍微有些重。

可以考虑在阅读栏内使用更轻的 Astryx 单行组合,例如 HStack、次要层级的 Text 和一个小号 ghost Button。“Viewing earlier messages”配合“Return to latest”就足够了。我也建议避免使用“已保存但尚未加载”或通过空心 rail 刻度让用户理解驻留状态,因为这些属于实现细节。

这个建议不需要阻塞当前 PR。

@Astro-Han

Astro-Han commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Thanks again for working through this. The current fix is correct for the architecture it is built on, and I do not think #3880 should grow into an architectural rewrite.

While reviewing it, though, I noticed a deeper follow-up that seems worth capturing in a separate issue. The 512 KiB value is a range-fetch budget, not a conversation limit. Today, jumping outside the resident range makes DesktopTranscriptReplica replace the current durable projection with the newly fetched range. The renderer virtualizer therefore sees only resident turns, while the prompt rail navigates through a separate sampled landmark index. The notice in this PR correctly explains the resulting state, but ideally the product would not need to expose that state at all.

Would you be interested in opening and taking an architecture issue for this? A possible direction would be:

  • Keep Runtime Host and storage as the durable transcript authority.
  • Keep the bounded range fetches and current cache budgets.
  • Add a lightweight, pageable logical turn-position index across the conversation, without duplicating message bodies.
  • Let the renderer virtualizer preserve unloaded ranges as logical gaps and load content around the viewport.
  • Keep the prompt landmarks as a navigation projection rather than a second transcript authority.
  • Preserve the scroll anchor while content pages are loaded and evicted.

That would let the user navigate one continuous logical transcript while memory and DOM usage remain bounded. Raising the 512 KiB budget would only move the threshold, whereas joining data paging to the existing virtual window would address the cause.

The large-transcript fixture and range-store tests from this PR look like a useful starting point for that work. I think you are well positioned to take it on, and I would be happy to help review the design incrementally.

This is follow-up architecture work, not a defect in #3880, so it does not change my approval.

Review analysis was assisted by Codex; Astro-Han reviewed the data path and owns this feedback.

简体中文

再次谢谢你把这个问题处理清楚。当前修复在既有架构下是正确的,我也不认为应该把 #3880 扩大成一次架构重写。

不过在审查过程中,我注意到一个值得单独记录的深层改进。512 KiB 是一次范围读取的预算,并不是对话历史的上限。现在跳转到驻留范围之外时,DesktopTranscriptReplica 会用新读取的范围替换当前的持久化投影。Renderer 的 virtualizer 因而只能看到当前驻留的 turns,而 prompt rail 使用的是另一份抽样 landmark index。这个 PR 的提示正确解释了由此产生的状态,但理想情况下,产品并不需要把这层状态暴露给用户。

你是否愿意开一个独立的架构 issue,并继续推进这个改进?可以考虑以下方向:

  • Runtime Host 和 storage 继续作为 transcript 的持久化权威。
  • 保留有界的范围读取和当前缓存预算。
  • 为整段对话增加一份轻量、可分页的逻辑 turn position index,但不复制消息正文。
  • 让 Renderer virtualizer 保留未加载范围的逻辑位置,并围绕 viewport 加载内容。
  • Prompt landmarks 继续只负责导航,不成为第二份 transcript 权威。
  • 内容页面加载和淘汰时保持滚动锚点稳定。

这样既能让用户在一条连续的逻辑 transcript 中导航,也能继续限制内存和 DOM 使用。单纯提高 512 KiB 只会把阈值向后移动,把数据分页和现有虚拟窗口真正接起来才是在解决根因。

当前 PR 中的大 transcript fixture 和 range-store 测试看起来很适合作为后续工作的起点。你已经梳理了不少相关行为,我觉得很适合继续推进;如果采用分阶段设计,我也愿意逐步协助审查。

这是后续的架构改进,不是 #3880 本身的缺陷,因此不会改变我的 Approve。

本次审查分析由 Codex 协助;Astro-Han 审阅了数据路径并对这些反馈负责。

@Astro-Han

Copy link
Copy Markdown
Contributor

Thanks, I opened a focused follow-up for the architectural direction discussed above: #4123.

I kept it separate from #3880 and linked the existing fixture and tests as a starting point. There is no additional work required for this PR.

简体中文

谢谢,我已经把上面讨论的架构方向整理成一个独立的后续 issue:#4123

它与 #3880 保持独立,并把当前已有的 fixture 和测试作为后续工作的起点。这个 PR 不需要再增加额外改动。

@Astro-Han
Astro-Han merged commit 53a4aa7 into apache:main Aug 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(desktop): sparse history range makes persisted prompts appear missing

2 participants