FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat: return readable Claude reasoning, and render absent reasoning honestly by saucam · Pull Request #308 · highflame-ai/codeoid · GitHub

feat: return readable Claude reasoning, and render absent reasoning honestly - #308

Open
saucam wants to merge 1 commit into
mainfrom
feat/summarized-thinking-and-reasoning-ux
Open

feat: return readable Claude reasoning, and render absent reasoning honestly#308
saucam wants to merge 1 commit into
mainfrom
feat/summarized-thinking-and-reasoning-ux

Conversation

saucam commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

The reasoning expander always read "reasoning (1 lines)" and expanded onto nothing. Two independent causes — one API, one UI.

1. Claude was never asked for readable reasoning

thinking.display defaults to "omitted" on Opus 5 / 4.8 / 4.7, Sonnet 5, and Fable 5 — which streams thinking blocks whose text is empty. codeoid then committed them as a placeholder.

Measured on live data:

  • 3,445 of 3,450 thinking records in one session were the placeholder
  • 635 of 635 raw SDK thinking blocks across six transcripts had empty thinking text

ClaudeProvider now passes display: "summarized".

This is free. display controls visibility only — thinking happens and is billed identically either way. The tokens were already being spent; we just weren't being shown anything for them. (The raw chain of thought is never exposed on any model; this is a summary of it.)

2. The UI promised content it could not have

A <details> expander over the placeholder advertised reasoning, counted it as 1 lines, and opened onto the placeholder — which reads as a counting bug rather than absent data.

state before after
Reasoning present expander, (N lines) expander, (N lines) / (1 line)
No reasoning expander → placeholder flat marker, no expander, no count

Both branches are live, and neither is an error state — which is why this is a render-time decision rather than something to "fix" in a backend. qwen-code and OSS models behind an OpenAI-compatible gateway stream plaintext reasoning today (qwen-ledger has real thinking content in its transcript), while Claude only does under the setting above. The same UI now serves both.

Pluralisation is fixed as a side effect — (1 line), not (1 lines).

Shared constant

The placeholder moves to REASONING_UNAVAILABLE in the protocol package. The daemon writes it and the client keys off it, so the two sides can't drift over a prose string — the same class of bug as the memory-server name in #307.

Its wording also changes from "(reasoning elided)": codeoid elides nothing, the backend returned none. The old phrasing pointed the finger in the wrong direction while debugging this.

Note: packages/protocol is a bun file: copy in web/, so editing it requires bun install in web/ to refresh. CI installs fresh every run.

Verification

Daemon: lint + typecheck clean, 2382 pass / 0 fail.
Web: typecheck + build clean, 425 pass / 0 fail (41 files) — 3 new tests covering the absent-reasoning marker, the present-reasoning expander, and whitespace-only treated as absent; 3 existing assertions updated for the pluralisation fix.

🤖 Generated with Claude Code

…onestly

The reasoning expander in the web UI always read "reasoning (1 lines)" and
expanded onto nothing. Two independent causes.

1. Claude was never asked for readable reasoning.

`thinking.display` defaults to "omitted" on Opus 5 / 4.8 / 4.7, Sonnet 5, and
Fable 5, which streams thinking blocks whose text is EMPTY; codeoid then
committed them as a placeholder. Measured on one live session: 3,445 of 3,450
thinking records were the placeholder, and 635 of 635 raw SDK thinking blocks
across six transcripts had empty text.

ClaudeProvider now passes `display: "summarized"`. This is free — display
controls visibility only, and thinking is billed identically either way, so
the tokens were already being spent with nothing shown for them. (The raw
chain of thought is never exposed on any model; this is a summary of it.)

2. The UI promised content it could not have.

Rendering a <details> expander over the placeholder advertised reasoning,
counted it as "1 lines", and opened onto the placeholder text — which reads as
a counting bug rather than absent data. It now renders a flat, non-interactive
marker when there is nothing behind it, and keeps the expander (with a correct,
correctly-pluralised count) when there is.

Both branches are live and neither is an error state, which is why this is a
render-time decision rather than a backend fix: qwen-code and OSS models behind
an OpenAI-compatible gateway stream plaintext reasoning today — qwen-ledger has
real thinking content in its transcript — while Claude only does so under the
setting above.

The placeholder moves to a shared `REASONING_UNAVAILABLE` constant in the
protocol package: the daemon writes it and the client keys off it, so the two
sides cannot drift over a prose string. Its wording changes from "(reasoning
elided)" — codeoid elides nothing; the backend returned none.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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


Back | FazBrowse Home | New Git URL