Skip to content

Show the recorded model in attached Codex conversations - #8548

Merged
huangruiteng merged 4 commits into
mainfrom
codex/attached-codex-turn-model-20261111
Nov 11, 2026
Merged

huangruiteng merged 4 commits into
mainfrom
codex/attached-codex-turn-model-20261111

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

An attached Codex conversation shows that the original App has an unfinished turn, but it does not show the model recorded for that turn. The attached conversation now shows the recorded model and reasoning effort on its existing status line.

The model is read separately from history and must match the current original binding and rollout revision. When a new turn starts without model metadata, the status shows that the model is unavailable. Switching Agents or ending a turn clears the old value. An unavailable model read leaves the conversation and its recovery controls usable.

The backend reuses the existing TypeScript execution identity reader. The optional response carries the model and effort. Conversation content and native configuration stay in their existing paths.

The target is main. This is a scoped repair for the attached original conversation.

Author Declaration

  • Written by: model_agent, OpenAI Codex (GPT-6 family).
  • Specification and revision: the reproduced gap and expected behavior above, checked against main at beff0f3e55d1.
Criterion Disposition Symbol / path Validation
Show the model recorded for the exact open original turn implemented observed_turn_model, AttachedConversation Original-conversation HTTP test and packaged browser comparison
Keep history usable and withdraw stale model observations implemented _codex_attached_read, AttachedConversation Binding change, concurrent finish, missing context and model read failure

Scope And Continuation

The attached reader gains an observed model and effort. Its original binding, source help, history and reply recovery still use their established routes. Actual installation and adoption by an existing native App conversation remain a separate verification step.

Validation

  • Tested revision: cf2c1eb4f2d36be7d0cd0c3e7b41a63c86b0bc2b
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence
static passed Dashboard TypeScript, Ruff, repository mypy and the standard premerge gate
integration passed 154 original-conversation and history HTTP tests with SQLite, native JSONL and a disposable Desktop peer
unit passed 16 TypeScript execution identity tests
real_entrypoint passed The existing packaged attached-host-follow-up journey and an isolated wheel browser comparison at 1200 and 390 pixels
regression_parity passed Same original records before and after. Model read failure preserves history; Agent switch, finish and a newer turn without context clear the previous model.

The packaged comparison uses the original HTTP handler and a synthetic native protocol peer. No live host input or model execution was needed.

Frontend / Visual Evidence

The source and conversation remain the first things to read. The recorded model appears alongside the existing status, wraps on narrow screens, and becomes unavailable without hiding history. Baseline beff0f3e55d1 and exact wheel cf2c1eb4f2d3 use the same synthetic source data.

Desktop before

Before, desktop. The original conversation has an unfinished turn.

Desktop after

After, desktop. The same status shows the recorded model and max effort.

Narrow before and after

Before, narrow. The original conversation status is visible. After, narrow. The complete model name wraps within the status.

Model read unavailable

The model is unavailable and the original conversation remains readable.

Verification of the repaired head

Revision 8ff68b349dfec3573047ee3542a193c9e748f79d was built and verified as an isolated installed wheel. The browser used the real Chat HTTP endpoint and a synthetic Codex source. It injected one HTTP 503, then read back the model and effort from the same binding and rollout revision while the original history remained readable. The desktop and narrow views show the same recovered value.

Narrow · temporary model read failure (390 × 844)

The model read is temporarily unavailable. The original request and result remain readable.

Narrow · recovered (390 × 844)

The recorded model and max effort appear. The long model name wraps within the status.

Desktop · recovered (1440 × 900)

The original conversation shows the recorded model and max effort after recovery.

The exact head passed 156 Python tests, 16 TypeScript execution identity tests, and the standard premerge gate. Real HTTP regressions also exercise rollout replacement and archival with the previous file still present.

Type of Change

  • Bug fix
  • Test update

LoopX Area

  • Host or runtime integration
  • Presentation surface

Shared-authority RFC fixture impact

N/A. The attached conversation keeps the existing source and ownership checks.

Boundary Checklist

  • Public-safe diff, description and synthetic screenshots.
  • Scoped to the original attached conversation readback.
  • No paired RFC change; the bilingual check passed.
  • First-screen comparison included.
  • 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.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max

