Repository navigation
perf(conversations): 仅在标签页可见时拉取会话详情,消除打开工作区时的并发请求风暴 - #913
Merged
xintaofei merged 8 commits intoOct 10, 2026
Merged
Conversation
Every open tab keeps its ConversationTabView mounted (that is what preserves a background session's stream and scroll state), so the ungated useConversationDetail() call there fired one get_folder_conversation per open tab the moment the workspace restored its tab set — each one a tail window of up to TAIL_TURNS_DEFAULT (120) turns. Measured on a workspace with 49 open tabs: 49 concurrent requests in a single 100 ms burst, 25.4 MB decoded (7.2 MB gzipped), issued before the active conversation had painted. The cost grows with the number of open tabs AND with the length of each conversation, which is why reopening the workspace gets slower the longer it is used. Gate the auto-fetch on visibility instead of on mount. A hidden tab keeps its session, its scroll state and its position in the strip; it fetches on the first frame it becomes visible (tab switch, group selection, tiling), which is also the first moment its detail is actually needed. While here, stop seeding a child tab's summary from the full transcript: reconcileChildSummaries only reads detail.summary off the response, but it asked for the legacy unwindowed detail, so a long child session transferred and re-parsed megabytes of turns to read a title and a status. It now asks for tailTurns: 1.
… detail loads A tab restored behind another one is mounted hidden with a runtime session (its mount effects create one) but no detail, because its fetch now waits until it is shown. The render that shows it reported that session as settled, with no detail and nothing loading. It is also the render that makes the tab active, so the auto-connect gate, which waits on detailLoading for the stored session id, let the connect out with no session id. Depending on which finished first, that either spawned an agent on session/new only to kill it once the detail landed, or kept the tab on that new session, so the next prompt re-pointed the conversation away from its history. useConversationDetail now counts a fetch it is about to start as loading. It uses the same admission rule as fetchDetail, shared as sessionHoldsActiveTurns, so the gate stays closed from the first render until the stored session id arrives.
…t as it fails A failed detail fetch leaves no detail and nothing in flight, which is exactly what useConversationDetail's auto-fetch keys on, so the hook re-requested it on the very next render. A transcript that will not parse was re-parsed in a hot loop, a server that was down was hammered until it came back, and the error flickered in and out instead of staying next to its Reload action. A failure now waits for a retry schedule instead: 1, 2, 4, 8 and 16 seconds, then the error stays on screen until the user reloads. A loaded detail or a different conversation starts the schedule over, and a hidden view holds its pending retry until it is shown again.
The retry schedule for a failed detail fetch used to end after its fifth step, leaving the error up until the user pressed Reload. The loop it replaced did recover on its own once the server was reachable again, so an outage longer than half a minute now needed a manual Reload where it once did not. The last step, 30 seconds, now repeats for as long as the failure lasts and the view stays on screen. A view picks its conversation back up within half a minute of the server returning, and the error stays readable in between.
Gating the auto-fetch on visibility also stopped a hidden tab from refetching after its runtime session was dropped. Closing the sub-agent viewer drops the session it shares with an open tab; if that tab is hidden and holds a live connection, the next streamed batch recreates the session with live data and no detail, which fetchDetail never fills in, so the tab came back without its history. Only the first load waits for the tab to be shown now: once a view has held a detail it fetches the way every view did before. The gate also takes isActive, so the loading signal the auto-connect gate reads no longer leans on the tab store keeping the active tab its group's selected one.
…d read Only a detail load's own result clears detailLoading, and two readers that never set the flag could invalidate that load by bumping the fetch generation: the cross-client viewer sync poll and the older-turns page. The load's result was then dropped as stale, and if the poll never committed (every read failing) or a page landed instead, the session stayed loading for good: spinner, auto-connect held shut, overlay folds stopped. The poll overlap is common, since a load's own read can backfill the title and that upsert is a nudge. The poll now waits for a load in flight to land, without spending an attempt, and polls on from there, giving up after 30 seconds behind a load that never settles. An older-turns page is not issued while a load is in flight; the near-top trigger fires again the next time the list is scrolled up into the top, and the loader row pages on click.
Collaborator
|
codeg work task |
xintaofei
added a commit
that referenced
this pull request
Oct 10, 2026
This one lets agents answer with more than text: turn on Generative UI, and a reply can show cards, tables and other interactive components right in the conversation. The chat column can be widened by dragging its edges, chat animations can be switched off, and a conversation can be maximized while files are open beside it. Claude Code moves up to 0.89.1 and Codex to 2.2.2, along with five more bundled agents. Alongside that: the terminal panel comes back after a page reload, a workspace with many tabs opens much faster, remote workspaces keep reconnecting through outages and reopen even while their server is offline, the Open Folder dialog can create a folder, and a failed turn ends with one line saying why. ## New - **Agents can reply with interactive cards and tables** once you turn on "Generative UI (json-render)" under Settings → Skill Packs → UI: start a message with `/json-render` (`$json-render` in Codex) or just ask to see something as cards or a table, and the reply renders as live components while it streams. - **The chat column can be made wider or narrower** by dragging its left or right edge, or under Settings → Appearance → Chat width, and double-clicking an edge puts it back to the default. (#911, @sumanx) - **Chat animations can be switched off** under Settings → Appearance, so expanding, collapsing, working indicators and scrolling in the conversation happen instantly, while spinners keep turning. (#911, @sumanx) - **A conversation can be maximized while files are open beside it**, from the Maximize button at the right end of its tab strip, and Restore brings the files back just as you left them. - **The Open Folder dialog can create a new folder** and step into it, so a project can start from an empty folder, in the desktop app and the web version alike. (#881, @Jonathan-Asher) - **A remote workspace window can open the local workspace** from Quick actions in the status bar, the macOS Window menu, or the page shown when its connection fails or expires. (#891, @ker2xu) ## Improved - **Updated bundled agents:** Claude Code ACP 0.89.1 (Claude Code 2.1.293), Codex ACP 2.2.2 (Codex CLI 0.160.1), Cline 3.0.70, CodeBuddy 2.164.0, Grok 1.0.51, Qoder 1.1.67, Hermes 0.21.6. - **A failed turn ends with one muted line giving the agent's own error** in Codex, Claude Code, Cline and Qoder conversations, both as it happens and when you reopen the conversation. - **A workspace with many open tabs opens much faster**, because a tab sitting behind another now loads its conversation the first time you switch to it instead of every tab downloading its conversation at once. (#913, @Flyneen) - **Resizing the window is smoother**, as the workspace no longer runs extra full-page layouts on every step. (#898, @sumanx) - **Slash commands show the arguments they take** in the `/` menu, the message box's Add menu and the automation editor. - **Codex answers `/mcp` with the live status of each MCP server**, and `/mcp reconnect` works there too. - **Claude Code's Agent card shows the effort a sub-agent was asked to run at**, next to its model. - **Claude Haiku 5.5 is now the suggested Haiku model** in Claude Code's settings and in the model provider dialogs. - **On phones, the web version tints the browser bar and Android's navigation bar to match your light or dark theme**, and adding it to the home screen installs codeg as an app with a full-bleed icon, even behind a sign-in proxy. (#863, @eyjohn) ## Fixed - **Reloading the page or reconnecting no longer loses the terminal panel**: its tabs come back with their commands still running and their output in place, and a finished command's output stays until you close its tab. (#830, @dawNotPoi; #749 reported by @kekxv) - **Claude Code no longer leaves a conversation spinning for hours** after you send a message during a turn it started on its own, such as after a background task finished, and that message now gets a single reply. (#893 reported by @Luis-WowApps) - **Sending Claude Code a message while it is still writing a tool call no longer fails the turn.** - **Messages you send while a Claude Code turn is running now stay in its history**, and a background task that finished mid-turn shows its result there instead of looking unfinished. - **A Claude Code conversation's title no longer flips back and forth** between its first and its latest message in the sidebar and in a linked chat channel topic when Claude Code can't generate a title, as behind a gateway that refuses the request. - **Replies from turns a custom agent starts on its own**, such as after a background job, now stay in the conversation after a reload instead of only showing live. (#903 reported by @andrehqh) - **A custom agent that runs Claude Code's ACP adapter now takes messages inserted into the current turn directly**, as the built-in Claude Code does, and those messages stay in its history. (#892 reported by @andrehqh) - **A remote workspace keeps reconnecting through network outages** and shows a notice while it does, instead of giving up after three failed attempts and calling the connection expired, which now happens only when the server rejects the token. (#887, #890, @ker2xu) - **Remote workspace windows reopen at launch even while their server is offline**, and pick up in place once it is back. (#887, #890, @ker2xu) - **Clicking the Dock icon on macOS brings up the workspace you used last**, a minimized remote one included, instead of always the local window, and launching codeg again on Windows and Linux does the same. (#887, #889, @ker2xu) - **Custom agents from the ACP registry now install on Windows**, where most binary entries looked for a doubled name like `kilo.exe.exe`, and an agent published as a plain executable rather than an archive can be installed too. (#905 reported by @trueai-org) - **Agents installed with their official installer into `~/.local/bin`, such as Hermes, are now found when codeg isn't started from a terminal**, instead of showing as not installed. (#888, @Sma1lboy; #875 reported by @toptiersnowman) - **An OpenCode 2.x installed on your system now connects**, as codeg no longer passes it the `--port` and `--hostname` options its `acp` command rejects. (#909, @Liang-HZ) - **Effort choices now match the model you picked** under Agent defaults in Settings → Collaboration and in the to-do and automation editors, instead of following the agent's default model. (#910, @Liang-HZ) - **Scrolling up while a reply streams no longer pulls you back to the bottom**, whether you use the wheel over a code block, touch, the keyboard or the scrollbar. (#899, @Adam-Dalloul) - **Reordering conversation tabs no longer leaves a tab's transcript blank** until you scroll it. (#901, @Adam-Dalloul) - **In a sent message, a `/word` or `$word` shows as a command only when the agent actually offers that command or skill**, so paths like `/tmp` stay plain text. (#902, @Adam-Dalloul) - **The tab strip no longer squeezes and springs back when you open or close a side panel.** (#912, @sumanx) - **The sidebar, side panel and terminal panel no longer wobble while you resize the window.** (#897, @sumanx) - **Collapsing a thinking block or tool card no longer flashes its content for a frame**, and after a click in the conversation, pressing Esc, copying or coming back from another window no longer draws a focus outline around it. (#896, @sumanx) - **A conversation that fails to load now retries at growing intervals, up to every 30 seconds**, with the error and Reload button staying in view, instead of re-requesting nonstop while the error flickers. - **A conversation no longer stays stuck loading** when a background sync or a page of older messages arrives while it loads. - **Token usage is counted more accurately**: Codex no longer counts cache writes as fresh input, with existing Codex conversations recounted, and CodeBuddy totals now include requests that end in a tool call. - **Cline history no longer shows the messages Cline marks as internal**, such as compaction summaries, hook context and the prompt it sends itself after you approve switching to Act mode. - **Claude Code conversations reopened from history show a 1M context window for models that have one natively**, such as Opus 4.7 and later, Sonnet 5 and later, Haiku 5.5, Fable and Mythos, instead of 200K. - **Backups now include Codex's conversation names**, and restoring merges Codex's and Kimi's session lists with what is already there instead of skipping or overwriting them, so restored conversations keep their names and folders. - **On macOS, computer use presses return after typing into a Chromium or Electron app when the agent asks to submit**, instead of treating the typing as failed because the field reads back empty. - **The desktop app writes its logs to the same folder however it is started**, and Settings → Runtime Logs opens the folder actually in use and shows each file's current size. (#893 reported by @Luis-WowApps) ## Note - **Codex ACP 2.2 needs Node.js 20.3.0 or later**, as every message fails on Node.js 20.0 through 20.2, and the environment diagnostics now check the full Node.js version each agent needs rather than only the major version. - **With Claude Code ACP 0.88.0 and later, a running Monitor no longer shows in the background task strip**, so it can't be stopped from there. - **Generative UI is off by default**: agents get the json-render skill in conversations started after you turn it on, turning it off removes the skill from every agent, and a json-render skill of your own is never replaced. - **A tab restored behind another shows a brief loading state the first time you switch to it**, while its conversation loads. - **The terminal panel comes back after a page reload but not after codeg itself restarts**, since a restart ends the terminals' processes and their tabs then report the session as unavailable. Thanks to @sumanx, @ker2xu, @Adam-Dalloul, @Liang-HZ, @dawNotPoi, @eyjohn, @Jonathan-Asher, @Sma1lboy and @Flyneen for contributing to this release, and to @kekxv, @toptiersnowman, @andrehqh, @Luis-WowApps and @trueai-org for the reports. ----------------------------- # 发布版本 0.35.0 这一版让智能体的回复不止是文字:打开「生成式界面」后,回复里可以直接出现卡片、表格等可交互的组件。聊天区域可以拖动边缘调宽,动画可以关闭,旁边开着文件时会话也能最大化。Claude Code 升级到 0.89.1,Codex 升级到 2.2.2,另有五个内置智能体更新了版本。 同期还有:刷新页面后终端面板会原样回来,标签页很多的工作区打开快多了,远端工作区断网后会一直重连、服务器离线时也能照常恢复窗口,「打开文件夹」对话框可以新建文件夹,回合失败时末尾会用一行文字说明原因。 ## 新增 - **智能体可以用交互式卡片和表格来回复了**——在「设置 → 技能包 → 界面」里打开「启用 json-render 生成式界面」后,用 `/json-render`(Codex 里是 `$json-render`)开头提问,或者直接让它用卡片、表格来展示,回复就会在输出过程中渲染成可交互的组件。 - **聊天区域的宽度可以调整了**——拖动会话列的左右边缘,或在「设置 → 外观 → 聊天区域宽度」里设置,双击边缘即可恢复默认宽度。(#911,@sumanx) - **聊天区域动画可以关闭了**——在「设置 → 外观」里关掉后,会话里的展开收起、工作状态提示和滚动都会立即完成,只有转圈图标照常转动。(#911,@sumanx) - **旁边开着文件时,会话也能最大化了**——点会话标签栏最右侧的「最大化」,会话就会占满中间区域,点「还原」后文件原样回来。 - **「打开文件夹」对话框里可以新建文件夹了**,建好后直接进入,方便从一个空文件夹开始新项目,桌面版和网页版都支持。(#881,@Jonathan-Asher) - **远端工作区窗口可以直接打开本地工作区了**——入口在状态栏的「快捷操作」、macOS 的 Window 菜单,以及连接失败或过期时显示的页面上。(#891,@ker2xu) ## 改进 - **内置智能体版本更新:** Claude Code ACP 0.89.1(Claude Code 2.1.293)、Codex ACP 2.2.2(Codex CLI 0.160.1)、Cline 3.0.70、CodeBuddy 2.164.0、Grok 1.0.51、Qoder 1.1.67、Hermes 0.21.6。 - **回合失败时,末尾会用一行浅色文字给出智能体自己的报错**,Codex、Claude Code、Cline 和 Qoder 的会话都支持,实时能看到,重新打开会话后也还在。 - **开着很多标签页的工作区打开得快多了**——挡在其他标签页后面的标签页,要等你第一次切过去时才加载会话,不再一打开就把每个标签页的会话都下载一遍。(#913,@Flyneen) - **调整窗口大小更流畅了**,工作区不再在每一步缩放时额外做整页布局。(#898,@sumanx) - **斜杠命令会显示它接受的参数**,`/` 菜单、输入框的「添加」菜单和自动化编辑器里都能看到。 - **Codex 的 `/mcp` 会列出每个 MCP 服务器的实时状态**,`/mcp reconnect` 也能直接在会话里用。 - **Claude Code 的 Agent 卡片会在模型旁边显示子智能体被指定的思考强度。** - **Claude Code 设置和模型供应商对话框里推荐的 Haiku 模型改为 Claude Haiku 5.5。** - **在手机上使用网页版时,浏览器顶栏和 Android 导航栏会跟随浅色或深色主题**,添加到主屏幕会安装成独立应用,图标铺满不带白边,部署在登录代理后面也能正常安装。(#863,@eyjohn) ## 修复 - **刷新页面或重新连接后,终端面板不再丢失**——标签页会带着仍在运行的命令和已有输出回来,命令结束后的输出也会一直保留到你关闭它的标签页。(#830,@dawNotPoi;#749 由 @kekxv 反馈) - **Claude Code 不会再让会话一直转圈好几个小时**——它自己发起回合时(比如后台任务结束后)你发的消息,现在会得到一次回复并正常结束。(#893 由 @Luis-WowApps 反馈) - **Claude Code 还在生成工具调用时发送消息,不会再让回合失败。** - **Claude Code 回合进行中发送的消息会保留在历史记录里**,回合中途完成的后台任务在历史里也会显示结果,不再像是没有完成。 - **Claude Code 会话的标题不会再来回切换了**——Claude Code 生成不了标题时(比如网关拒绝了生成标题的请求),侧栏和消息渠道里绑定的话题以前会在第一条和最新一条消息之间反复变化。 - **自定义智能体自己发起的回合,回复在刷新后也会留在会话里**,比如后台任务完成后它自动开始的回合,不再只在实时显示时才能看到。(#903 由 @andrehqh 反馈) - **运行 Claude Code ACP 适配器的自定义智能体,插入当前回合的消息现在会直接送进回合**,和内置的 Claude Code 一样,这些消息也会保留在历史记录里。(#892 由 @andrehqh 反馈) - **远端工作区断网后会一直尝试重连**,重连期间会给出提示,不再连续失败三次就放弃并把连接显示成已过期,现在只有服务器拒绝令牌时才会显示过期。(#887、#890,@ker2xu) - **服务器离线时,远端工作区窗口在下次启动时也会照常恢复**,等服务器恢复后原地接着用。(#887、#890,@ker2xu) - **在 macOS 上点击程序坞图标,会切到你最近用过的工作区**,最小化的远端工作区也会还原,不再总是拉出本地窗口,Windows 和 Linux 上再次启动 codeg 也是这样。(#887、#889,@ker2xu) - **ACP 注册表里的自定义智能体在 Windows 上能正常安装了**——以前大多数二进制条目会去找 `kilo.exe.exe` 这样多了一层 `.exe` 的文件,直接以可执行文件而非压缩包发布的智能体现在也能安装。(#905 由 @trueai-org 反馈) - **用官方安装器装在 `~/.local/bin` 里的智能体(比如 Hermes),不从终端启动 codeg 时也能被找到**,不再显示为未安装。(#888,@Sma1lboy;#875 由 @toptiersnowman 反馈) - **你自己安装的 OpenCode 2.x 现在能连上了**,codeg 不再给它传 `acp` 命令不接受的 `--port` 和 `--hostname` 参数。(#909,@Liang-HZ) - **Effort 选项现在跟随你选的模型**——「设置 → 协作」的「子智能体配置」以及待办任务和自动化编辑器里都是如此,不再按智能体默认模型列出。(#910,@Liang-HZ) - **回复输出过程中向上滚动,不会再被拽回底部**,无论是在代码块上滚动滚轮,还是用触摸、键盘或拖动滚动条。(#899,@Adam-Dalloul) - **调整会话标签顺序后,标签页的聊天记录不会再一片空白、要滚动一下才出现。**(#901,@Adam-Dalloul) - **已发送消息里的 `/词` 或 `$词`,只有确实是智能体提供的命令或技能时才显示成命令**,`/tmp` 这样的路径会保持普通文字。(#902,@Adam-Dalloul) - **展开或收起侧栏时,顶部标签栏不会再先被挤压再弹回。**(#912,@sumanx) - **调整窗口大小时,侧栏、右侧面板和终端面板不会再来回抖动。**(#897,@sumanx) - **收起思考块或工具卡片时不会再闪现一帧内容**,在会话里点击后按 Esc、复制或从别的窗口切回来,也不会再出现包住整个会话的焦点框。(#896,@sumanx) - **会话加载失败后会按逐渐拉长的间隔自动重试,最长每 30 秒一次**,报错和「重新加载」按钮一直显示,不再不停地重复请求、报错一闪一闪。 - **后台同步或更早的消息恰好在会话加载期间到达时,会话不会再一直停在加载中。** - **Token 用量统计更准确了**——Codex 不再把写入缓存的部分算作新输入,已有的 Codex 会话会重新统计,CodeBuddy 的总量也补上了以工具调用结束的请求。 - **Cline 的历史记录不再显示 Cline 标记为内部的消息**,比如压缩摘要、钩子上下文,以及你批准切换到 Act 模式后它自己发出的提示。 - **从历史记录打开的 Claude Code 会话,原生支持 1M 上下文的模型会显示 1M 上下文窗口**,比如 Opus 4.7 及以后、Sonnet 5 及以后、Haiku 5.5、Fable 和 Mythos,不再显示 200K。 - **备份现在包含 Codex 的会话名称**,恢复时会把 Codex 和 Kimi 的会话列表与现有内容合并,而不是跳过或整个覆盖,恢复的会话能保留名称和所在文件夹。 - **在 macOS 上,智能体在 Chromium 或 Electron 应用里输入文字并要求提交时,电脑操作会在输入后按下回车**,不再因为输入框读回为空而判定输入失败。 - **桌面版无论以什么方式启动,日志都写到同一个文件夹**,「设置 → 运行日志」打开的就是正在写入的文件夹,并显示每个文件的当前大小。(#893 由 @Luis-WowApps 反馈) ## 注意 - **Codex ACP 2.2 需要 Node.js 20.3.0 或更高版本**,在 Node.js 20.0 到 20.2 上每条消息都会失败,环境诊断现在也会按每个智能体要求的完整 Node.js 版本检查,不再只看主版本号。 - **从 Claude Code ACP 0.88.0 起,运行中的 Monitor 不再出现在后台任务条里**,也就无法在那里停止它。 - **生成式界面默认关闭**——打开后新开始的会话才会带上 json-render 技能,关闭时会从所有智能体移除该技能,你自己的同名 json-render 技能不会被替换。 - **挡在其他标签页后面恢复的标签页,第一次切过去时会短暂显示加载中**,等会话内容加载完成。 - **终端面板能在刷新页面后恢复,但 codeg 本身重启后不能**,重启会结束终端里的进程,对应的标签页会显示终端会话不可用。 感谢 @sumanx、@ker2xu、@Adam-Dalloul、@Liang-HZ、@dawNotPoi、@eyjohn、@Jonathan-Asher、@Sma1lboy 和 @Flyneen 为本次发布做出的贡献,也感谢 @kekxv、@toptiersnowman、@andrehqh、@Luis-WowApps 和 @trueai-org 的反馈。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
工作区打开的标签页越多、每个会话越长,重新打开 Web 工作区就越慢。
在本机(localhost,无网络延迟)对一个 49 个打开标签页的工作区做过实测:重新打开
/workspace后,170 ms 处一次性并发发出 49 个get_folder_conversation请求,100 ms 内全部发完,解码后合计 25.4 MB(gzip 后 7.2 MB)。这 49 个请求与opened_tab表的 49 行一一对应 —— 也就是说,用户一个会话都还没看,就已经为所有打开的标签页各拉了一份最多 120 轮的完整会话内容。单个请求的体积随会话长度线性增长(实测 156 轮 = 723 KB、245 轮 = 1.04 MB、261 轮 = 1.37 MB,单个最大 2.76 MB),因此打开耗时由「标签页数量 × 会话长度」共同决定,用得越久越慢。
远程访问场景下代价被进一步放大:这 25 MB 要走网络,还要在手机端解析并渲染成百上千个 turn。
根因
ConversationDetailPanel把所有打开的标签页都保持挂载(keep-alive 是刻意设计,用于保住后台会话的流式连接与滚动位置),而ConversationTabView中的useConversationDetail(effectiveConversationId)没有任何可见性判断 —— 挂载即拉取。于是「恢复标签页」这一个动作,等价于对每个标签页各发一次get_folder_conversation(id, { tailTurns: 120 })。另外,
tab-store的reconcileChildSummaries只读取detail.summary,却调用了不带 window 的getFolderConversation(id)(legacy 全量响应)—— 为了读一个标题,把子会话的整份 transcript 传过来再解析一遍。改动
useConversationDetail的自动拉取改为由「可见性」驱动,而不是「挂载」ConversationTabView新增isVisibleprop(激活标签页,或 tiled 分组下的全部成员);useConversationDetail(effectiveConversationId, { enabled: isVisible })。invisible,不产生任何可感知代价。子会话摘要不再拉取全量 transcript
reconcileChildSummaries改为getFolderConversation(id, { tailTurns: 1 })。summary与 window 无关,照常返回;tailTurns: 1会 round-align 到最后一个用户轮,足以支撑标签标题与状态。测试
use-conversation-detail.test.tsx:新增 visibility gating 用例(隐藏时不发请求;变为可见时按默认 tail window 发一次);tab-store-child-summary-window.test.ts:锁定子会话摘要请求使用最小窗口;tab-context.test.tsx中对应的断言。验证
pnpm test:579 个文件 / 8645 个用例全部通过tsc --noEmit:通过eslint(含 prettier):通过影响与兼容性
tailTurns是既有参数(MAX_WINDOW_TURNS = 500,tailTurns: 1会被 clamp 到合法区间);fetchDetail本来就会对存在 live/optimistic 数据的会话直接跳过。后续可做(本 PR 未包含)
tailTurns目前按「轮」计数、不设字节上限,单次仍可能返回数 MB,建议改为「轮数上限 + 字节/token 上限」双约束;list_conversations返回全量(本机实测 3560 条 / 1.41 MB / 3.5–5.1 s;而get_stats只返回 407 字节也要 3.5 s,说明每次请求都在全盘扫描会话存储),建议加时间窗口/分页并走 DB 或缓存;get_conversation没有任何 window 参数,长会话一次性返回(实测最长 12.65 MB),建议与 folder 会话对齐。