Skip to content

fix(prompt): forward Anthropic thinking signature through streaming#2010

Open
zxuhan wants to merge 1 commit into
JetBrains:developfrom
zxuhan:fix/anthropic-streaming-signature
Open

fix(prompt): forward Anthropic thinking signature through streaming#2010
zxuhan wants to merge 1 commit into
JetBrains:developfrom
zxuhan:fix/anthropic-streaming-signature

Conversation

@zxuhan
Copy link
Copy Markdown
Contributor

@zxuhan zxuhan commented May 14, 2026

Summary

Fixes #1959: Anthropic's extended thinking signature was lost during streaming, so the next request in a multi-turn conversation failed with:

Encrypted signature is required for reasoning messages but was null

The signature was being dropped in three places:

  1. AnthropicLLMClient.executeStreaming ignored AnthropicContent.Thinking.signature on CONTENT_BLOCK_START.
  2. CONTENT_BLOCK_DELTA had no branch for signature_delta events.
  3. StreamFrameFlowBuilder.PendingReasoning carried no encrypted field, so ReasoningComplete.encrypted was always null.

Changes

  • Add signature to AnthropicStreamDelta and SIGNATURE_DELTA to AnthropicStreamDeltaContentType.
  • Forward the signature on both content_block_start and signature_delta events in executeStreaming.
  • Add encrypted to PendingReasoning and propagate it through tryEmitPendingReasoning to ReasoningComplete.

Test plan

  • ./gradlew :prompt:prompt-model:jvmTest (adds testEmitReasoningDeltaWithEncrypted and testEmitReasoningDeltaEncryptedSurvivesTransition for the new plumbing).
  • ./gradlew :prompt:prompt-executor:prompt-executor-clients:prompt-executor-anthropic-client:jvmTest
  • ./gradlew :prompt:prompt-executor:prompt-executor-clients:prompt-executor-google-client:jvmTest :prompt:prompt-executor:prompt-executor-clients:prompt-executor-openrouter-client:jvmTest :prompt:prompt-executor:prompt-executor-clients:prompt-executor-ollama-client:jvmTest (sister clients that call emitReasoningDelta still pass with the new optional encrypted parameter).
  • compileKotlinJs for prompt-model and the Anthropic client to confirm common-source compatibility.

Fixes #1959

The Anthropic streaming path discarded the thinking-block signature in
two places: the CONTENT_BLOCK_START handler dropped AnthropicContent
.Thinking.signature, and the CONTENT_BLOCK_DELTA handler did not decode
signature_delta events at all. The pending reasoning state in
StreamFrameFlowBuilder also had nowhere to store the signature, so
ReasoningComplete.encrypted was always null and downstream
Message.Reasoning lost the field.

Reconstruction of Message.Reasoning from streamed frames then failed on
the next request with "Encrypted signature is required for reasoning
messages but was null", breaking multi-turn streaming with extended
thinking.

Buffer the signature on PendingReasoning and emit it on
ReasoningComplete; decode signature_delta in AnthropicStreamDelta and
plumb it through executeStreaming.

Fixes JetBrains#1959
zxuhan added a commit to zxuhan/projects that referenced this pull request May 22, 2026
…order

- Add vercel/ai (5 PRs) and spring-projects/spring-ai (3 PRs) in slots 5-6
  so they're visible without scrolling.
- Add huggingface/diffusers (2 PRs) and JetBrains/koog#2010.
- Re-verify status against GitHub API: include closed-but-landed PRs
  (pytorch/pytorch #181393 commit 98a0359064, #181531 commit 9d330f6684,
  spring-ai #6039 commit 65838d6cd) — these ship via mergebot/cherry-pick
  which closes the PR without using GitHub's native merge button.
- Drop genuinely abandoned PRs (vllm/vllm).
- Reorder tail: minikube, diffusers, ClickHouse, tensorflow, axolotl.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

Anthropic streaming doesn't pass signature to StreamFrame.ReasoningComplete.encrypted

1 participant