Python: [BREAKING] changed AIFunction to FunctionTool and @ai_function to @tool (#3413)

* changed AIFunction to FunctionTool and @ai_function to @tool

* test and mypy fixes

* mypy fix

* switch function tool to always_require

* fix noop

* fix github copilot imports

* test fixes

* fix ollama test

* fixes for tests

* fix tests

* reverted change to always_require and extended timeout

* fix test
This commit is contained in:
Eduard van Valkenburg
2026-01-28 15:53:53 +01:00
committed by GitHub
Unverified
parent 15b43f2abe
commit a7d924a7d2
255 changed files with 1202 additions and 1290 deletions
@@ -6,7 +6,7 @@ from copy import deepcopy
from typing import Any
import numpy as np
from agent_framework._tools import AIFunction
from agent_framework._tools import FunctionTool
from agent_framework._types import ChatMessage
from loguru import logger
from pydantic import BaseModel
@@ -25,8 +25,8 @@ from tau2.environment.tool import Tool # type: ignore[import-untyped]
_original_set_state = Environment.set_state
def convert_tau2_tool_to_ai_function(tau2_tool: Tool) -> AIFunction[Any, Any]:
"""Convert a tau2 Tool to an AIFunction for agent framework compatibility.
def convert_tau2_tool_to_function_tool(tau2_tool: Tool) -> FunctionTool[Any, Any]:
"""Convert a tau2 Tool to a FunctionTool for agent framework compatibility.
Creates a wrapper that preserves the tool's interface while ensuring
results are deep-copied to prevent unintended mutations.
@@ -37,7 +37,7 @@ def convert_tau2_tool_to_ai_function(tau2_tool: Tool) -> AIFunction[Any, Any]:
# Deep copy to prevent mutations of returned data
return result.model_copy(deep=True) if isinstance(result, BaseModel) else deepcopy(result)
return AIFunction(
return FunctionTool(
name=tau2_tool.name,
description=tau2_tool._get_description(),
func=wrapped_func,
@@ -32,7 +32,7 @@ from tau2.utils.utils import get_now # type: ignore[import-untyped]
from ._message_utils import flip_messages, log_messages
from ._sliding_window import SlidingWindowChatMessageStore
from ._tau2_utils import convert_agent_framework_messages_to_tau2_messages, convert_tau2_tool_to_ai_function
from ._tau2_utils import convert_agent_framework_messages_to_tau2_messages, convert_tau2_tool_to_function_tool
__all__ = ["ASSISTANT_AGENT_ID", "ORCHESTRATOR_ID", "USER_SIMULATOR_ID", "TaskRunner"]
@@ -179,9 +179,9 @@ class TaskRunner:
f"Environment has {len(env.get_tools())} tools: {', '.join([tool.name for tool in env.get_tools()])}"
)
# Convert tau2 tools to agent framework AIFunction format
# Convert tau2 tools to agent framework FunctionTool format
# This bridges the gap between tau2's tool system and agent framework's expectations
ai_functions = [convert_tau2_tool_to_ai_function(tool) for tool in tools]
tools = [convert_tau2_tool_to_function_tool(tool) for tool in tools]
# Combines general customer service behavior with specific policy guidelines
assistant_system_prompt = f"""<instructions>
@@ -198,7 +198,7 @@ class TaskRunner:
return ChatAgent(
chat_client=assistant_chat_client,
instructions=assistant_system_prompt,
tools=ai_functions,
tools=tools,
temperature=self.assistant_sampling_temperature,
chat_message_store_factory=lambda: SlidingWindowChatMessageStore(
system_message=assistant_system_prompt,
@@ -6,11 +6,10 @@ import urllib.request
from pathlib import Path
import pytest
from agent_framework._tools import AIFunction
from agent_framework._types import ChatMessage, Content, Role
from agent_framework import ChatMessage, Content, FunctionTool, Role
from agent_framework_lab_tau2._tau2_utils import (
convert_agent_framework_messages_to_tau2_messages,
convert_tau2_tool_to_ai_function,
convert_tau2_tool_to_function_tool,
)
from tau2.data_model.message import AssistantMessage, SystemMessage, ToolCall, ToolMessage, UserMessage
from tau2.domains.airline.data_model import FlightDB
@@ -51,8 +50,8 @@ def tau2_airline_environment() -> Environment:
)
def test_convert_tau2_tool_to_ai_function_basic(tau2_airline_environment):
"""Test basic conversion from tau2 tool to AIFunction."""
def test_convert_tau2_tool_to_function_tool_basic(tau2_airline_environment):
"""Test basic conversion from tau2 tool to FunctionTool."""
# Get real tools from tau2 environment
tools = tau2_airline_environment.get_tools()
@@ -61,33 +60,33 @@ def test_convert_tau2_tool_to_ai_function_basic(tau2_airline_environment):
tau2_tool = tools[0]
# Convert the tool
ai_function = convert_tau2_tool_to_ai_function(tau2_tool)
tool = convert_tau2_tool_to_function_tool(tau2_tool)
# Verify the conversion
assert isinstance(ai_function, AIFunction)
assert ai_function.name == tau2_tool.name
assert ai_function.description == tau2_tool._get_description()
assert ai_function.input_model == tau2_tool.params
assert isinstance(tool, FunctionTool)
assert tool.name == tau2_tool.name
assert tool.description == tau2_tool._get_description()
assert tool.input_model == tau2_tool.params
# Test that the function is callable (we won't call it with real params to avoid side effects)
assert callable(ai_function.func)
assert callable(tool.func)
def test_convert_tau2_tool_to_ai_function_multiple_tools(tau2_airline_environment):
def test_convert_tau2_tool_to_function_tool_multiple_tools(tau2_airline_environment):
"""Test conversion with multiple tau2 tools."""
# Get real tools from tau2 environment
tools = tau2_airline_environment.get_tools()
# Convert multiple tools
ai_functions = [convert_tau2_tool_to_ai_function(tool) for tool in tools[:3]] # Test first 3 tools
function_tools = [convert_tau2_tool_to_function_tool(tool) for tool in tools[:3]] # Test first 3 tools
# Verify all conversions
for ai_function, tau2_tool in zip(ai_functions, tools[:3], strict=False):
assert isinstance(ai_function, AIFunction)
assert ai_function.name == tau2_tool.name
assert ai_function.description == tau2_tool._get_description()
assert ai_function.input_model == tau2_tool.params
assert callable(ai_function.func)
for tool, tau2_tool in zip(function_tools, tools[:3], strict=False):
assert isinstance(tool, FunctionTool)
assert tool.name == tau2_tool.name
assert tool.description == tau2_tool._get_description()
assert tool.input_model == tau2_tool.params
assert callable(tool.func)
def test_convert_agent_framework_messages_to_tau2_messages_system():