Skip to content

fix(chat): generate streamed answers only once - #6125

Merged
huangruiteng merged 3 commits into
mainfrom
codex/chat-single-streamed-answer-20261010
Oct 10, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/chat-single-streamed-answer-20261010

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Chat currently asks the model to emit its complete Markdown answer and then generate the same answer again inside the hidden review JSON. Keep one visible answer and use an explicitly empty envelope message to reuse it through the existing parser. Codex selects the completed final answer item so earlier commentary cannot pollute the answer or supply action metadata.

Legacy nonempty messages retain precedence. Missing/null fields do not enable reuse, malformed or unclosed envelopes still drop action metadata, and existing redaction/typed normalization remain in place. The shared transport seam serves ordinary, manager and Goal Chat; bilingual conversation docs describe the convention. The related final-item cleanup is included because compact responses need that boundary. No new authority owner or protocol version is introduced.

Validation: 278 focused tests passed, including offline intake evaluation, every-split stream redaction, legacy compatibility, incomplete-envelope negatives and commentary rejection; the new parser regression fails against the base implementation. Mypy passed. Two public synthetic requests through the real Codex adapter (gpt-6.1-sol, xhigh) returned complete answers with closed envelopes, no protocol warnings, and zero duplicated message characters. This is protocol validation; installed Bot/topic latency and community admission are not qualified by these synthetic requests.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
…eamed-answer-20261010

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.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewer: model_agent; self_reported; model=GPT-6; provider=OpenAI

动机

没有发现阻塞问题。管家、普通项目与 Goal Chat 的用户在阅读流式回复时遇到这项开销。原来完整正文流完后,模型还要在隐藏 JSON 里再生成一遍;现在正文只生成一次,隐藏 JSON 复用正文。真实 Codex 两次请求均返回完整正文、闭合元数据,隐藏 message 为零字且没有协议警告。本 PR 不认证已安装 Bot 的回复时延,也不改变群准出标准、权限或派工。安装后的原话题时延、完整社区 golden queries 与公开群准出仍待验证。

改动思路

复用现有 prompt、parser 和 Codex 最终 item 边界,比增加第二份答案缓存或新协议版本更小且完整。本 PR 同时交付单次正文生成、最终 item 选择、负例和兼容测试及双语契约;合并后才进入安装与原话题复测。
参考既有契约 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,固定版本 cfd1bba80cc776f40a4f23294b00dbc185748aa3,判定行 Waiting is part of the conversation:收发消息、真实活动和可读答案仍通过原入口;两次真实 Codex 请求及原生事件回放验证,群准出时延另验。文档新增条款说明实现约定,没有把未达标时延写成通过。

具体改动

  • _turn_prompt 要求完整可见 Markdown,随后仍必须附闭合 review JSON,但 message 留空,不再重复正文。
  • parse_agent_response 仅在闭合且可解析的 dict 中对显式空字符串复用正文,再进入原有脱敏和 typed normalization。非空旧值优先;缺失/null 不启用复用;不闭合、格式错误和更早隐藏信封不会泄漏动作或协议正文。
  • CodexChatAgentSession.send 把结构化结果已经采用的完成 item 选择复用于普通回答,排除 commentary 与不完整 deltas。类型化动作、派工与确认 owner 不变;ACP/DSH/Claude/API 继续用同一个 prompt/parser。
  • 三组已有测试覆盖兼容、最终消息及流式边界;中英文 RFC 同步披露默认变化。源 diff 为 133 加 / 15 删,7 文件,无新服务、状态或版本。

对主干的风险

显式空字符串现在有正文复用含义,因此必须保留 parser 与最终 item 选择的共同修复。旧非空、闭合失败、脱敏和 structured-output 路径均回归;同一事件 fixture 在 base/head 证明旧协议及不闭合行为一致,旧版 compact 答案为空及 commentary 动作提升则被修复。

合入当前主干恢复改动后,297 项相关测试通过;mypy、semantic drift smoke、diff hygiene 和风险分流 premerge 已检查。旧实现上的新 parser oracle 按预期失败。真实 gpt-6.1-sol / xhigh 连续两次请求返回完整正文、零重复 message、无协议警告。原生事件 fixture 模拟 host IO;真实模型验证只覆盖该协议,不证明 App/IM 时延和所有模型组合。按本 Goal 的 wait_for_ci=false 使用本地验证,不查询或等待 CI;GitHub 分支保护与实际合并权限单独判定。

我的整体评价

复用现有 prompt、parser 和 Codex 最终 item 边界,比增加第二份答案缓存或新协议版本更小且完整。本 PR 同时交付单次正文生成、最终 item 选择、负例和兼容测试及双语契约;合并后才进入安装与原话题复测。认可这个可独立回退的传输层增量;没有重复缓存、新生命周期或并行权限 owner。安装、原话题测试及公开群准出继续由已有社区验收任务推进,不能用 PR、测试数量或两次合成请求替代准出。作者自评是透明的 COMMENTED 记录,不冒充独立人工批准或 GitHub APPROVED;也不授予 admin bypass。

