Skip to content

Use ContentThinkingDelta for streaming thinking#211

Closed
cpsievert wants to merge 8 commits intoui/thinkingfrom
ui/thinking-delta
Closed

Use ContentThinkingDelta for streaming thinking#211
cpsievert wants to merge 8 commits intoui/thinkingfrom
ui/thinking-delta

Conversation

@cpsievert
Copy link
Copy Markdown
Collaborator

@cpsievert cpsievert commented May 7, 2026

Summary

Thinking content (ContentThinkingDelta and ContentThinking) now flows through the same normalization and message-sending pipeline as all other content types, instead of being special-cased in the stream loop. This makes thinking a property of the message rather than the code path, so non-streaming thinking (e.g., bookmark restore) works correctly without separate handling.

Dependencies

What this replaces

Alternative to #210, which removed content_type: "thinking" from the wire protocol entirely. This PR keeps the typed wire protocol while achieving the server-side simplification.

TODO

cpsievert and others added 3 commits May 7, 2026 17:52
Replace the ContentThinking accumulator pattern with
ContentThinkingDelta's phase-based inline construction. The phase
property ("start", "body", "end") lets the server build stored
messages with <thinking> tags in a single pass — no accumulator
or finally-block reconstruction needed.

- R: add ContentThinkingDelta dispatch in contents_shinychat
- Python: replace _is_content_thinking + accumulator with
  _is_content_thinking_delta + phase-based message building
- Remove _current_stream_thinking field entirely

Depends on posit-dev/chatlas#299.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ContentThinking still appears in non-streaming contexts like bookmark
restore, so it needs to remain registered alongside ContentThinkingDelta.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both packages need versions that export ContentThinkingDelta.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cpsievert and others added 4 commits May 7, 2026 18:51
The method registration fails at load time if the installed ellmer
doesn't export ContentThinkingDelta yet. Guard with exists() so
shinychat can still load with older ellmer versions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CI failure is expected until ellmer ships ContentThinkingDelta.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cpsievert cpsievert requested a review from gadenbuie May 7, 2026 23:55
Copy link
Copy Markdown
Collaborator

@gadenbuie gadenbuie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be helpful if you could take a step back and discuss the problem you're wanting to solve with these additional PRs. It's hard to read between the lines of Claude's PR description to understand what part is bugging you and what problem you're wanting to solve. And I think it'd be best to do that in my original PR as a review so we can have that discussion there.

Comment thread pkg-py/src/shinychat/_chat.py Outdated
Instead of computing content_type inside _send_append_message (via a
content_type_override parameter), resolve it at each call site using a
shared resolve_content_type() helper. This lets thinking content be
detected from the original message before normalization loses the type,
and handles both streaming (ContentThinkingDelta) and non-streaming
(ContentThinking) paths uniformly.
@cpsievert cpsievert force-pushed the ui/thinking-delta branch from c4dbf7a to 775bc64 Compare May 8, 2026 14:59
Comment on lines +1617 to +1619
content_type=resolve_content_type(
message_dict, stored.content
),
Copy link
Copy Markdown
Collaborator Author

@cpsievert cpsievert May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently this won't restore the correct content type. We already have this problem on main though, and I think it's worth us actually fixing this.

@cpsievert cpsievert closed this May 8, 2026
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