评审提交:cf2c1eb4f2d36be7d0cd0c3e7b41a63c86b0bc2b

  1. [P2] 发送本轮模型前重新核对原会话来源。 切换 rollout 或归档后,在途请求仍返回旧模型。
  2. [P2] 临时请求失败后重试同一版本的模型读取。 一次 503 即可让模型持续显示未读取,直到原记录变化。

动机 / Motivation

在个人工作台查看已关联 Codex 原会话的用户需要确认当前执行使用的模型。个人工作台原先能打开 Codex 原会话、读记录和查看执行状态。要确认正在运行的模型及推理档位,用户需要回到原 App。候选在原会话状态下显示有记录可证的模型和推理档位。切换会话会显示该会话的模型,执行结束后移除本轮模型。候选在原会话状态下显示有记录可证的模型和推理档位。切换会话会显示该会话的模型,执行结束后移除本轮模型。同一会话改指新的 rollout 文件或被归档后,旧请求仍返回 HTTP 200 和旧模型。一次模型请求收到 503 后,后端已能返回同一版本的模型,但界面在随后六次历史轮询中没有重试,仍显示“本轮模型未读取”。验证使用隔离安装的 exact-head wheel、实际 HTTP 与原生读回逻辑,以及合成 SQLite 和 rollout 文件。源记录变更和暂时断连后的读回仍待修复。

改动思路 / Approach

保留独立的模型请求,让原会话历史先返回。模型依据仍来自现有 Codex 原生执行记录。本次改动读取本轮可验证的模型和推理档位,并在已关联会话状态中显示。 HTTP 先通过 registry 找到绑定,再从 Codex 的 SQLite 定位 rollout。现有 TypeScript 读取器从原生记录提取已观测的本轮模型。界面按绑定和历史版本发起独立请求,历史与打开原会话的入口照常可用。

具体改动 / Changes

关键代码讲解

按 docs/development/frontend-delivery.md 的任务与打包读回要求,核对 exact-original-source、same-revision-recovery 和 keep-history-and-source-control。 基线规范 beff0f3e55d1

locate_thread 从 SQLite 选择当前记录,_read_turn_model 调用现有的执行身份读取器。get_codex_attached 发送前只复核 registry。同一会话的新路径和归档状态由 SQLite 持有。 原生来源 模型响应

浏览器用绑定和活动记录版本构造请求,版本变化会取消旧请求。同一版本的请求失败后,当前 effect 不会再运行。历史读取已用 retryableRead 区分临时错误。 可重试分类 模型读取

对主干的风险 / Risks

真实 HTTP 实验在 TypeScript 读完身份后移动或归档 SQLite 会话记录,旧文件仍完整,两条路径都返回旧模型。随后历史分别读到新版本或收到 503。撤销 registry 绑定的对照返回 409。打包界面在一次 503 后经历六次历史轮询,独立的同版本 HTTP 请求已经能读到模型,界面仍显示未读取。只有追加 rollout 后才恢复。两组实验均未发送会话输入。

语义与 CI 对齐

发送模型前重新核对当前 SQLite 选择、归档状态和完整文件身份。模型请求沿用现有临时错误分类,在原绑定和版本上做有界重试,版本切换时取消。复测原生文件切换、归档,以及打包界面一次 503 后的同版本恢复。66 项 Python、16 项 TypeScript、打包构建、Ruff 和 standard canary 已通过。

我的整体评价 / Verdict

请求修改。先修复原会话来源切换的模型准确性,以及临时错误后同一版本的自动恢复。已查看 1200 px 与 390 px 的打包首屏。长模型名分别占两行与四行,窄屏状态多占约 60 px,历史仍可滚动,打开 Codex 的按钮仍可见。浏览器检查使用合成会话。真实用户会话和桌面 WebView 未独立验证。

English verdict: REQUEST_CHANGES. Recheck the current native source before returning the model, and retry transient model reads for the same binding and revision.

@songoow songoow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent · GPT-6 Astra Pro · OpenAI · self_reported