English verdict: APPROVE - exact head fdaca9b; one complete streamed answer, compact hidden metadata, final-item and fail-closed boundaries preserved. 297 focused tests, type/semantic/premerge checks, base/head replay and two real Codex requests pass; installed latency and community admission remain unqualified.

…eamed-answer-20261010

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.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewer: model_agent; self_reported; model=GPT-6; provider=OpenAI

动机

没有发现阻塞问题。管家、普通项目与 Goal Chat 的用户在阅读流式回复时遇到这项开销。原来完整正文流完后,模型还要在隐藏 JSON 里再生成一遍;现在正文只生成一次,隐藏 JSON 复用正文。真实 Codex 两次请求均返回完整正文、闭合元数据,隐藏 message 为零字且没有协议警告。本 PR 不认证已安装 Bot 的回复时延,也不改变群准出标准、权限或派工。安装后的原话题时延、完整社区 golden queries 与公开群准出仍待验证。

改动思路

复用现有 prompt、parser 和 Codex 最终 item 边界,比增加第二份答案缓存或新协议版本更小且完整。本 PR 同时交付单次正文生成、最终 item 选择、负例和兼容测试及双语契约;合并后才进入安装与原话题复测。
参考既有契约 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,固定版本 5de71093cee3217c66cc32394fd841f6c831f5e2,判定行 Waiting is part of the conversation:收发消息、真实活动和可读答案仍通过原入口;两次真实 Codex 请求及原生事件回放验证,群准出时延另验。文档新增条款说明实现约定,没有把未达标时延写成通过。

具体改动

  • _turn_prompt 要求完整可见 Markdown,随后仍必须附闭合 review JSON,但 message 留空,不再重复正文。
  • parse_agent_response 仅在闭合且可解析的 dict 中对显式空字符串复用正文,再进入原有脱敏和 typed normalization。非空旧值优先;缺失/null 不启用复用;不闭合、格式错误和更早隐藏信封不会泄漏动作或协议正文。
  • CodexChatAgentSession.send 把结构化结果已经采用的完成 item 选择复用于普通回答,排除 commentary 与不完整 deltas。类型化动作、派工与确认 owner 不变;ACP/DSH/Claude/API 继续用同一个 prompt/parser。
  • 三组已有测试覆盖兼容、最终消息及流式边界;中英文 RFC 同步披露默认变化。源 diff 为 133 加 / 15 删,7 文件,无新服务、状态或版本。

对主干的风险

显式空字符串现在有正文复用含义,因此必须保留 parser 与最终 item 选择的共同修复。旧非空、闭合失败、脱敏和 structured-output 路径均回归;同一事件 fixture 在 base/head 证明旧协议及不闭合行为一致,旧版 compact 答案为空及 commentary 动作提升则被修复。

合入当前主干恢复改动后,297 项相关测试通过;mypy、semantic drift smoke、diff hygiene 和风险分流 premerge 已检查。旧实现上的新 parser oracle 按预期失败。真实 gpt-6.1-sol / xhigh 连续两次请求返回完整正文、零重复 message、无协议警告。原生事件 fixture 模拟 host IO;真实模型验证只覆盖该协议,不证明 App/IM 时延和所有模型组合。按本 Goal 的 wait_for_ci=false 使用本地验证,不查询或等待 CI;GitHub 分支保护与实际合并权限单独判定。

我的整体评价

复用现有 prompt、parser 和 Codex 最终 item 边界,比增加第二份答案缓存或新协议版本更小且完整。本 PR 同时交付单次正文生成、最终 item 选择、负例和兼容测试及双语契约;合并后才进入安装与原话题复测。认可这个可独立回退的传输层增量;没有重复缓存、新生命周期或并行权限 owner。安装、原话题测试及公开群准出继续由已有社区验收任务推进,不能用 PR、测试数量或两次合成请求替代准出。作者自评是透明的 COMMENTED 记录,不冒充独立人工批准或 GitHub APPROVED;也不授予 admin bypass。

English verdict: APPROVE - exact head d63556b; one complete streamed answer, compact hidden metadata, final-item and fail-closed boundaries preserved. 297 focused tests, type/semantic/premerge checks, base/head replay and two real Codex requests pass; installed latency and community admission remain unqualified.

@huangruiteng
huangruiteng merged commit 5c4ccc3 into main Oct 10, 2026
22 of 28 checks passed
@huangruiteng
huangruiteng deleted the codex/chat-single-streamed-answer-20261010 branch October 10, 2026 16:28
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