Repository navigation
fix(chat): recover current conversation past closed history - #6949
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
APPROVE — dae52135a46dd2cbf706191528b42c9ccb8e81fd。完整七路径评审通过,未发现阻塞问题。代码结论、合并资格及合并权限分别核验。
动机
用户回到一个已有 Goal 时,希望读到原对话、看到它的实际模型,并继续在原上下文中工作。较新的关闭会话原先会遮蔽较早的可用会话:正文仍显示旧历史,当前控制却绑定关闭行,模型消失,LoopX 模式出现 conversation unavailable。不修复会增加人工排查和重开会话的成本。
当前版本在既有选择器中排除 closed,保留选定执行器的第一个非关闭会话;关闭历史仍进入正文,resume_failed 仍明确可见。隔离的真实 Chat 存储和 HTTP 读取证实关闭行先于原 ready 行;实际构建的界面恢复原模型、两段历史和可编辑的未发送草稿,390px 下没有横向溢出。原两段消息逐项不变,未产生 Turn 或模型调用。该检查使用合成 adapter,不代表正式安装或原账号执行已验收。
改动思路
修复现有消费者即可解决这个选择错误。只改排序会保留错误的关闭行;另设可用标记或新会话管理器会复制权威。现在 Goal 发现也复用同一个选择器,避免概览与对话采用不同规则。
Session 是原生对话及其执行身份,历史消息与当前可操作身份是两个读取用途。排除关闭行只影响当前控制,不删除其历史,不更换账号、原生目录、线程或已选择的执行器。服务端仍拥有恢复、创建会话和发送准入;前端一次观察不授予执行权。普通路径无需增加用户确认或配置步骤。
具体改动
依据为 docs/integrations/session-runtime-control-plane-adapter.md,固定规范版本 ef77d9064607dfc69edd3f21926dc4c22126c44b。以下标识映射原文未编号条款:original-session-identity 保留原 Session/线程/配置身份;observed-model-readback 使用实际 Session 模型而非目录猜测;history-read-recovery 保留历史及不可读状态,原当前来源未读到时仍禁止发送;separate-activation 保持普通对话、显式模型选择与 Agent Loop 启动的既有边界。前三项由选择器、现有历史 owner 和真实 HTTP/构建界面验证;最后一项由代码与无 Turn 读回验证。正式 OTA/安装、真实模型调用和完整跨渠道工作不在本次选择缺陷的交付范围内,仍由既有恢复工作承担。
七个路径共 +30/-8:两个生产文件、两个既有回归文件和三张合成截图。新增量主要是三个关闭/失败场景,没有新模块、配置、协议字段或持久化状态。已逐张检查 PR 正文中的前后及窄屏首屏,画面符合声明的合成数据边界。
关键代码讲解
currentChannelSession在服务端原有顺序上,按精确agent_id和status !== "closed"选择当前行。它不重排、不改写输入,也不跳过恢复失败;sessions-only 类型让发现入口直接复用。实际基线/当前函数对相同 20 组完整输入执行,16 组完整输出相同,4 组关闭会话变化符合预期。useConversationHistory继续保管 scope、快照、重试及发送门。当前来源必须有对应快照;较早历史读失败不能重启当前流。它使用新的选择结果决定当前身份,同时保留完整历史列表,因而选取与正文不会互相覆盖。PersonalGoalHome的发现分支在 L2087 复用该选择器;原恢复分支也调用同一 owner,再交既有createChatSession(..., "resume_latest")路径处理。发现不再直接取列表第一行。实际构建界面从 Goal 进入对话,原模型、历史和草稿均可读。
对主干的风险
最强反例是关闭行后面虽有旧 ready 行,但真正最新的非关闭行是 resume_failed,或者所选执行器的当前快照读失败。把这些也当历史略过,会掩盖真实失败并可能创建错误替代会话。20 组对照保留 failed/busy/未知状态、不可恢复标记、执行器隔离及原输入顺序;只剩关闭行时返回空当前身份。11 个完整浏览器场景覆盖这三个新增分支及原有八种迟到、重试、刷新、切换竞争。
本轮独立验证:TypeScript/Vite 与 Chat bundle 构建通过;串行历史浏览器场景 11/11;会话返回检查通过;真实 HTTP/store 历史恢复、真实 HTTP/SQLite/Core 原会话绑定检查通过;19 个原生目录/HTTP 绑定测试通过;模型菜单 64 项双语/可访问断言通过(SSR)。干净精确七路径 premerge 为 4 项直接检查、5 项 catalog、8 项风险检查及 1 项公私边界检查通过,无 manual hold。未查询远端 CI。
保留早先失败:首次与构建并行的开发服务器检查中,两个场景发生 Vite 浮层/等待超时,其余九项通过;没有删除断言或放宽超时。构建结束后完整串行重跑、独立函数对照、真实 HTTP 边界及实际打包界面补验所改不变量。开发服务器首次启动的间歇原因未宣称已修复。私有 UI 夹具还曾因模式响应漏字段进入页面兜底;修正夹具响应后在原浏览器任务重载完成检查,产品源码未因此修改。后续通过不会改写这些历史失败。
隔离浏览器会沿既有入口恢复会话,并可能更新会话元数据;整个浏览器过程不称为纯只读。原消息保持不变,业务发送为零、Turn 为零。模型/native adapter 与若干无关工作区投影为合成输入,部分无关服务故意不可用;不据此声称全 App、正式安装、真实账号或 live Lark 资格。主干较新的 completed-history 后端整理未改本次客户端选择 owner;完整合并组合和安装采用仍是后续独立边界。
我的整体评价
本次选择缺陷达到 goal_achieved。long_horizon 为 improved,限于保留可继续使用的原会话身份;user_experience 为 improved,限于从原 Goal 直接读回模型和历史、编辑草稿,无新增必需交互。两者都不推断模型完成了更多工作或总成本收益。
在既有选择器中修复条件,并让发现入口复用它,是相称且可回滚的边界。未引入新的会话事实、状态同步、默认执行、指令义务或权限。当前完整代码可批准;实际安装、原生执行与受保护合并继续由原 owner 的资格及授权决定。
English verdict: APPROVE — dae5213. Full seven-path review. The shared selector excludes closed Sessions from current controls while retaining their history and visible resume failures. Twenty paired inputs, all eleven isolated browser cases, real HTTP/store/binding checks, the built desktop/narrow journey and local premerge support this bounded repair. Earlier development-server and private-fixture failures remain recorded. No installed/native-model, CI, merge-authority or complete recovery-program claim.
Goal And Delivered Outcome
A recently closed Codex Session could precede an older usable Session in the same Goal channel. The UI kept displaying the older transcript while binding current controls to the closed row: model settings disappeared and LoopX mode reported
conversation unavailable.Current controls now select the newest non-closed Session for the selected executor. Closed transcripts remain readable, and
resume_failedremains visible. Goal discovery reuses the same selector. Related to #6934 and #6937; intended base:main.Author Declaration
docs/integrations/session-runtime-control-plane-adapter.mdatef77d906.src/data/use-conversation-history.tssrc/views/dashboard-page.tsxSelf-check: reviewed all seven changed paths, repository instructions, existing history/recovery consumers and actual packaged behavior. No server lifecycle, model dispatch, profile permissions or account configuration changes.
Scope And Continuation
Complete for this selection defect. This is a frontend consumer fix in the existing native Chat capability. The broader desktop activation and installed-account recovery work remains separate. Bounded refactoring applied: reuse the existing selector in discovery through a sessions-only input type; no additional state or abstraction.
Validation
42fb84defdc4a09802b44685027169bd44f2baacfor the production source and packaged Core/frontend; final headdae52135a46dd2cbf706191528b42c9ccb8e81fdadds only the after/mobile screenshots.pnpm run build: dashboard TypeScript, Vite and verified Chat bundle.node smoke/conversation-history-order-browser-smoke.mjs: all 11 scenarios, including the original eight history races, closed-first, closed-only and failed-current.pnpm run test:conversation-returns: source isolation, late return, deduplication and transport uncertainty.Frontend / Visual Evidence
04c147c6. After: Core/frontend42fb84def; final head adds images only. Native QA binary is unchanged. No public preview deployment; local QA services are stopped after validation.Before:
After:
Mobile:
Type of Change
LoopX Area
Technical Direction
Native conversation recovery; no new roadmap claim.
Shared-authority RFC fixture impact
N/A: no authority backend, routing or promotion changes.
Boundary Checklist