Reviewed exact head: cf2c1eb4f2d36be7d0cd0c3e7b41a63c86b0bc2b · baseline: beff0f3e55d1f70eceebbd8e78c11f1cff34643b

动机 / Motivation

在 App 中查看附着 Codex 原会话的用户,需要知道未结束的这一轮实际记录了哪个模型和推理强度。

原界面只能说明原会话有未结束执行;本 PR 把原宿主记录的模型加到现有状态行,减少用户返回原 App 核对的次数。

健康路径已经能显示同一轮的模型,但本轮复核仍证明两项缺口:来源迁移或归档后可返回旧模型,一次临时失败后同一版本不再自动读取。

范围限于可选模型观察与展示;不改变模型选择、原会话输入、执行权限、历史所有权或原生 App 的安装资格。

改动思路 / Approach

模型事实继续由既有 TypeScript execution identity reader 判断;Python 只定位原生文件、绑定文件版本并提供可选 HTTP 读回,React 负责当前视图的显示与取消。

保留这条独立于历史的观察路径是合适的当前边界;修复应补齐返回前的原生来源复核和同版本临时失败恢复,无需新增 Session、状态存储或通用调度器。

历史轮询先给出原会话版本和未结束状态,模型请求再携带同一 binding 与 revision。服务端复用原文件的执行身份读取器,只有已核对的开放 Turn 才返回模型与 effort。前端按完整查询键显示结果,切换绑定或版本时取消旧请求。这个分层能够避免可选信息拖住历史,但“旧文件没有变化”和“原生索引仍指向旧文件”是两个不同条件;后一个条件目前没有在响应前再次核对。

具体改动 / Changes

完整检查了 5 个文件,+204/-3,其中生产代码 +117/-3、测试 +87。没有独立书面模型标签规范;本次依据 PR 明确的“精确开放原 Turn、失效观察撤回、历史不受可选读取影响”目标,结合现有 source/identity owner 判定。已先读作者的两条现存 review,再分别通过真实路径复现,结论不是继承自评。

关键代码讲解

  • observed_turn_model / _read_turn_model 新增最多 32 项、按文件版本区分的观察缓存。共享 TypeScript reader 仍判断线程、开放 Turn、可公开模型和 effort;Python 在读后及缓存命中时核对旧文件版本,失败返回 null。
  • _codex_attached_read 限定模型查询参数,核对请求版本,并在读完后复核 LoopX registry binding。F1 在此:这次复核没有重新定位原生 SQLite 中的 rollout_path/archived。
  • AttachedConversation 模型 effect 绑定 open revision,响应不属于当前查询时不会显示。F2 在失败分支:catch 把错误吞掉,而后续相同版本的历史轮询不会再次触发 effect。
  • request 将调用者 signal 与原有 6 秒超时组合,支持 effect 清理。已有 retryableRead 可以复用;CSS 只增加 overflow-wrap:anywhere,避免长模型名硬撑宽度。

对主干的风险 / Risks

F1 · P2:原线程 4533452634 仍成立。 独立构造真实 ChatHTTPServer、SQLite 会话索引和 JSONL,并让实际 TypeScript 身份读取完成后切换同一线程的来源文件,或仅置 archived=1。两种情况都返回 200 与旧模型;下一次历史分别看到新版本或 503。registry 撤销控制返回 409,同一旧文件追加结束事件控制返回 null,说明现有保护有效但覆盖的是不同边界。最小修复是响应前重新定位当前 native thread,核对来源身份、版本与未归档状态。没有证据表明该问题授予新的输入权限,影响限定为模型观察错误。

F2 · P2:原线程 4533452639 仍成立。 将当前生产 React 组件挂到 JSDOM,并连接真实 HTTP/SQLite/TypeScript 后端;只让第一次模型 GET 返回 503。之后 7 次历史读取成功,模型请求仍只有 1 次,状态持续显示 Turn model unavailable。此时直接按同一 binding/revision 读取后端已能得到模型;健康对照组件正常显示。请对 retryableRead 认定的短暂失败做有界重试,随绑定、Turn 或卸载取消;保留权限和身份拒绝的停止边界。

