Skip to content

fix(cli, llm, serve-web): Join split reasoning into one region - #919

Merged
JeanMertz merged 3 commits into
mainfrom
redacted-thinking-line-break
Jul 31, 2026
Merged

fix(cli, llm, serve-web): Join split reasoning into one region#919
JeanMertz merged 3 commits into
mainfrom
redacted-thinking-line-break

Conversation

@JeanMertz

Copy link
Copy Markdown
Collaborator

Anthropic interrupts a thinking block with an opaque redacted_thinking block and resumes the thinking in a third block, splitting one region of reasoning mid-word across three items. Each thinking block carries its own signature, and a ConversationEvent holds one signature field, so the three items cannot be merged upstream without dropping a signature and failing the next request's signature validation.

Rendering previously treated every ChatResponse boundary as a block boundary, which broke this text apart on screen, in jp c print replay, and in the web viewer. Text-bearing responses (Message, Reasoning) now concatenate across consecutive events of the same kind, and the visual break between segments comes from blank lines in the stored content instead of from the response boundary. Discrete responses (Structured) are unaffected: each one still closes its json fence at the response boundary, since a JSON value cannot encode its own framing.

Reasoning events are now persisted even when their text is empty, because the attached metadata (a redacted-thinking payload or a thinking signature) can be the only reason the event exists; dropping whitespace-only reasoning would lose that metadata. The web viewer's render_events gained a small buffer that accumulates consecutive text events of one kind before parsing them as markdown, so it stays consistent with the CLI's rendering.

jp_llm's MultiProviderMetadata now derives its Map conversion from Serialize instead of building the map by hand, since the struct fields already match the metadata keys one for one.

Anthropic interrupts a `thinking` block with an opaque
`redacted_thinking` block and resumes the thinking in a third block,
splitting one region of reasoning mid-word across three items. Each
`thinking` block carries its own signature, and a `ConversationEvent`
holds one signature field, so the three items cannot be merged
upstream without dropping a signature and failing the next request's
signature validation.

Rendering previously treated every `ChatResponse` boundary as a block
boundary, which broke this text apart on screen, in `jp c print`
replay, and in the web viewer. Text-bearing responses (`Message`,
`Reasoning`) now concatenate across consecutive events of the same
kind, and the visual break between segments comes from blank lines in
the stored content instead of from the response boundary. Discrete
responses (`Structured`) are unaffected: each one still closes its
`json` fence at the response boundary, since a JSON value cannot
encode its own framing.

Reasoning events are now persisted even when their text is empty,
because the attached metadata (a redacted-thinking payload or a
thinking signature) can be the only reason the event exists; dropping
whitespace-only reasoning would lose that metadata. The web viewer's
`render_events` gained a small buffer that accumulates consecutive
text events of one kind before parsing them as markdown, so it stays
consistent with the CLI's rendering.

`jp_llm`'s `MultiProviderMetadata` now derives its `Map` conversion
from `Serialize` instead of building the map by hand, since the struct
fields already match the metadata keys one for one.

Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz
JeanMertz merged commit 5513d65 into main Jul 31, 2026
16 checks passed
@JeanMertz
JeanMertz deleted the redacted-thinking-line-break branch July 31, 2026 11:53
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.

1 participant