fix: Emit assistant.message per text block in Claude runtime#1561
Open
knechtionscoding wants to merge 1 commit into
Open
fix: Emit assistant.message per text block in Claude runtime#1561knechtionscoding wants to merge 1 commit into
knechtionscoding wants to merge 1 commit into
Conversation
The Claude session provider only emitted assistant.message via the assembled message envelope, and only when no streaming deltas had occurred. During normal streaming it never emitted a bubble-closing event, so every text block in a turn concatenated into one bubble. Accumulate streamed text per content-block index and emit assistant.message on each content_block_stop, interleaved with the deltas. This matches the sequence the web reducer and TUI expect and mirrors the Codex provider, which already emits a closing message per block. Update the plain terminal to end the current streamed line on a mid-stream assistant.message so blocks render separately there too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
knechtionscoding
had a problem deploying
to
ok-to-test
July 24, 2026 10:22 — with
GitHub Actions
Error
knechtionscoding
marked this pull request as ready for review
July 24, 2026 11:01
Collaborator
|
/kelos review |
Contributor
|
🤖 Kelos Task Status Task |
Contributor
|
🤖 Kelos Reviewer Agent @gjkim42 Review SummaryVerdict: REQUEST CHANGES Findings Overview
FindingsCorrectness
Performance
Tests
Key takeaways
|
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What type of PR is this?
/kind bug
What this PR does / why we need it:
Fixes assistant text blocks concatenating into a single bubble within a turn in
Claude-backed sessions.
The Claude session provider (
internal/sessionruntime/claude.go) only emittedassistant.messagevia the assembled message envelope, and even then onlywhen no streaming deltas had occurred (
!hadTextDelta). During normal streamingit never emitted a bubble-closing
assistant.messageat all, so every textblock in a turn accumulated into one bubble.
Emitting the close events from the assembled envelope wouldn't fix it either:
all deltas arrive before the envelope, producing
delta, delta, message, messageinstead of the interleaved
delta, message, delta, messagethat clients expect.This PR:
assistant.messageon each
content_block_stop, interleaved in the stream where the reducerexpects it. Non-text blocks (e.g.
tool_use) accumulate no text and emitnothing. This mirrors the Codex provider, which already emits deltas plus a
closing message per block.
still works and there is no duplicate emission.
internal/cli/session_terminal.go) to end thecurrent streamed line on a mid-stream
assistant.messageso blocks renderseparately there too. The TUI already handled this via
finishStreaming()and needed no change.
Which issue(s) this PR is related to:
N/A
Special notes for your reviewer:
Behavior across the three event consumers after this change:
delta … message … delta … messageandrenders separate bubbles.
session_terminal_tui.go) — already calledfinishStreaming()on amid-stream
assistant.message; it ignores the message text while streaming(uses accumulated deltas), so there is no duplication.
Added
internal/sessionruntime/claude_test.gocovering: two-block separation,a
tool_useblock emitting no message, the non-streaming fallback, andconfirmation that the assembled message does not re-emit streamed text.
Note:
make verifyfails on this branch, but only on pre-existing issuesunrelated to this change — YAML linting of stale
.claude/worktrees/copies anda generated-files drift check. This is a pure Go-logic change with no
CRD/API/codegen impact.
gofmt,go vet, and theinternal/sessionruntimeandinternal/clipackage tests all pass.Does this PR introduce a user-facing change?
Summary by cubic
Fixes Claude-backed sessions concatenating multiple assistant text blocks into one message by emitting
assistant.messageper block, interleaved with deltas. Web and terminal UIs now render separate bubbles/lines for each block.internal/sessionruntime/claude.go, accumulate text per content-block index and emitassistant.messageon eachcontent_block_stop; non-text blocks emit nothing. The assembled-message path remains unchanged to avoid duplicates and matches the Codex provider’s behavior.delta, message, delta, message, so the web reducer renders separate bubbles.internal/cli/session_terminal.go, close the current streamed line on mid-streamassistant.messageso blocks print separately. Added tests for two-block separation,tool_useno-op, non-streaming fallback, and no duplicate emission.Written for commit b8f56dc. Summary will update on new commits.