Skip to content

Commit fcf72a0

Browse files
cpsievertCopilot
andauthored
Support returning ContentToolResultImage from a tool with ChatAnthropic (#118)
* wip support ContentToolResultImage/ContentToolResultResource where we can * Update chatlas/_google.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Simplify --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent c359721 commit fcf72a0

File tree

5 files changed

+46
-16
lines changed

5 files changed

+46
-16
lines changed

chatlas/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from ._anthropic import ChatAnthropic, ChatBedrockAnthropic
33
from ._auto import ChatAuto
44
from ._chat import Chat
5-
from ._content import ContentToolRequest, ContentToolResult
5+
from ._content import ContentToolRequest, ContentToolResult, ContentToolResultImage
66
from ._content_image import content_image_file, content_image_plot, content_image_url
77
from ._content_pdf import content_pdf_file, content_pdf_url
88
from ._databricks import ChatDatabricks
@@ -46,6 +46,7 @@
4646
"content_pdf_url",
4747
"ContentToolRequest",
4848
"ContentToolResult",
49+
"ContentToolResultImage",
4950
"interpolate",
5051
"interpolate_file",
5152
"Provider",

chatlas/_anthropic.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
ContentText,
1818
ContentToolRequest,
1919
ContentToolResult,
20+
ContentToolResultImage,
21+
ContentToolResultResource,
2022
)
2123
from ._logging import log_model_default
2224
from ._provider import Provider, StandardModelParamNames, StandardModelParams
@@ -515,8 +517,26 @@ def _as_content_block(content: Content) -> "ContentBlockParam":
515517
"tool_use_id": content.id,
516518
"is_error": content.error is not None,
517519
}
518-
# Anthropic supports non-text contents like ImageBlockParam
519-
res["content"] = content.get_model_value() # type: ignore
520+
521+
if isinstance(content, ContentToolResultImage):
522+
res["content"] = [
523+
{
524+
"type": "image",
525+
"source": {
526+
"type": "base64",
527+
"media_type": content.mime_type,
528+
"data": content.value,
529+
},
530+
}
531+
]
532+
elif isinstance(content, ContentToolResultResource):
533+
raise NotImplementedError(
534+
"ContentToolResultResource is not currently supported by Anthropic."
535+
)
536+
else:
537+
# Anthropic supports non-text contents like ImageBlockParam
538+
res["content"] = content.get_model_value() # type: ignore
539+
520540
return res
521541

522542
raise ValueError(f"Unknown content type: {type(content)}")

chatlas/_google.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
ContentText,
1717
ContentToolRequest,
1818
ContentToolResult,
19+
ContentToolResultImage,
20+
ContentToolResultResource,
1921
)
2022
from ._logging import log_model_default
2123
from ._merge import merge_dicts
@@ -424,6 +426,13 @@ def _as_part_type(self, content: Content) -> "Part":
424426
)
425427
)
426428
elif isinstance(content, ContentToolResult):
429+
if isinstance(
430+
content, (ContentToolResultImage, ContentToolResultResource)
431+
):
432+
raise NotImplementedError(
433+
"Tool results with images or resources aren't supported by Google (Gemini). "
434+
)
435+
427436
if content.error:
428437
resp = {"error": content.error}
429438
else:

chatlas/_openai.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
ContentText,
1919
ContentToolRequest,
2020
ContentToolResult,
21+
ContentToolResultImage,
22+
ContentToolResultResource,
2123
)
2224
from ._logging import log_model_default
2325
from ._merge import merge_dicts
@@ -482,6 +484,12 @@ def _as_message_param(turns: list[Turn]) -> list["ChatCompletionMessageParam"]:
482484
}
483485
)
484486
elif isinstance(x, ContentToolResult):
487+
if isinstance(
488+
x, (ContentToolResultImage, ContentToolResultResource)
489+
):
490+
raise NotImplementedError(
491+
"OpenAI does not support tool results with images or resources."
492+
)
485493
tool_results.append(
486494
ChatCompletionToolMessageParam(
487495
# Currently, OpenAI only allows for text content in tool results

tests/test_provider_anthropic.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
import httpx
44
import pytest
5-
6-
from chatlas import ChatAnthropic, ContentToolResult
5+
from chatlas import ChatAnthropic, ContentToolResultImage
76

87
from .conftest import (
98
assert_data_extraction,
@@ -108,17 +107,10 @@ def get_picture():
108107
# Local copy of https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png
109108
with open(test_images_dir / "dice.png", "rb") as image:
110109
bytez = image.read()
111-
res = [
112-
{
113-
"type": "image",
114-
"source": {
115-
"type": "base64",
116-
"media_type": "image/png",
117-
"data": base64.b64encode(bytez).decode("utf-8"),
118-
},
119-
}
120-
]
121-
return ContentToolResult(value=res, model_format="as_is")
110+
return ContentToolResultImage(
111+
value=base64.b64encode(bytez).decode("utf-8"),
112+
mime_type="image/png",
113+
)
122114

123115
chat = ChatAnthropic()
124116
chat.register_tool(get_picture)

0 commit comments

Comments
 (0)