test(anthropic): pin tool_result image_url conversion regression
Adds a focused regression test so the fix for tool_result image handling cannot silently revert. Two cases: - list content with an image_url + text block -> image_url is translated to a native Anthropic image block, sibling text passes through unchanged - plain string content passes through untouched (the new list branch must not alter the string path) These cover the exact symptom surface (silent image drop with a "Non-transient LLM error with image content" warning) and the only two content shapes tool results actually take today. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""Tests for AnthropicProvider._tool_result_block image_url conversion.
|
||||
|
||||
Regression for: tool results containing OpenAI-format image_url blocks
|
||||
(e.g. from read_file on an image file, via build_image_content_blocks)
|
||||
were passed to Anthropic unconverted, causing silent image drops with a
|
||||
"Non-transient LLM error with image content, retrying without images"
|
||||
warning.
|
||||
"""
|
||||
|
||||
from nanobot.providers.anthropic_provider import AnthropicProvider
|
||||
|
||||
|
||||
def test_tool_result_block_converts_image_url_in_list_content():
|
||||
"""image_url blocks inside tool_result list content must be translated
|
||||
to Anthropic-native image blocks; sibling text blocks pass through."""
|
||||
msg = {
|
||||
"role": "tool",
|
||||
"tool_call_id": "call_1",
|
||||
"content": [
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {"url": "data:image/png;base64,AAAA"},
|
||||
"_meta": {"path": "/tmp/x.png"},
|
||||
},
|
||||
{"type": "text", "text": "(Image file: /tmp/x.png)"},
|
||||
],
|
||||
}
|
||||
block = AnthropicProvider._tool_result_block(msg)
|
||||
|
||||
assert block["type"] == "tool_result"
|
||||
assert block["tool_use_id"] == "call_1"
|
||||
content = block["content"]
|
||||
assert isinstance(content, list)
|
||||
assert content[0] == {
|
||||
"type": "image",
|
||||
"source": {
|
||||
"type": "base64",
|
||||
"media_type": "image/png",
|
||||
"data": "AAAA",
|
||||
},
|
||||
}
|
||||
assert content[1] == {"type": "text", "text": "(Image file: /tmp/x.png)"}
|
||||
|
||||
|
||||
def test_tool_result_block_preserves_string_content():
|
||||
"""String content must be passed through unchanged; the image-conversion
|
||||
path for lists must not affect the string path."""
|
||||
msg = {
|
||||
"role": "tool",
|
||||
"tool_call_id": "call_2",
|
||||
"content": "plain tool output",
|
||||
}
|
||||
block = AnthropicProvider._tool_result_block(msg)
|
||||
|
||||
assert block["type"] == "tool_result"
|
||||
assert block["tool_use_id"] == "call_2"
|
||||
assert block["content"] == "plain tool output"
|
||||
Reference in New Issue
Block a user