Skip to content

Commit 003b6d6

Browse files
Python: Add tool call/result content types and update connectors and samples (microsoft#2971)
* Add new AI content types and image tool support Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Add Python content types for tool calls/results and image generation tool support Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Address review feedback for tool content and samples Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Tighten image generation typing and sample tools list Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Align image generation output typing Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Handle MCP naming, image options mapping, and connector tool content Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Allow MCP call in function approval request Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Remove raw image_generation tool remapping Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Restore Anthropic tool_use to function calls unless code execution Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Fix lint issues for hosted file docstring and MCP parsing Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Import ChatResponse types in Anthropic client Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Fix Anthropics citation type imports and MCP typing for handoff/tools Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Skip lightning tests without agentlightning and fix function call import Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * fix lint on lab package * rebuilt anthropic parsing * redid anthropic parsing * typo * updated parsing and added missing docstrings * fix tests * mypy fixes * second mypy fix * add new class to other samples --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
1 parent 4557110 commit 003b6d6

15 files changed

Lines changed: 995 additions & 242 deletions

python/packages/anthropic/agent_framework_anthropic/_chat_client.py

Lines changed: 216 additions & 31 deletions
Large diffs are not rendered by default.

python/packages/core/agent_framework/_tools.py

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
Generic,
1717
Literal,
1818
Protocol,
19+
TypedDict,
1920
TypeVar,
2021
cast,
2122
get_args,
@@ -73,6 +74,7 @@
7374
"FunctionInvocationConfiguration",
7475
"HostedCodeInterpreterTool",
7576
"HostedFileSearchTool",
77+
"HostedImageGenerationTool",
7678
"HostedMCPSpecificApproval",
7779
"HostedMCPTool",
7880
"HostedWebSearchTool",
@@ -324,6 +326,41 @@ def __init__(
324326
super().__init__(**args)
325327

326328

329+
class HostedImageGenerationToolOptions(TypedDict, total=False):
330+
"""Options for HostedImageGenerationTool."""
331+
332+
count: int
333+
image_size: str
334+
media_type: str
335+
model_id: str
336+
response_format: Literal["uri", "data", "hosted"]
337+
streaming_count: int
338+
339+
340+
class HostedImageGenerationTool(BaseTool):
341+
"""Represents a hosted tool that can be specified to an AI service to enable it to perform image generation."""
342+
343+
def __init__(
344+
self,
345+
*,
346+
options: HostedImageGenerationToolOptions | None = None,
347+
description: str | None = None,
348+
additional_properties: dict[str, Any] | None = None,
349+
**kwargs: Any,
350+
):
351+
"""Initialize a HostedImageGenerationTool."""
352+
if "name" in kwargs:
353+
raise ValueError("The 'name' argument is reserved for the HostedImageGenerationTool and cannot be set.")
354+
355+
self.options = options
356+
super().__init__(
357+
name="image_generation",
358+
description=description or "",
359+
additional_properties=additional_properties,
360+
**kwargs,
361+
)
362+
363+
327364
class HostedMCPSpecificApproval(TypedDict, total=False):
328365
"""Represents the specific mode for a hosted tool.
329366
@@ -1419,14 +1456,11 @@ async def _auto_invoke_function(
14191456
Raises:
14201457
KeyError: If the requested function is not found in the tool map.
14211458
"""
1422-
from ._types import (
1423-
FunctionResultContent,
1424-
)
1425-
14261459
# Note: The scenarios for approval_mode="always_require", declaration_only, and
14271460
# terminate_on_unknown_calls are all handled in _try_execute_function_calls before
14281461
# this function is called. This function only handles the actual execution of approved,
14291462
# non-declaration-only functions.
1463+
from ._types import FunctionCallContent, FunctionResultContent
14301464

14311465
tool: AIFunction[BaseModel, Any] | None = None
14321466
if function_call_content.type == "function_call":
@@ -1444,11 +1478,14 @@ async def _auto_invoke_function(
14441478
else:
14451479
# Note: Unapproved tools (approved=False) are handled in _replace_approval_contents_with_results
14461480
# and never reach this function, so we only handle approved=True cases here.
1447-
tool = tool_map.get(function_call_content.function_call.name)
1481+
inner_call = function_call_content.function_call
1482+
if not isinstance(inner_call, FunctionCallContent):
1483+
return function_call_content
1484+
tool = tool_map.get(inner_call.name)
14481485
if tool is None:
14491486
# we assume it is a hosted tool
14501487
return function_call_content
1451-
function_call_content = function_call_content.function_call
1488+
function_call_content = inner_call
14521489

14531490
parsed_args: dict[str, Any] = dict(function_call_content.parse_arguments() or {})
14541491

0 commit comments

Comments
 (0)