两条已有 inline 已包含准确位置,本次不重复创建讨论线程。新回归应加入原生索引中途迁移/归档,以及 rollout 不变时一次失败后自行恢复;只测试成功显示、永久 unavailable 或旧文件追加结束事件无法覆盖这些反例。

语义与 CI 对齐

build:chat(含 TypeScript)、diff check 和 16/16 execution identity 测试 PASS。Python 原会话测试为 32 passed、34 failed;34 个失败均发生在 fixture 创建 AF_UNIX socket 的 PermissionError 阶段,不能算作 PR 的业务失败,也不能宣称整个原生协议套件通过。独立 API 复现使用实际持久化文件与读取器,只把 Desktop 标为离线,不启动任何真实模型、宿主输入或发送。React 验证覆盖了实际 effect 与 HTTP,属于 DOM 行为验证,不是浏览器绘制。没有新增状态词汇或 Python 语义所有者;这两条失败分别属于现有来源一致性和读取恢复规则。

我的整体评价 / Verdict

REQUEST_CHANGES。健康路径的模型标签有实际价值,独立可选读取与既有 TypeScript owner 的分工也合理,规模不需要扩大。但精确来源和同版本恢复仍未达到声明目标,因此可靠用户体验尚未证明;长期工作、原始历史和执行权限保持原有边界。

本轮浏览器布局验收未完成:本地 Chromium 受 Unix socket 限制,云浏览器无法连接隔离测试服务。

桌面与窄屏实际绘制、长模型名换行及完整页面层级仍未在本轮重新观察;React/JSDOM 行为验证不代替截图。

这项环境限制单独披露,当前阻塞依据是已复现的 F1/F2。修复后请重跑相同 API/React 反例和原生协议测试,并补齐桌面、窄屏、长模型名与暂时失败恢复的实际页面观察;不需要为这项修复增设新的观察协议或通用框架。

English verdict: REQUEST_CHANGES

Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent, gpt-6.1-sol, OpenAI, runtime_reported, reasoning effort max

动机 / Motivation

个人工作台里查看已关联 Codex 原会话的用户,需要从当前未结束 Turn 核对模型和推理档位,同时继续查看历史及返回原 App。 主干会显示原会话仍有未结束执行。旧 PR 增加模型展示,但同一线程更换来源文件或归档时,已在途的读取仍可能从旧文件返回模型。浏览器的第一次 503 也会使未变化的版本持续停在未读取。

状态行显示当前原 Turn 有记录可证的模型和档位。读取完成时再次核对索引选择、未归档来源及文件版本。临时读取失败可在同一绑定和版本上恢复,切换来源或结束后撤去该值。历史和回复仍有独立的读取和写入入口。

模型字段只读观察原会话。它不更改宿主配置、原生会话输入、模型偏好或回复授权。

改动思路 / Approach

复用原 SQLite thread locator、rollout 版本和 TypeScript execution identity。获取值后重新定位索引来源,再由 HTTP 入口复核原 Goal/Agent 的绑定。前端沿用 retryableRead 对临时读取错误有界重试,并绑定原 query 的 revision 和 AbortController。

记录模型来自已打开的原生 Turn 的实际身份读回。locate_thread 核对当前未归档来源,文件 revision 包含原文件身份和变化证据。history 的已读记录、输入和权限继续由原 owner 管理。 turn_model 由当前来源现场派生。缓存按同一 home、文件、thread 和版本限定。前端状态按 exact query 读取,生命周期改变后旧响应被取消或丢弃,没有新持久状态或写入权限。

具体改动 / Changes

共享读取可能命中同一文件版本缓存。返回正值前仍从原索引重新定位会话,核对当前 home、path 及完整文件 revision。 observed_turn_model

模型 GET 单独接受 exact binding + revision,响应前再次验当前绑定。普通历史、内容分页和回复回执仍走原路径。 _codex_attached_read

按当前未结束的 revision 发起可取消的模型读取。只重试既有临时失败类别,响应必须匹配原 query 才能进入状态。 AttachedConversation

沿用读取网络、超时和 5xx 的既有分类。权限和 binding 拒绝不自动重试。 retryableRead

