mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into feature-python-foundry-agents
This commit is contained in:
@@ -330,11 +330,19 @@ class AnthropicClient(BaseChatClient):
|
||||
if content.has_top_level_media_type("image"):
|
||||
a_content.append({
|
||||
"type": "image",
|
||||
"source": {"data": content.uri, "media_type": content.media_type},
|
||||
"source": {
|
||||
"data": content.get_data_bytes_as_str(),
|
||||
"media_type": content.media_type,
|
||||
"type": "base64",
|
||||
},
|
||||
})
|
||||
else:
|
||||
logger.debug(f"Ignoring unsupported data content media type: {content.media_type} for now")
|
||||
case "uri":
|
||||
if content.has_top_level_media_type("image"):
|
||||
a_content.append({"type": "image", "source": {"type": "url", "url": content.uri}})
|
||||
else:
|
||||
logger.debug(f"Ignoring unsupported data content media type: {content.media_type} for now")
|
||||
case "function_call":
|
||||
a_content.append({
|
||||
"type": "tool_use",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
@@ -1,5 +1,6 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Annotated
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@@ -9,6 +10,7 @@ from agent_framework import (
|
||||
ChatMessage,
|
||||
ChatOptions,
|
||||
ChatResponseUpdate,
|
||||
DataContent,
|
||||
FinishReason,
|
||||
FunctionCallContent,
|
||||
FunctionResultContent,
|
||||
@@ -775,3 +777,31 @@ async def test_anthropic_client_integration_ordering() -> None:
|
||||
|
||||
assert response is not None
|
||||
assert response.messages[0].text is not None
|
||||
|
||||
|
||||
@pytest.mark.flaky
|
||||
@skip_if_anthropic_integration_tests_disabled
|
||||
async def test_anthropic_client_integration_images() -> None:
|
||||
"""Integration test with images."""
|
||||
client = AnthropicClient()
|
||||
|
||||
# get a image from the assets folder
|
||||
image_path = Path(__file__).parent / "assets" / "sample_image.jpg"
|
||||
with open(image_path, "rb") as img_file: # noqa [ASYNC230]
|
||||
image_bytes = img_file.read()
|
||||
|
||||
messages = [
|
||||
ChatMessage(
|
||||
role=Role.USER,
|
||||
contents=[
|
||||
TextContent(text="Describe this image"),
|
||||
DataContent(media_type="image/jpeg", data=image_bytes),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
response = await client.get_response(messages=messages)
|
||||
|
||||
assert response is not None
|
||||
assert response.messages[0].text is not None
|
||||
assert "house" in response.messages[0].text.lower()
|
||||
|
||||
@@ -897,6 +897,9 @@ class TextReasoningContent(BaseContent):
|
||||
return self
|
||||
|
||||
|
||||
TDataContent = TypeVar("TDataContent", bound="DataContent")
|
||||
|
||||
|
||||
class DataContent(BaseContent):
|
||||
"""Represents binary data content with an associated media type (also known as a MIME type).
|
||||
|
||||
@@ -1079,8 +1082,8 @@ class DataContent(BaseContent):
|
||||
except Exception:
|
||||
return "png" # Fallback if decoding fails
|
||||
|
||||
@classmethod
|
||||
def create_data_uri_from_base64(cls, image_base64: str) -> tuple[str, str]:
|
||||
@staticmethod
|
||||
def create_data_uri_from_base64(image_base64: str) -> tuple[str, str]:
|
||||
"""Create a data URI and media type from base64 image data.
|
||||
|
||||
Args:
|
||||
@@ -1089,11 +1092,31 @@ class DataContent(BaseContent):
|
||||
Returns:
|
||||
Tuple of (data_uri, media_type)
|
||||
"""
|
||||
format_type = cls.detect_image_format_from_base64(image_base64)
|
||||
format_type = DataContent.detect_image_format_from_base64(image_base64)
|
||||
uri = f"data:image/{format_type};base64,{image_base64}"
|
||||
media_type = f"image/{format_type}"
|
||||
return uri, media_type
|
||||
|
||||
def get_data_bytes_as_str(self) -> str:
|
||||
"""Extracts and returns the base64-encoded data from the data URI.
|
||||
|
||||
Returns:
|
||||
The binary data as str.
|
||||
"""
|
||||
match = URI_PATTERN.match(self.uri)
|
||||
if not match:
|
||||
raise ValueError(f"Invalid data URI format: {self.uri}")
|
||||
return match.group("base64_data")
|
||||
|
||||
def get_data_bytes(self) -> bytes:
|
||||
"""Extracts and returns the binary data from the data URI.
|
||||
|
||||
Returns:
|
||||
The binary data as bytes.
|
||||
"""
|
||||
base64_data = self.get_data_bytes_as_str()
|
||||
return base64.b64decode(base64_data)
|
||||
|
||||
|
||||
class UriContent(BaseContent):
|
||||
"""Represents a URI content.
|
||||
|
||||
@@ -56,7 +56,7 @@ math = [
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"uv>=0.8.2,<0.9.0",
|
||||
"uv",
|
||||
"pre-commit >= 3.7",
|
||||
"ruff>=0.11.8",
|
||||
"pytest>=8.4.1",
|
||||
|
||||
@@ -39,7 +39,7 @@ dependencies = [
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"uv>=0.8.2,<0.10.0",
|
||||
"uv>=0.9,<1.0.0",
|
||||
"flit>=3.12.0",
|
||||
"pre-commit >= 3.7",
|
||||
"ruff>=0.11.8",
|
||||
|
||||
Generated
+3443
-3427
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user