fix(bedrock): preserve encrypted reasoning replay signatures - #5879
Conversation
Affected packages: - core/providers/bedrock/ - add a failing regression test for empty-summary encrypted reasoning replay
Affected packages: - core/providers/bedrock/ - map encrypted Responses reasoning to the native Bedrock signature field - core/ - document the user-facing fix
📝 WalkthroughSummary by CodeRabbit
WalkthroughBedrock reasoning conversion now preserves non-empty encrypted reasoning content in the ChangesBedrock reasoning replay
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/providers/bedrock/responses.go (1)
4553-4564: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winFilter summary items by text, not only by slice length.
When
Summarycontains an item withText == ""andEncryptedContentis non-empty, Line 4553 enters the summary branch. Theelse ifthen skips Lines 4564-4568, so the converter emits an empty reasoning block and drops the replay signature. Emit only non-empty summary text, then useEncryptedContentwhen no visible summary was emitted. The sibling conversion incore/providers/bedrock/invoke.goalready applies this rule. Add a regression case for an empty summary item.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/bedrock/responses.go` around lines 4553 - 4564, The Responses reasoning conversion must filter Summary entries by non-empty Text rather than using Summary length. Update the logic around the ResponsesReasoning summary conversion to append blocks only for visible text, then fall back to EncryptedContent when no summary block was emitted; mirror the sibling behavior in invoke.go and add a regression case covering an empty summary item with non-empty encrypted content.
🧹 Nitpick comments (1)
core/providers/bedrock/reasoning_replay_test.go (1)
30-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert
Signatureis non-nil before dereferencing it.
require.Equalevaluates the dereference before the assertion runs. If the converter returns a nil signature, the test panics instead of reporting a failed assertion. Addrequire.NotNilbefore Line 30.Suggested test adjustment
+ require.NotNil(t, blocks[0].ReasoningContent.ReasoningText.Signature) require.Equal(t, encryptedContent, *blocks[0].ReasoningContent.ReasoningText.Signature)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/providers/bedrock/reasoning_replay_test.go` at line 30, In the reasoning replay test, add a require.NotNil assertion for blocks[0].ReasoningContent.ReasoningText.Signature before the existing require.Equal assertion, then retain the equality check against encryptedContent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@core/providers/bedrock/responses.go`:
- Around line 4553-4564: The Responses reasoning conversion must filter Summary
entries by non-empty Text rather than using Summary length. Update the logic
around the ResponsesReasoning summary conversion to append blocks only for
visible text, then fall back to EncryptedContent when no summary block was
emitted; mirror the sibling behavior in invoke.go and add a regression case
covering an empty summary item with non-empty encrypted content.
---
Nitpick comments:
In `@core/providers/bedrock/reasoning_replay_test.go`:
- Line 30: In the reasoning replay test, add a require.NotNil assertion for
blocks[0].ReasoningContent.ReasoningText.Signature before the existing
require.Equal assertion, then retain the equality check against
encryptedContent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: fb41fa1d-47df-44f4-9150-4799d65109ec
📒 Files selected for processing (3)
core/changelog.mdcore/providers/bedrock/reasoning_replay_test.gocore/providers/bedrock/responses.go
* [test]: Bedrock provider - cover encrypted reasoning replay Affected packages: - core/providers/bedrock/ - add a failing regression test for empty-summary encrypted reasoning replay * [fix]: Bedrock provider - preserve encrypted reasoning replay Affected packages: - core/providers/bedrock/ - map encrypted Responses reasoning to the native Bedrock signature field - core/ - document the user-facing fix
…#5879) * [test]: Bedrock provider - cover encrypted reasoning replay Affected packages: - core/providers/bedrock/ - add a failing regression test for empty-summary encrypted reasoning replay * [fix]: Bedrock provider - preserve encrypted reasoning replay Affected packages: - core/providers/bedrock/ - map encrypted Responses reasoning to the native Bedrock signature field - core/ - document the user-facing fix
Summary
Preserve encrypted reasoning replay data when a Responses API reasoning item is translated to Bedrock Converse format.
Responses reasoning items can carry
EncryptedContentalongside an empty, non-nilSummary. The Bedrock converter previously treated that empty slice as visible reasoning, emitted no block, and silently dropped the replay payload. Its fallback also represented encrypted reasoning as synthetic text rather than the native Bedrock reasoning signature.Changes
EncryptedContenttoreasoningContent.reasoningText.signature.[ENCRYPTED_REASONING: ...]text representation.Type of change
Affected areas
How to test
Expected result: the regression test passes and the Bedrock reasoning block contains the encrypted payload in
reasoningText.signature, with no synthetic text.The full Bedrock provider package was also run. It currently fails on pre-existing document-placeholder expectations (
TestConvertBifrostResponsesMessageContentBlocksToBedrockContentBlocks_EmptyBlocksandTestDocumentFormatMapping) because currentdevemits a placeholder text block alongside document blocks. Those failures are unrelated to this change.No new configuration or environment variables were added.
Screenshots/Recordings
Not applicable; this change has no UI impact.
Breaking changes
Related issues
Related to #5638 and #5094.
Security considerations
No new security surface. The change preserves an existing opaque provider-issued reasoning signature instead of converting it into visible synthetic text.
Checklist