|
20 | 20 | from google.adk import version as adk_version |
21 | 21 | from google.adk.models import anthropic_llm |
22 | 22 | from google.adk.models.anthropic_llm import Claude |
| 23 | +from google.adk.models.anthropic_llm import content_to_message_param |
23 | 24 | from google.adk.models.anthropic_llm import function_declaration_to_tool_param |
24 | 25 | from google.adk.models.llm_request import LlmRequest |
25 | 26 | from google.adk.models.llm_response import LlmResponse |
@@ -346,3 +347,81 @@ async def mock_coro(): |
346 | 347 | mock_client.messages.create.assert_called_once() |
347 | 348 | _, kwargs = mock_client.messages.create.call_args |
348 | 349 | assert kwargs["max_tokens"] == 4096 |
| 350 | + |
| 351 | + |
| 352 | +content_to_message_param_test_cases = [ |
| 353 | + ( |
| 354 | + "user_role_with_text_and_image", |
| 355 | + Content( |
| 356 | + role="user", |
| 357 | + parts=[ |
| 358 | + Part.from_text(text="What's in this image?"), |
| 359 | + Part( |
| 360 | + inline_data=types.Blob( |
| 361 | + mime_type="image/jpeg", data=b"fake_image_data" |
| 362 | + ) |
| 363 | + ), |
| 364 | + ], |
| 365 | + ), |
| 366 | + "user", |
| 367 | + 2, # Expected content length |
| 368 | + False, # Should not log warning |
| 369 | + ), |
| 370 | + ( |
| 371 | + "model_role_with_text_and_image", |
| 372 | + Content( |
| 373 | + role="model", |
| 374 | + parts=[ |
| 375 | + Part.from_text(text="I see a cat."), |
| 376 | + Part( |
| 377 | + inline_data=types.Blob( |
| 378 | + mime_type="image/png", data=b"fake_image_data" |
| 379 | + ) |
| 380 | + ), |
| 381 | + ], |
| 382 | + ), |
| 383 | + "assistant", |
| 384 | + 1, # Image filtered out, only text remains |
| 385 | + True, # Should log warning |
| 386 | + ), |
| 387 | + ( |
| 388 | + "assistant_role_with_text_and_image", |
| 389 | + Content( |
| 390 | + role="assistant", |
| 391 | + parts=[ |
| 392 | + Part.from_text(text="Here's what I found."), |
| 393 | + Part( |
| 394 | + inline_data=types.Blob( |
| 395 | + mime_type="image/webp", data=b"fake_image_data" |
| 396 | + ) |
| 397 | + ), |
| 398 | + ], |
| 399 | + ), |
| 400 | + "assistant", |
| 401 | + 1, # Image filtered out, only text remains |
| 402 | + True, # Should log warning |
| 403 | + ), |
| 404 | +] |
| 405 | + |
| 406 | + |
| 407 | +@pytest.mark.parametrize( |
| 408 | + "_, content, expected_role, expected_content_length, should_log_warning", |
| 409 | + content_to_message_param_test_cases, |
| 410 | + ids=[case[0] for case in content_to_message_param_test_cases], |
| 411 | +) |
| 412 | +def test_content_to_message_param_with_images( |
| 413 | + _, content, expected_role, expected_content_length, should_log_warning |
| 414 | +): |
| 415 | + """Test content_to_message_param handles images correctly based on role.""" |
| 416 | + with mock.patch("google.adk.models.anthropic_llm.logger") as mock_logger: |
| 417 | + result = content_to_message_param(content) |
| 418 | + |
| 419 | + assert result["role"] == expected_role |
| 420 | + assert len(result["content"]) == expected_content_length |
| 421 | + |
| 422 | + if should_log_warning: |
| 423 | + mock_logger.warning.assert_called_once_with( |
| 424 | + "Image data is not supported in Claude for model turns." |
| 425 | + ) |
| 426 | + else: |
| 427 | + mock_logger.warning.assert_not_called() |
0 commit comments