Python: [BREAKING] Replace Hosted*Tool classes with tool methods (#3634)

* Replace Hosted*Tool classes with client static factory methods

* fixed failing test

* mypy fix

* mypy fix 2

* declarative mypy fix

* addressed comments

* ToolProtocol removal

* fixed test

* agents mypy fix

* fix failing tests

* mypy fix

* addressed comments

* fixed tests

* addressed comments + added factory method overrides for azureai v2 client

* mypy fix

* added kwargs to azureai tool methods

* fixed in test

* _sessions fix

* test fix
This commit is contained in:
Giles Odigwe
2026-02-10 16:04:27 -08:00
committed by GitHub
Unverified
parent d249473a6d
commit 7a88af0aef
133 changed files with 3018 additions and 2650 deletions
@@ -32,20 +32,20 @@ async with (
|------|-------------|
| [`azure_ai_provider_methods.py`](azure_ai_provider_methods.py) | Comprehensive example demonstrating all `AzureAIAgentsProvider` methods: `create_agent()`, `get_agent()`, `as_agent()`, and managing multiple agents from a single provider. |
| [`azure_ai_basic.py`](azure_ai_basic.py) | The simplest way to create an agent using `AzureAIAgentsProvider`. It automatically handles all configuration using environment variables. Shows both streaming and non-streaming responses. |
| [`azure_ai_with_bing_custom_search.py`](azure_ai_with_bing_custom_search.py) | Shows how to use Bing Custom Search with Azure AI agents to find real-time information from the web using custom search configurations. Demonstrates how to set up and use HostedWebSearchTool with custom search instances. |
| [`azure_ai_with_bing_grounding.py`](azure_ai_with_bing_grounding.py) | Shows how to use Bing Grounding search with Azure AI agents to find real-time information from the web. Demonstrates web search capabilities with proper source citations and comprehensive error handling. |
| [`azure_ai_with_bing_custom_search.py`](azure_ai_with_bing_custom_search.py) | Shows how to use Bing Custom Search with Azure AI agents to find real-time information from the web using custom search configurations. Demonstrates how to use `AzureAIAgentClient.get_web_search_tool()` with custom search instances. |
| [`azure_ai_with_bing_grounding.py`](azure_ai_with_bing_grounding.py) | Shows how to use Bing Grounding search with Azure AI agents to find real-time information from the web. Demonstrates `AzureAIAgentClient.get_web_search_tool()` with proper source citations and comprehensive error handling. |
| [`azure_ai_with_bing_grounding_citations.py`](azure_ai_with_bing_grounding_citations.py) | Demonstrates how to extract and display citations from Bing Grounding search responses. Shows how to collect citation annotations (title, URL, snippet) during streaming responses, enabling users to verify sources and access referenced content. |
| [`azure_ai_with_code_interpreter_file_generation.py`](azure_ai_with_code_interpreter_file_generation.py) | Shows how to retrieve file IDs from code interpreter generated files using both streaming and non-streaming approaches. |
| [`azure_ai_with_code_interpreter.py`](azure_ai_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Azure AI agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
| [`azure_ai_with_code_interpreter.py`](azure_ai_with_code_interpreter.py) | Shows how to use `AzureAIAgentClient.get_code_interpreter_tool()` with Azure AI agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
| [`azure_ai_with_existing_agent.py`](azure_ai_with_existing_agent.py) | Shows how to work with an existing SDK Agent object using `provider.as_agent()`. This wraps the agent without making HTTP calls. |
| [`azure_ai_with_existing_thread.py`](azure_ai_with_existing_thread.py) | Shows how to work with a pre-existing thread by providing the thread ID. Demonstrates proper cleanup of manually created threads. |
| [`azure_ai_with_explicit_settings.py`](azure_ai_with_explicit_settings.py) | Shows how to create an agent with explicitly configured provider settings, including project endpoint and model deployment name. |
| [`azure_ai_with_azure_ai_search.py`](azure_ai_with_azure_ai_search.py) | Demonstrates how to use Azure AI Search with Azure AI agents. Shows how to create an agent with search tools using the SDK directly and wrap it with `provider.get_agent()`. |
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Demonstrates how to use the HostedFileSearchTool with Azure AI agents to search through uploaded documents. Shows file upload, vector store creation, and querying document content. |
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Demonstrates how to use `AzureAIAgentClient.get_file_search_tool()` with Azure AI agents to search through uploaded documents. Shows file upload, vector store creation, and querying document content. |
| [`azure_ai_with_function_tools.py`](azure_ai_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to integrate Azure AI agents with hosted Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates remote MCP server connections and tool discovery. |
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to use `AzureAIAgentClient.get_mcp_tool()` with hosted Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates remote MCP server connections and tool discovery. |
| [`azure_ai_with_local_mcp.py`](azure_ai_with_local_mcp.py) | Shows how to integrate Azure AI agents with local Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates both agent-level and run-level tool configuration. |
| [`azure_ai_with_multiple_tools.py`](azure_ai_with_multiple_tools.py) | Demonstrates how to use multiple tools together with Azure AI agents, including web search, MCP servers, and function tools. Shows coordinated multi-tool interactions and approval workflows. |
| [`azure_ai_with_multiple_tools.py`](azure_ai_with_multiple_tools.py) | Demonstrates how to use multiple tools together with Azure AI agents, including web search, MCP servers, and function tools using client static methods. Shows coordinated multi-tool interactions and approval workflows. |
| [`azure_ai_with_openapi_tools.py`](azure_ai_with_openapi_tools.py) | Demonstrates how to use OpenAPI tools with Azure AI agents to integrate external REST APIs. Shows OpenAPI specification loading, anonymous authentication, thread context management, and coordinated multi-API conversations. |
| [`azure_ai_with_response_format.py`](azure_ai_with_response_format.py) | Demonstrates how to use structured outputs with Azure AI agents using Pydantic models. |
| [`azure_ai_with_thread.py`](azure_ai_with_thread.py) | Demonstrates thread management with Azure AI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
@@ -2,8 +2,7 @@
import asyncio
from agent_framework import HostedWebSearchTool
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
@@ -30,25 +29,25 @@ To set up Bing Custom Search:
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Custom Search."""
# 1. Create Bing Custom Search tool using HostedWebSearchTool
# The connection ID and instance name will be automatically picked up from environment variables
bing_search_tool = HostedWebSearchTool(
name="Bing Custom Search",
description="Search the web for current information using Bing Custom Search",
)
# 2. Use AzureAIAgentsProvider for agent creation and management
# Use AzureAIAgentsProvider for agent creation and management
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
# Create Bing Custom Search tool using instance method
# The connection ID and instance name will be automatically picked up from environment variables
# (BING_CUSTOM_CONNECTION_ID and BING_CUSTOM_INSTANCE_NAME)
bing_search_tool = client.get_web_search_tool()
agent = await provider.create_agent(
name="BingSearchAgent",
instructions=(
"You are a helpful agent that can use Bing Custom Search tools to assist users. "
"Use the available Bing Custom Search tools to answer questions and perform tasks."
),
tools=bing_search_tool,
tools=[bing_search_tool],
)
# 3. Demonstrate agent capabilities with bing custom search
@@ -2,8 +2,7 @@
import asyncio
from agent_framework import HostedWebSearchTool
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
@@ -25,18 +24,17 @@ To set up Bing Grounding:
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Grounding search."""
# 1. Create Bing Grounding search tool using HostedWebSearchTool
# The connection ID will be automatically picked up from environment variable
bing_search_tool = HostedWebSearchTool(
name="Bing Grounding Search",
description="Search the web for current information using Bing",
)
# 2. Use AzureAIAgentsProvider for agent creation and management
# Use AzureAIAgentsProvider for agent creation and management
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
# Create Bing Grounding search tool using instance method
# The connection ID will be automatically picked up from environment variable
bing_search_tool = client.get_web_search_tool()
agent = await provider.create_agent(
name="BingSearchAgent",
instructions=(
@@ -44,7 +42,7 @@ async def main() -> None:
"Use the Bing search tool to find up-to-date information and provide accurate, "
"well-sourced answers. Always cite your sources when possible."
),
tools=bing_search_tool,
tools=[bing_search_tool],
)
# 3. Demonstrate agent capabilities with web search
@@ -2,8 +2,8 @@
import asyncio
from agent_framework import Annotation, HostedWebSearchTool
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework import Annotation
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
@@ -27,18 +27,17 @@ To set up Bing Grounding:
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Grounding search."""
# 1. Create Bing Grounding search tool using HostedWebSearchTool
# The connection ID will be automatically picked up from environment variable
bing_search_tool = HostedWebSearchTool(
name="Bing Grounding Search",
description="Search the web for current information using Bing",
)
# 2. Use AzureAIAgentsProvider for agent creation and management
# Use AzureAIAgentsProvider for agent creation and management
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
# Create Bing Grounding search tool using instance method
# The connection ID will be automatically picked up from environment variable
bing_search_tool = client.get_web_search_tool()
agent = await provider.create_agent(
name="BingSearchAgent",
instructions=(
@@ -46,7 +45,7 @@ async def main() -> None:
"Use the Bing search tool to find up-to-date information and provide accurate, "
"well-sourced answers. Always cite your sources when possible."
),
tools=bing_search_tool,
tools=[bing_search_tool],
)
# 3. Demonstrate agent capabilities with web search
@@ -2,8 +2,8 @@
import asyncio
from agent_framework import AgentResponse, ChatResponseUpdate, HostedCodeInterpreterTool
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework import AgentResponse, ChatResponseUpdate
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.ai.agents.models import (
RunStepDeltaCodeInterpreterDetailItemObject,
)
@@ -12,7 +12,7 @@ from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Code Interpreter Example
This sample demonstrates using HostedCodeInterpreterTool with Azure AI Agents
This sample demonstrates using get_code_interpreter_tool() with Azure AI Agents
for Python code execution and mathematical problem solving.
"""
@@ -32,7 +32,7 @@ def print_code_interpreter_inputs(response: AgentResponse) -> None:
async def main() -> None:
"""Example showing how to use the HostedCodeInterpreterTool with Azure AI."""
"""Example showing how to use the code interpreter tool with Azure AI."""
print("=== Azure AI Agent with Code Interpreter Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
@@ -41,10 +41,14 @@ async def main() -> None:
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="CodingAgent",
instructions=("You are a helpful assistant that can write and execute Python code to solve problems."),
tools=HostedCodeInterpreterTool(),
tools=[code_interpreter_tool],
)
query = "Generate the factorial of 100 using python code, show the code and execute it."
print(f"User: {query}")
@@ -3,17 +3,14 @@
import asyncio
import os
from agent_framework import (
HostedCodeInterpreterTool,
)
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.ai.agents.aio import AgentsClient
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent Code Interpreter File Generation Example
This sample demonstrates using HostedCodeInterpreterTool with AzureAIAgentsProvider
This sample demonstrates using get_code_interpreter_tool() with AzureAIAgentsProvider
to generate a text file and then retrieve it.
The test flow:
@@ -32,6 +29,10 @@ async def main() -> None:
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="CodeInterpreterAgent",
instructions=(
@@ -39,7 +40,7 @@ async def main() -> None:
"ALWAYS use the code interpreter tool to execute Python code when asked to create files. "
"Write actual Python code to create files, do not just describe what you would do."
),
tools=[HostedCodeInterpreterTool()],
tools=[code_interpreter_tool],
)
# Be very explicit about wanting code execution and a download link
@@ -19,7 +19,9 @@ by providing thread IDs for thread reuse patterns.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/getting_started/tools/function_tool_with_approval.py
# and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
@@ -18,7 +18,9 @@ settings rather than relying on environment variable defaults.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/getting_started/tools/function_tool_with_approval.py
# and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
@@ -4,8 +4,7 @@ import asyncio
import os
from pathlib import Path
from agent_framework import Content, HostedFileSearchTool
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.ai.agents.aio import AgentsClient
from azure.ai.agents.models import FileInfo, VectorStore
from azure.identity.aio import AzureCliCredential
@@ -45,8 +44,9 @@ async def main() -> None:
vector_store = await agents_client.vector_stores.create_and_poll(file_ids=[file.id], name="my_vectorstore")
print(f"Created vector store, vector store ID: {vector_store.id}")
# 2. Create file search tool with uploaded resources
file_search_tool = HostedFileSearchTool(inputs=[Content.from_hosted_vector_store(vector_store_id=vector_store.id)])
# 2. Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
file_search_tool = client.get_file_search_tool(vector_store_ids=[vector_store.id])
# 3. Create an agent with file search capabilities
agent = await provider.create_agent(
@@ -55,7 +55,7 @@ async def main() -> None:
"You are a helpful assistant that can search through uploaded employee files "
"to answer questions about employees."
),
tools=file_search_tool,
tools=[file_search_tool],
)
# 4. Simulate conversation with the agent
@@ -18,7 +18,9 @@ showing both agent-level and query-level tool configuration patterns.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/getting_started/tools/function_tool_with_approval.py
# and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
@@ -3,8 +3,8 @@
import asyncio
from typing import Any
from agent_framework import AgentResponse, AgentThread, HostedMCPTool, SupportsAgentRun
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework import AgentResponse, AgentThread, SupportsAgentRun
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
@@ -40,17 +40,23 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
async def main() -> None:
"""Example showing Hosted MCP tools for a Azure AI Agent."""
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
# Create MCP tool using instance method
mcp_tool = client.get_mcp_tool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
)
agent = await provider.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=HostedMCPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
),
tools=[mcp_tool],
)
thread = agent.get_new_thread()
# First query
@@ -6,12 +6,10 @@ from typing import Any
from agent_framework import (
AgentThread,
HostedMCPTool,
HostedWebSearchTool,
SupportsAgentRun,
tool,
)
from agent_framework.azure import AzureAIAgentsProvider
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
@@ -35,7 +33,9 @@ To set up Bing Grounding:
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/getting_started/tools/function_tool_with_approval.py
# and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_time() -> str:
"""Get the current UTC time."""
@@ -67,20 +67,27 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
async def main() -> None:
"""Example showing Hosted MCP tools for a Azure AI Agent."""
"""Example showing multiple tools for an Azure AI Agent."""
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIAgentClient(credential=credential)
# Create tools using instance methods
mcp_tool = client.get_mcp_tool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
)
web_search_tool = client.get_web_search_tool()
agent = await provider.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=[
HostedMCPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
),
HostedWebSearchTool(count=5),
mcp_tool,
web_search_tool,
get_time,
],
)
@@ -17,7 +17,9 @@ automatic thread creation with explicit thread management for persistent context
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/getting_started/tools/function_tool_with_approval.py and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/getting_started/tools/function_tool_with_approval.py
# and samples/getting_started/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],