@@ -4820,7 +4820,7 @@ def test_convert_reasoning_value_to_parts_flat_string_unchanged():
48204820
48214821@pytest .mark .asyncio
48224822async def test_content_to_message_param_anthropic_outputs_thinking_blocks ():
4823- """For Anthropic models, thinking_blocks are output instead of reasoning_content ."""
4823+ """Anthropic model messages base64-encode thought signatures ."""
48244824 content = types .Content (
48254825 role = "model" ,
48264826 parts = [
@@ -4839,12 +4839,47 @@ async def test_content_to_message_param_anthropic_outputs_thinking_blocks():
48394839 assert result ["thinking_blocks" ] == [{
48404840 "type" : "thinking" ,
48414841 "thinking" : "deep thought" ,
4842- "signature" : "sig_round_trip " ,
4842+ "signature" : "c2lnX3JvdW5kX3RyaXA= " ,
48434843 }]
48444844 assert result .get ("reasoning_content" ) is None
48454845 assert result ["content" ] == "Hello!"
48464846
48474847
4848+ @pytest .mark .asyncio
4849+ async def test_content_to_message_param_anthropic_model_round_trip_preserves_signature ():
4850+ """Decoded signatures are re-encoded when rebuilding Anthropic messages."""
4851+ response_message = {
4852+ "role" : "assistant" ,
4853+ "content" : "Final answer" ,
4854+ "thinking_blocks" : [{
4855+ "type" : "thinking" ,
4856+ "thinking" : "Let me reason..." ,
4857+ "signature" : "c2lnX2E=" ,
4858+ }],
4859+ }
4860+
4861+ parts = _convert_reasoning_value_to_parts (
4862+ _extract_reasoning_value (response_message )
4863+ )
4864+ content = types .Content (
4865+ role = "model" ,
4866+ parts = parts + [types .Part (text = "Final answer" )],
4867+ )
4868+
4869+ result = await _content_to_message_param (
4870+ content ,
4871+ provider = "anthropic" ,
4872+ model = "anthropic/claude-4-sonnet" ,
4873+ )
4874+
4875+ assert result ["thinking_blocks" ] == [{
4876+ "type" : "thinking" ,
4877+ "thinking" : "Let me reason..." ,
4878+ "signature" : "c2lnX2E=" ,
4879+ }]
4880+ assert result .get ("reasoning_content" ) is None
4881+
4882+
48484883@pytest .mark .asyncio
48494884async def test_content_to_message_param_non_anthropic_uses_reasoning_content ():
48504885 """For non-Anthropic models, reasoning_content is used as before."""
0 commit comments