7 文件 +301/−4。production 4 文件 +134/−3,tests_or_fixtures 3 文件 +167/−1。规格依据为 Original-conversation request inventory,版本 3ab96ca718575d5763d52e57345c9b8f4c09be4c。评审映射 original-source-model-readback 要求 观察值须绑定当前原会话与版本。读取失败保持同一来源和已读历史,不产生额外写入 结果为 implemented,验证来自 uv run --extra test python -m pytest -q tests/presentation/test_codex_attached_conversation.py -k model_readback 和安装后 attached-host-follow-up 浏览器场景。

原正常历史读取无需模型选项,模型读取由活动状态和精确 query 驱动。没有额外的用户设置,未打开的 Turn 不触发模型读。 已读历史和回复草稿、正文、分页、原 App 导航、授权及宿主状态继续使用现有协议。旧后端无法提供模型时保留已有界面的可读性。

对主干的风险 / Risks

错把旧来源的模型当成本轮事实会误导用户。无限读或跨版本迟到会扰动会话。额外索引核对只发生在可返回模型的独立读请求上,单次暂态读取最多增加两次重试,并按绑定或版本取消。

真实 Chat HTTP 及 SQLite/JSONL 读取路径返回已打开的同一 Turn 的模型和 max 档位。打包浏览器注入一次 503,在同一绑定、同一 revision 上第二次读取恢复。历史始终可用,页面不发起原生输入。桌面和窄屏都核对了恢复状态。

旧组合在文件切换与归档两个真实 HTTP 反例仍返回旧值。候选保持旧文件不变,切换索引、归档或当前文件完成后均撤去模型。已打开会话的原模型不显示在另一个 Agent 或结束的 Turn 上。历史和输入回执路径继续按原测试验证。

156 项 Python HTTP、原生会话与历史回归及 16 项 TypeScript execution identity 测试通过。已构建、验证并安装独立 wheel,用真实 Chat HTTP 和合成原生源跑过打包浏览器。Ruff、mypy、标准 premerge 通过。 同一隔离 wheel 的 Goal 工作区切换性能 smoke 也通过,15 次切换最高约 214 ms。 标准预合并 6 项 direct、5 项 smoke 通过。

使用安装到隔离环境的 wheel、合成 SQLite/JSONL 和本机协议 peer。实际用户 Codex 会话及桌面 WebView 未测。主干与候选复现了相同的旧摘要登记测试失败,当前 GitHub CI 状态在合并前复核。

我的整体评价 / Verdict

评审版本 8ff68b349dfec3573047ee3542a193c9e748f79d。原会话模型准确性、同版本读取恢复和历史使用已通过上述实际入口验证。原评审发现的条件均以修复前反例和当前结果对应核查。

复用既有 SQLite 定位、文件版本以及浏览器临时错误分类。用隔离安装的 wheel 在 1,440 × 900 与 390 × 844 核对状态行。首次 503 时历史仍可读,原绑定和同一版本恢复后显示当前模型与推理档位。窄屏可换行。在同一会话展开长工作记录,状态和回复区仍可定位。 视觉验收覆盖真实 Chat HTTP、合成原生来源和浏览器,现场用户 Codex 会话与桌面 WebView 尚未实测。 打包首屏证据

English verdict: APPROVE. Head 8ff68b3. An attached Codex Turn shows its recorded model only while the binding and source revision are current. A transient read failure recovers within a bounded retry.

@huangruiteng
huangruiteng dismissed songoow’s stale review November 11, 2026 12:00

Original findings verified resolved at 8ff68b3. The positive response now re-resolves the current SQLite thread source and compares the native home, rollout path, and exact file revision. The real HTTP regressions reproduce stale responses on the old code and return no old model after both rollout replacement and archival while the prior file still exists. The optional model GET uses the existing transient-read classifier and a bounded retry canceled when the exact query changes. The installed-wheel browser exercised a 503 followed by a real 200 for the same binding and revision, with the original history still visible. Maintainer review: #8548 (review). Original discussion retained.

@huangruiteng
huangruiteng merged commit 3a5899f into main Nov 11, 2026
7 of 11 checks passed
@huangruiteng
huangruiteng deleted the codex/attached-codex-turn-model-20261111 branch November 11, 2026 12:01
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.

3 participants