Repository navigation
Avoid reparsing completed Chat Turns during App and Lark admission - #8316
loopx-agent wants to merge 3 commits into
Conversation
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, gpt-6.1-sol, OpenAI, runtime_reported, reasoning_effort=max
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
[P2] 匹配记录的第二次读取失败会重复准入同一请求。 同一 client_turn_id 重试时,File Chat 的发现读取已经匹配原记录。只让随后重新打开该文件的一次 read_text 返回 EIO,已排队和已完成两种状态都从原来复用一个 Turn 变为创建第二个 Turn,并多写一条用户消息。
动机 / Motivation
使用稳定 client_turn_id 重试的 App 和 Lark 私聊队列依赖已接受的请求只创建一个 Turn。 用真实 File ChatStore 对照长历史排队、健康重放和匹配记录的单次 EIO。 热排队减少历史正文读取;正匹配后的读取失败会重复准入。 核对了 3 条变更路径和 File Chat 的调用链。运行时配置与 UI 没有变动。
改动思路 / Approach
复用同一终态观察供重放查找和容量使用;正文、附件、结果仍由真实记录和原重放校验读取。 复用原终态指纹、状态和准入锁,范围合适。首次完整读取已经完成时,第二次打开既增加 I/O,也给请求重放引入失败分支。 问题限定在 File Chat 已知匹配的重试。缓存收益和故障安全分别核验。
具体改动 / Changes
基线为 e58ba30bc949c29ec90c570a8362fb1e7ec9f3be。RFC 定义 client_turn_id、response-loss 重放、不同请求正文的拒绝及现有 File 观察边界。 基线规范
- 长历史排队。 在相同的 320 条、每条 12 KiB 的已完成历史中,新消息每次排队读取的历史正文从冷路径 640 次降到 320 次,热路径五次均从 320 次降到 0 次。热路径中位数 43.29 → 25.07 ms。健康重试返回原 Turn 和最新响应,同 ID 不同正文仍被拒绝。
- 重试身份。 同一 client_turn_id 重试时,File Chat 的发现读取已经匹配原记录。只让随后重新打开该文件的一次 read_text 返回 EIO,已排队和已完成两种状态都从原来复用一个 Turn 变为创建第二个 Turn,并多写一条用户消息。
关键代码讲解
旧版直接使用第一次成功读到的整条记录。新版在匹配后总是再次读取,_read_json 将这一轮 EIO 转成空对象,turn_for_client 返回 None,create_queued_turn 于是走分配新 Turn 和写 transcript 的分支。 匹配后重读 · 读错误处理 · 队列准入
对主干的风险 / Risks
前后对照保留了优化收益。已确认命中的请求在第二次 I/O 失败时仍需守住去重,尤其是用户重试已完成消息。
508 项 File Chat、原生 Steward 和 Lark 私聊相关测试通过,另完成长历史和四组同条件重放对照。 Quick premerge 的 6 项直接检查和 2 项选中检查通过。 DCO trailer 已核验。主干在评审期间合入 #8317,变动只涉及研究页面,与本 PR 无重叠,合并树检查通过。 基线第一次读成功,未触发第二次 I/O;当前 head 的第二次 I/O 才触发注入。两次试验都使用实际落盘记录和队列写入。 远端 CI 未取样。
语义与 CI 对齐
沿用现有客户端请求标识和终态集合。验收用例需覆盖已匹配后的暂时读取故障,并断言原请求的存储身份。
我的整体评价 / Verdict
直接使用本次已完整读取的匹配记录。缓存只交付终态元数据时,正匹配后的完整读取失败应返回可重试的不可用结果,阻止重复准入。补齐冷、热、queued 和 completed 的故障用例,并核对健康重试及新请求的长历史读取数。 当前证据限于隔离的 File Core 入口和本地检查。安装后的端到端行为和生产锁尾延迟仍需另行验证。
English verdict: REQUEST_CHANGES. A transient second read of an already-matched request admits a duplicate Turn for both queued and completed records. Keep the long-history optimization and preserve replay identity under I/O failure.
| continue | ||
| # Replay validation needs the complete current record, including | ||
| # the original request body and the latest persisted result. | ||
| payload = _read_json(path) |
There was a problem hiding this comment.
[P2] Preserve a matched request when the full read fails
同一 client_turn_id 重试时,File Chat 的发现读取已经匹配原记录。只让随后重新打开该文件的一次 read_text 返回 EIO,已排队和已完成两种状态都从原来复用一个 Turn 变为创建第二个 Turn,并多写一条用户消息。 旧版直接使用第一次成功读到的整条记录。新版在匹配后总是再次读取,_read_json 将这一轮 EIO 转成空对象,turn_for_client 返回 None,create_queued_turn 于是走分配新 Turn 和写 transcript 的分支。 直接使用本次已完整读取的匹配记录。缓存只交付终态元数据时,正匹配后的完整读取失败应返回可重试的不可用结果,阻止重复准入。补齐冷、热、queued 和 completed 的故障用例,并核对健康重试及新请求的长历史读取数。
…rk-queue-terminal-observation-20261108 Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Goal And Delivered Outcome
Managed App submission and queued App/Lark admission scanned completed Turn bodies while holding the Session admission fence. Both use the same file observation of unchanged terminal Turns. A matching client ID still resolves the full current request for the existing replay checks. The managed planner still receives current prepared Turns. Bound App and Lark inputs use the same queue.
Target:
main. Tested against8a4d4f9dab17b01d6fe3546936155b4d718fc20d.Author Declaration
ChatSessionStore.accept_managed_turn,ChatIngressStore._turn_discovery_rowsChatIngressStore.turn_for_clientScope And Continuation
This change covers managed and queued admission in the file-backed store. Review and production adoption remain separate stages. The previous Windows run hit the shared
loopx_turn_planoutput-growth check (11,404 against 9,300). The refreshed head still needs hosted verification.Validation
33659aeaf5288a00a1c877b1b9eec9f9606426e9. Local validation finished with synthetic and public repository fixtures.The paired arms alternate in one process and swap the exact prior method. For App, that method comes from the previous queued fix integrated with the tested base. Cold means an empty discovery observer. The first cold batch measured App 450.4 → 533.2 ms and Lark 397.2 → 491.1 ms. The expanded cold batch measured App 521.5 → 518.2 ms and Lark 591.5 → 512.8 ms. Cold wall times varied between batches. Production tail latency and Windows CI remain separate.
Frontend / Visual Evidence
Type of Change
LoopX Area
Shared-authority RFC fixture impact
N/A. File Chat admission only.
Boundary Checklist