Skip to content

fix(bridge): stop raw CoT from scrolling through the desktop thinking band on routed models - #4301

Closed
RobinBially wants to merge 1 commit into
lidge-jun:devfrom
RobinBially:codex/raw-reasoning-content-channel
Closed

fix(bridge): stop raw CoT from scrolling through the desktop thinking band on routed models#4301
RobinBially wants to merge 1 commit into
lidge-jun:devfrom
RobinBially:codex/raw-reasoning-content-channel

Conversation

@RobinBially

@RobinBially RobinBially commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Routed open-source models (GLM/DeepSeek/Grok chat, Kiro raw tags) streamed their raw chain of thought through the summary channel (3183154, issue Reasoning tokens not expanding in Codex UI - "Worked for X" shows time but no trace #45), so the Codex desktop thinking band animated unsummarized CoT — text cycling through the one-line band every few hundred milliseconds. That presentation only fits native OpenAI providers, which author real summaries while the CoT stays hidden server-side.
  • Raw reasoning now rides the content channelresponse.reasoning_text.delta live plus a final reasoning item with content: [{type: "reasoning_text", text}] and an empty summary — the exact native gpt-oss shape from the 100_codex-native-parity/51_raw-reasoning-bridge research. Codex applies its own display policy: the desktop band shows the generic "Thinking…" placeholder, and the CLI keeps raw display behind show_raw_agent_reasoning (opt-in).
  • Deleted the content→summary payload rewrite for native Responses passthrough (its only purpose was that display); DeepSeek's native content-channel round-trip works unchanged upstream. Hidden mode (reasoning.summary absent/"none") is unchanged — envelope-only items with the txt-only ocxr1 round-trip keep preserveReasoningContentModels replay working for GLM interleaved thinking.
  • Video evidence: the 19-second recording below shows the band cycling through different raw CoT sentences within seconds. It was captured on the reporter's desktop; the same file is committed at .github/pr-assets/raw-reasoning-band.mov for durable reference.

Video evidence

raw-reasoning-band.mp4

Verification

  • bun run typecheck, bun run privacy:scan, bun run structure:check — all green.
  • bun run test:changed on this change set: 8891 pass / 0 fail / 2 skip across 388 files (91 s), covering the bridge, passthrough relay, reasoning replay, xAI streaming, web-search, and layout gates.
  • Full bun run test (local): clean rerun — parallel suite exit 0 (200.9 s), every serial test file exit 0, zero fail lines, zero worker crashes. The first two runs exited 1 through a Bun worker SIGSEGV (tests/routing/routing-policy-surface-parity.test.ts) with cascading worker aborts; all four named files pass in isolation (27 pass / 0 fail) and the same crash appears on the pre-change tree, so it is infrastructure flake, not a regression. The two exit 1 fixture invocations inside the runner log are expected negative-fixture cases, not failures.
  • Focused: bun test tests/adapters/bridge.test.ts tests/adapters/bridge-raw-reasoning-hidden.test.ts tests/adapters/bridge-reasoning-replay-batch.test.ts tests/adapters/reasoning-replay-robustness.test.ts tests/images/loop-reasoning-replay.test.ts tests/web-search/web-search.test.ts tests/server/server-xai-chat-reasoning-streaming.test.ts tests/responses/responses-reasoning-summary-passthrough.test.ts tests/providers/opencode-go-luna-wire.test.ts — green.
  • Two web-search tests that fail only in multi-file batch runs fail identically on the pre-change tree (pre-existing cross-file contamination, not caused here); they pass in isolation before and after this change.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed (structure/providers/chat-compat.md, devlog record).
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.
  • 1. GitHub CI is green. (Repository CI does not start automatically for fork-PR authors; a maintainer has to trigger it.)
  • 2. I have rebased my branch onto the latest dev commit.
  • 3. I have fixed all correct findings from the Codex & CodeRabbit automated reviews.
  • 4. This PR is ready for human maintainer review.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Behavior Changes

    • Raw reasoning is now preserved through the Responses content channel for streaming and non-streaming responses.
    • Reasoning content remains in its native format across display modes and supported providers.
    • Clients now receive reasoning_text events and content items instead of summary-channel reasoning events.
  • Documentation

    • Updated reasoning display guidance to reflect native content-channel behavior and client-side display handling.
  • Tests

    • Updated coverage for streaming, passthrough, replay, and provider reasoning behavior.

Routed open-source models streamed their raw chain of thought through the
summary channel (3183154, issue lidge-jun#45), so the Codex desktop thinking band
scrolled unsummarized CoT with its flicker animation — a presentation that
only fits native OpenAI providers that author real summaries.

Stream raw reasoning as response.reasoning_text.delta (content_index 0) and
close the item with content: [{type: "reasoning_text"}] plus an empty
summary — the native gpt-oss shape, so Codex applies its own display policy:
the desktop band shows the "Thinking..." placeholder and the CLI keeps raw
display behind show_raw_agent_reasoning.

Delete the content-to-summary payload rewrite for native Responses
passthrough: its only purpose was that display, and DeepSeek's native
content-channel round-trip works unchanged upstream.

Hidden mode (summary absent/"none") is unchanged: envelope-only items with
the txt-only ocxr1 round-trip for preserveReasoningContentModels replay.
Signed thinking_delta (Claude/kiro visible mode) intentionally stays on the
summary channel.

Video evidence of the band behavior: .github/pr-assets/raw-reasoning-band.gif
(reviewer's own desktop recording, published in this PR with consent).
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: acaed1fd-7b45-4d10-913d-88c6b2905740

📥 Commits

Reviewing files that changed from the base of the PR and between cb7f96c and 5d6d186.

⛔ Files ignored due to path filters (1)
  • .github/pr-assets/raw-reasoning-band.mov is excluded by !**/*.mov
📒 Files selected for processing (13)
  • devlog/_fin/260911_raw_reasoning_content_channel/010_record.md
  • scripts/test-layout/layout.json
  • src/bridge.ts
  • src/server/responses-reasoning-summary-rewrite.ts
  • src/server/responses/core.ts
  • structure/providers/chat-compat.md
  • tests/adapters/bridge-raw-reasoning-hidden.test.ts
  • tests/adapters/bridge.test.ts
  • tests/fixtures/test-layout-expected.json
  • tests/providers/opencode-go-luna-wire.test.ts
  • tests/responses/responses-reasoning-summary-passthrough.test.ts
  • tests/responses/responses-reasoning-summary-rewrite.test.ts
  • tests/server/server-xai-chat-reasoning-streaming.test.ts
💤 Files with no reviewable changes (4)
  • tests/responses/responses-reasoning-summary-rewrite.test.ts
  • src/server/responses-reasoning-summary-rewrite.ts
  • tests/fixtures/test-layout-expected.json
  • scripts/test-layout/layout.json

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

This change routes visible raw reasoning through the Responses content channel, removes the server-side summary-channel rewrite, and updates tests, docs, and test-layout metadata to match the native reasoning_text passthrough shape.

Changes

Reasoning content-channel routing

Layer / File(s) Summary
Bridge raw reasoning emission
src/bridge.ts, tests/adapters/bridge.test.ts, tests/adapters/bridge-raw-reasoning-hidden.test.ts, tests/server/server-xai-chat-reasoning-streaming.test.ts
src/bridge.ts now emits response.reasoning_text.delta and response.reasoning_text.done with content_index: 0. Completed reasoning items now use summary: [] and content: [{ type: "reasoning_text", text }] in streaming and buffered paths. Adapter and streaming tests now assert the content-channel shape and the removal of summary-channel events.
Responses passthrough rewrite removal
src/server/responses/core.ts, src/server/responses-reasoning-summary-rewrite.ts, tests/responses/responses-reasoning-summary-passthrough.test.ts, tests/providers/opencode-go-luna-wire.test.ts, tests/responses/responses-reasoning-summary-rewrite.test.ts
The summary-channel rewrite file was deleted. src/server/responses/core.ts no longer rewrites reasoning content for replay comparison, SSE passthrough, or bounded JSON passthrough. Responses and provider tests now expect native content-channel reasoning in both display modes, and the deleted rewrite tests were removed.
Docs and layout cleanup
structure/providers/chat-compat.md, scripts/test-layout/layout.json, tests/fixtures/test-layout-expected.json, devlog/_fin/260911_raw_reasoning_content_channel/010_record.md
The provider documentation now describes visible raw reasoning as content[reasoning_text] output. The explicit layout mapping for the deleted rewrite test was removed, and the expected fixture was updated. The devlog records the routing change and verification notes.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Low

Sequence Diagram(s)

sequenceDiagram
  participant Provider
  participant Bridge
  participant ResponsesCore
  participant Client

  Provider->>Bridge: raw reasoning delta
  Bridge->>Client: response.reasoning_text.delta
  Provider->>Bridge: raw reasoning complete
  Bridge->>Client: output item content[{type:"reasoning_text", text}]
  Provider->>ResponsesCore: native /responses reasoning_text events
  ResponsesCore->>Client: passthrough without summary rewrite
Loading

Merge Risk: ⚪ Minimal · up to 5d6d1

The reasoning channel migration is covered by updated streaming, buffered, passthrough, replay, and hidden-mode tests; no current merge-blocking risk was identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 7 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies the bridge fix and its primary effect: preventing raw chain-of-thought from appearing in the desktop thinking band for routed models.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 7 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 11, 2026
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

Hygiene

Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 70 / 80

설명

이 PR은 라우팅된 오픈소스 모델(GLM / DeepSeek / Grok chat, Kiro raw 태그)의 날것 사고 과정(CoT)이 Codex 데스크톱 thinking 밴드에 그대로 스크롤되던 증상을 고칩니다. 지금 dev HEAD cb7f96cbcsrc/bridge.tsreasoning_raw_delta를 summary 채널(response.reasoning_summary_text.delta 등)로 보냅니다. 그건 예전 #45 / 커밋 318315450이 “펼칠 수 있는 사고 추적”을 주기 위해 넣은 배선입니다. 그런데 네이티브 OpenAI 쪽만 진짜 summary를 쓰고 CoT는 서버 뒤에 숨깁니다. 오픈소스 라우트는 summary 자리에 요약이 아닌 원문 CoT가 들어가서, 데스크톱 한 줄 밴드가 수백 밀리초마다 다른 문장으로 깜빡입니다. PR에 올린 영상 증거가 그 화면입니다.

고치는 방향은 네이티브 gpt-oss와 같은 content 채널입니다. 라이브는 response.reasoning_text.delta(content_index: 0), 최종 reasoning 아이템은 content: [{type: "reasoning_text", text}]에 원문을 두고 summary는 빈 배열입니다. 그러면 Codex가 자기 표시 정책을 적용합니다. 데스크톱 밴드는 “Thinking…” 자리 표시만 하고, CLI에서 원문을 보려면 show_raw_agent_reasoning이 필요합니다. 그와 맞춰 네이티브 Responses 패스스루용 content→summary 재작성 모듈 src/server/responses-reasoning-summary-rewrite.ts와 그 테스트·layout 항목을 지웁니다. DeepSeek 네이티브 content 채널 왕복은 그대로 두고, 숨김 모드(hideThinkingSummary / summary 없음·"none")의 envelope + ocxr1 재생 경로는 유지합니다. Claude/kiro의 서명된 thinking_delta visible 모드는 일부러 summary 채널에 남깁니다.

이 변경이 중요한 이유는 제품 선택이기 때문입니다. #45가 주려던 “데스크톱에서 펼쳐 읽는 CoT”를 되돌리고, 대신 밴드를 안정시키는 쪽입니다. structure 문서 structure/providers/chat-compat.mddevlog/_fin/260911_raw_reasoning_content_channel/에 그 의도가 적혀 있습니다. 범위는 bridge·responses core의 rewrite 호출 제거·문서·테스트로 묶여 있고 types.ts/config.ts 분할과 무관합니다. 우선순위 70인 이유는 체감 UX 버그가 확실하고 설계가 gpt-oss 패리티와 맞고 테스트가 채널 기대를 뒤집혀 잠갔기 때문입니다. 다만 draft이고 준비 체크리스트가 비어 있으며, “펼침 CoT를 포기한다”는 메인테이너 동의가 먼저입니다. 전체 스위트에서 Bun worker SIGSEGV flake도 본문에 기록돼 있어, 인프라 노이즈와 실제 회귀를 한 번 더 갈라 보는 게 좋습니다.

src/bridge.ts raw 경로 - summary_* 이벤트를 reasoning_text + 빈 summary로 바꾼 방향이 gpt-oss 모양과 일치합니다. 유지하세요.
src/server/responses-reasoning-summary-rewrite.ts 삭제 - 모듈 존재 이유가 그 표시뿐이었다면 삭제가 맞습니다. core.ts에서 import/호출이 함께 빠졌는지 CI로 한 번 더 확인하세요.
숨김 모드 테스트 - envelope/ocxr1·preserveReasoningContentModels 재생이 그대로인 점은 회귀 방지에 중요합니다. 유지하세요.
경로 - Claude/kiro signed thinking_delta - visible이 여전히 summary 채널입니다. 의도된 follow-up이면 이슈로 남겨 두세요. 같은 PR에 넣지 않은 선택은 범위 관리상 좋습니다.
경로 - #45 의도 되돌림 - 데스크톱에서 원문 CoT를 펼쳐 읽던 사용자 경험이 사라집니다. “Thinking…”만 보일지, 다른 UI로 원문을 줄지 제품 판단이 필요합니다.
경로 - draft/체크리스트 - Ready 박스와 CI 녹색이 아직입니다. 머지 전에 draft를 풀 조건을 분명히 하세요.

메인테이너의 판단이 필요한 지점

너의 추천
제품 쪽으로 “밴드는 placeholder, 원문은 CLI 옵트인”이 맞다면 draft를 유지한 채 CI와 full suite가 깨끗해진 뒤 Ready로 올리고 머지하세요. 동의 전이면 머지하지 말고, #45 의도를 살리는 대안(요약 생성 / 밴드 비활성 / 별도 패널)을 먼저 짧게 적어 주세요. types/config 분할과 무관하니 close-don't-rebase 대상이 아닙니다.

이 댓글은 grok-bot이 작성했습니다

@RobinBially

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Working through the three points:

core.ts cleanup — verified: no remaining import, call site, or test reference to the deleted rewrite module anywhere under src/, tests/, or scripts/ (grep clean). bun run typecheck and bun run structure:check are green, and the layout fixtures (scripts/test-layout/layout.json, tests/fixtures/test-layout-expected.json) no longer list the deleted test file.

Signed thinking_delta follow-up — tracked as #4303, with the before/after SSE shape and the reason it is not a channel rename (signature envelope + hideThinkingSummary round-trip).

SIGSEGV flake — separated from real regressions: the four named files pass in isolation (27 pass / 0 fail), the crash reproduces on the pre-change tree, and a clean rerun of the full local suite finished with the parallel suite at exit 0 (200.9 s), every serial file exit 0, zero fail lines and zero worker crashes. The two exit 1 entries in the runner log are expected negative-fixture cases.

Readiness — the checklist is complete and the gate marked this PR ready (4/4, head 5d6d1862a). The local-CI box is an author attestation by design: repository CI does not start automatically for fork-PR authors, so triggering it stays with a maintainer.

On #45 — the product call you flagged is the maintainer decision, and the PR body states the tradeoff explicitly: desktop keeps the "Thinking…" placeholder instead of an expandable raw CoT, and the raw trace stays available in the CLI behind show_raw_agent_reasoning. If you prefer a different resolution (generated summaries, band suppression, separate panel), say so and we will adjust rather than merge on our own judgement.

@RobinBially RobinBially changed the title fix(bridge): keep raw reasoning on the content channel fix(bridge): stop raw CoT from scrolling through the desktop thinking band on routed models Sep 11, 2026
yxr1995-maker pushed a commit to yxr1995-maker/opencodex that referenced this pull request Sep 12, 2026
showThinkingSummary's job is to take a provider's genuine reasoning out of the hidden
replay envelope. Which channel carries the visible text is the bridge's decision, not
this flag's: lidge-jun#4301 moves raw reasoning from the summary channel to the content channel
(the native gpt-oss shape), so asserting the summary channel here would pin the opposite
of whichever behaviour is current.

Rewritten around the Cloud Code Assist path the flag exists for. That also lets the
request-side half be asserted in the same file: includeThoughts reaching the wire when a
provider opts in, and not being bought at all for a turn the client asked to hide. The
passthrough-based cases are dropped -- lidge-jun#4301 deletes the content-to-summary rewrite they
exercised, and with it their subject.

Comment-only edits keep provider.ts, registry.ts and core.ts from claiming the summary
channel as the contract; the docs row says the same and documents the explicit false.
@lidge-jun

Copy link
Copy Markdown
Owner

Landed via #4351 at 17da84f89adf0db78852f1f13e7e74c14d5a317e.

#4345가 raw CoT vs provider summary 분리를 dev에 반영하며 #4301을 reconcile했으므로 landed-via-maintainer로 닫습니다.

@lidge-jun lidge-jun closed this Sep 13, 2026
@lidge-jun lidge-jun added the landed-via-maintainer Original PR closed after landing via a maintainer merge train label Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working landed-via-maintainer Original PR closed after landing via a maintainer merge train review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants