Skip to content

fix(chat): recover current conversation past closed history - #6949

Merged
huangruiteng merged 2 commits into
mainfrom
codex/chat-current-session-recovery-20261020
Oct 20, 2026
Merged

huangruiteng merged 2 commits into
mainfrom
codex/chat-current-session-recovery-20261020

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

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_failed remains visible. Goal discovery reuses the same selector. Related to #6934 and #6937; intended base: main.

Author Declaration

  • Written by: model_agent — OpenAI Codex, GPT-6 family.
  • Specification and revision: reproduced recovery defect described above; existing Session identity contract in docs/integrations/session-runtime-control-plane-adapter.md at ef77d906.
Criterion Disposition Path Validation
Closed history cannot own current controls implemented src/data/use-conversation-history.ts closed-first / closed-only browser cases
Keep historical messages and visible recovery failures implemented same history owner retained transcript and failed-current cases
Use the same rule for Goal discovery implemented src/views/dashboard-page.tsx TypeScript/build and packaged navigation

Self-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

  • Tested revision: 42fb84defdc4a09802b44685027169bd44f2baac for the production source and packaged Core/frontend; final head dae52135a46dd2cbf706191528b42c9ccb8e81fd adds only the after/mobile screenshots.
  • Run state: finished
  • Input classes: synthetic, authorized_private_read_only
Check kind Result Evidence / limitation
static passed pnpm run build: dashboard TypeScript, Vite and verified Chat bundle.
regression_parity passed node smoke/conversation-history-order-browser-smoke.mjs: all 11 scenarios, including the original eight history races, closed-first, closed-only and failed-current.
unit passed pnpm run test:conversation-returns: source isolation, late return, deduplication and transport uncertainty.
real_backend passed Disposable native profiles with real Codex app-server and actual Chat HTTP handler: original Session/thread/home recovery, coexistence and backend reopen; seven refusal cases without admitting a Turn. The native profile owner is unchanged by this PR.
real_entrypoint passed Debug packaged native App with the exact committed Core/frontend: retained history, accurate model/effort, editable unsent composer, switching profiles, normal Quit/reopen. No model inference or business-message replay. This is QA, not formal installed-App adoption.
static passed Final-head standard canary premerge: four direct checks, five catalog checks, eight risk-profile smokes and public-boundary scan. Exact-diff change-quality receipt recorded and verified.
manual passed Desktop and 390px views; no horizontal overflow. All public images use synthetic data. Original owner-local Session content was inspected read-only and stayed unchanged; no private details are published.
integration not_run Remote PR CI has not been claimed green. Production signed OTA activation and original-account execution are outside this frontend fix.

Frontend / Visual Evidence

  • UI impact: changed
  • Source data: synthetic
  • Boundary: browser first-viewport captures of the packaged Core/frontend used by the debug native App. Before: Core/frontend 04c147c6. After: Core/frontend 42fb84def; final head adds images only. Native QA binary is unchanged. No public preview deployment; local QA services are stopped after validation.
  • Attention review: removes the false availability error and restores existing model and runtime controls, with no extra labels or controls. Closed history remains in the transcript; actual recovery failures remain visible.
  • Craft review: existing layout, tokens and state treatments retained; desktop and mobile capture the changed conversation state.

Before:

Closed row incorrectly owns the conversation

After:

Original usable conversation and model restored

Mobile:

Same conversation at 390px

Type of Change

  • Bug fix
  • Test update

LoopX Area

  • Public docs or presentation surface (dashboard)
  • Host or runtime integration

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

  • No private state, credentials, raw traces, internal links or local machine paths in the diff or public evidence.
  • No duplicated benchmark execution.
  • Scoped to the reproduced conversation recovery defect.
  • No paired RFC changes; bilingual diff check passed.
  • First viewport evidence is embedded above.
  • Every commit has a DCO sign-off.

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 loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

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 正文中的前后及窄屏首屏,画面符合声明的合成数据边界。

关键代码讲解

  1. currentChannelSession 在服务端原有顺序上,按精确 agent_id 和 status !== "closed" 选择当前行。它不重排、不改写输入,也不跳过恢复失败;sessions-only 类型让发现入口直接复用。实际基线/当前函数对相同 20 组完整输入执行,16 组完整输出相同,4 组关闭会话变化符合预期。
  2. useConversationHistory 继续保管 scope、快照、重试及发送门。当前来源必须有对应快照;较早历史读失败不能重启当前流。它使用新的选择结果决定当前身份,同时保留完整历史列表,因而选取与正文不会互相覆盖。
  3. 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.

@huangruiteng
huangruiteng merged commit 13deb64 into main Oct 20, 2026
30 of 42 checks passed
@huangruiteng
huangruiteng deleted the codex/chat-current-session-recovery-20261020 branch October 20, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants