Skip to content

Send display: summarized so Claude thinking renders - #4355

Open
ThePharmer wants to merge 1 commit into
getpaseo:mainfrom
ThePharmer:fix/claude-thinking-display
Open

Send display: summarized so Claude thinking renders#4355
ThePharmer wants to merge 1 commit into
getpaseo:mainfrom
ThePharmer:fix/claude-thinking-display

Conversation

@ThePharmer

@ThePharmer ThePharmer commented Sep 5, 2026

Copy link
Copy Markdown

Linked issue

Closes #4342

Type of change

  • Bug fix
  • New feature
  • Enhancement
  • Refactor
  • Docs

Reasoning

Claude Code agents never show a Thought row in the Paseo timeline, on any Claude 4.7+ model at any effort level. The daemon builds thinking: { type: "adaptive" } for the Agent SDK but never sets display, so the request falls through to the API default, which is "omitted" on Opus 4.7 and later. Every thinking block then arrives with empty text and a populated signature, and Paseo's extractor drops empty blocks by design. The result is zero reasoning timeline items for Claude, while Codex on the same daemon renders reasoning fine.

This PR sets display: "summarized" at both resolveThinkingConfig() call sites that enable adaptive thinking. Paseo's only reason to read thinking blocks is to show them to the user, which is exactly the case the Anthropic docs say summarized is for. With the change, Claude agents stream a Thought row during the turn, and Settings > Always expand reasoning has something to act on.

The bundled SDK (@anthropic-ai/claude-agent-sdk 0.3.246) already types the field on ThinkingAdaptive, so no dependency change is needed.

Goals

  • Claude agents with thinking enabled (any effort level, and Ultracode) receive thinking text from the API.
  • reasoning timeline items appear for Claude agents, in the web UI and in paseo logs --filter text.
  • Existing unit tests for the thinking option shape assert the new display field.

Non-goals

  • No config option or daemon setting to gate the display mode. The field is set unconditionally whenever thinking is enabled, as proposed in the issue. Happy to add a gate in a follow-up if preferred.
  • No handling of the {"type":"system","subtype":"thinking_tokens"} message. That is mentioned as optional in the issue and is a separate change.
  • No change for thinking: { type: "disabled" } or the provider-default path, which continue to send no thinking at all.
  • Trade-off: with summarized, first answer text arrives a couple of seconds later on average because the server streams the summary first. Total turn time is unchanged, and the user sees the Thought row streaming during that gap instead of a blank wait. Measurements are in the issue.

QA

Reproduced before the fix (Paseo 0.7.2, Claude Code 2.1.258, model claude-opus-5, effort high, Debian 12 in Docker): a Claude agent turn shows tool calls and assistant text but no Thought row. paseo logs <agent-id> --filter text lists only [User] and assistant text, no [Thought] entries. The raw stream-json output from the CLI under the same options carries thinking blocks with "thinking":"" and a populated signature, while usage.output_tokens_details.thinking_tokens is non-zero. Full captures, the CLI A/B with --thinking-display summarized, and timing measurements are in #4342.

Confirmed after the fix on the same setup: a child image patching the two call sites in the published dist to { type: "adaptive", display: "summarized" } produces [Thought] rows in paseo logs --filter text and renders the collapsed Thought row in the web UI. That patch has been running for me from 0.2.1 through 0.7.2.

Unit tests (packages/server/src/server/agent/providers/claude/agent.test.ts): the Ultracode assertion and the "reconciles Off when switching to an unsupported model" case now assert { type: "adaptive", display: "summarized" }. The toEqual case fails on main without the source change and passes with it. Test, typecheck, lint, and format results are from the full CI run on my fork before opening this PR: https://github.com/ThePharmer/paseo/actions/runs/33943978065 (22 checks green).

 ✓ src/server/agent/providers/claude/agent.test.ts (75 tests) 800ms
 Test Files  354 passed | 11 skipped (365)

Platforms tested: web UI in a browser, Android, and paseo logs CLI, against a Linux (Docker) daemon. Not tested: iOS and Electron desktop. The change is daemon-side only, so those surfaces receive the same timeline items.

Checklist

  • One focused change
  • npm run typecheck passes
  • npm run lint passes
  • npm run format passes
  • QA evidence
  • Tests added or updated where it made sense

The Agent SDK request never set thinking.display, so on Opus 4.7 and
later the API default of "omitted" applied and every thinking block
arrived with empty text. Paseo drops empty blocks, so Claude agents
never produced reasoning timeline items.

Closes getpaseo#4342
@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR requests summarized thinking output for every Claude adaptive-thinking configuration so non-empty reasoning can reach Paseo’s timeline.

  • Adds display: "summarized" for Ultracode and effort-based adaptive thinking.
  • Updates the corresponding SDK-option assertions.

Confidence Score: 5/5

The PR appears safe to merge; the focused request-option change is consistently applied and covered by existing provider tests.

No concrete correctness, compatibility, security, or repository-rule violation remains after reviewing both adaptive-thinking paths and their updated assertions.

Important Files Changed

Filename Overview
packages/server/src/server/agent/providers/claude/agent.ts Adds the supported summarized display mode to both adaptive-thinking configurations without changing disabled or provider-default behavior.
packages/server/src/server/agent/providers/claude/agent.test.ts Updates focused assertions to verify that adaptive-thinking requests include the summarized display mode.

Reviews (1): Last reviewed commit: "Send display: summarized so Claude think..." | Re-trigger Greptile

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.

bug: Claude thinking never renders because the daemon sends no thinking.display, so every block arrives empty

1 participant