Skip to content

Commit 26b7cab

Browse files
google-genai-botcopybara-github
authored andcommitted
fix: Add support for code execution result and skip inline data in anthropic llm
``` blaze run assistant/lamda/bard/scrape/vertex/tools:use_vertex_agent -- --prompt_collection_id=cab_v0p7@3 --agent_name=vertex_1p_agent --kernel_id=vertex_agent:claude-sonnet-4@20250514 --dynamically_inject_tools=True --add_final_answer_tag=True --example_ids=plot-line-004_0.5_new_1 ``` TODO: https://evalhub.corp.google.com/runs/Uf5en14gqmK-R/links PiperOrigin-RevId: 768098002
1 parent 68f3413 commit 26b7cab

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

src/google/adk/models/anthropic_llm.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
from __future__ import annotations
1818

19+
import base64
1920
from functools import cached_property
2021
import logging
2122
import os
@@ -45,7 +46,7 @@
4546

4647
logger = logging.getLogger("google_adk." + __name__)
4748

48-
MAX_TOKEN = 1024
49+
MAX_TOKEN = 8192
4950

5051

5152
class ClaudeRequest(BaseModel):
@@ -70,6 +71,14 @@ def to_google_genai_finish_reason(
7071
return "FINISH_REASON_UNSPECIFIED"
7172

7273

74+
def _is_image_part(part: types.Part) -> bool:
75+
return (
76+
part.inline_data
77+
and part.inline_data.mime_type
78+
and part.inline_data.mime_type.startswith("image")
79+
)
80+
81+
7382
def part_to_message_block(
7483
part: types.Part,
7584
) -> Union[
@@ -80,7 +89,7 @@ def part_to_message_block(
8089
]:
8190
if part.text:
8291
return anthropic_types.TextBlockParam(text=part.text, type="text")
83-
if part.function_call:
92+
elif part.function_call:
8493
assert part.function_call.name
8594

8695
return anthropic_types.ToolUseBlockParam(
@@ -89,7 +98,7 @@ def part_to_message_block(
8998
input=part.function_call.args,
9099
type="tool_use",
91100
)
92-
if part.function_response:
101+
elif part.function_response:
93102
content = ""
94103
if (
95104
"result" in part.function_response.response
@@ -105,15 +114,45 @@ def part_to_message_block(
105114
content=content,
106115
is_error=False,
107116
)
108-
raise NotImplementedError("Not supported yet.")
117+
elif _is_image_part(part):
118+
data = base64.b64encode(part.inline_data.data).decode()
119+
return anthropic_types.ImageBlockParam(
120+
type="image",
121+
source=dict(
122+
type="base64", media_type=part.inline_data.mime_type, data=data
123+
),
124+
)
125+
elif part.executable_code:
126+
return anthropic_types.TextBlockParam(
127+
type="text",
128+
text="Code:```python\n" + part.executable_code.code + "\n```",
129+
)
130+
elif part.code_execution_result:
131+
return anthropic_types.TextBlockParam(
132+
text="Execution Result:```code_output\n"
133+
+ part.code_execution_result.output
134+
+ "\n```",
135+
type="text",
136+
)
137+
138+
raise NotImplementedError(f"Not supported yet: {part}")
109139

110140

111141
def content_to_message_param(
112142
content: types.Content,
113143
) -> anthropic_types.MessageParam:
144+
message_block = []
145+
for part in content.parts or []:
146+
# Image data is not supported in Claude for model turns.
147+
if _is_image_part(part):
148+
logger.warning("Image data is not supported in Claude for model turns.")
149+
continue
150+
151+
message_block.append(part_to_message_block(part))
152+
114153
return {
115154
"role": to_claude_role(content.role),
116-
"content": [part_to_message_block(part) for part in content.parts or []],
155+
"content": message_block,
117156
}
118157

119158

0 commit comments

Comments
 (0)