Python: restructure: Python samples into progressive 01-05 layout (#3862)

* restructure: Python samples into progressive 01-05 layout

- 01-get-started/: 6 numbered steps (hello agent → hosting)
- 02-agents/: all agent concept samples (tools, middleware, providers, etc.)
- 03-workflows/: ALL existing workflow samples preserved as-is
- 04-hosting/: azure-functions, durabletask, a2a
- 05-end-to-end/: demos, evaluation, hosted agents
- Old files moved to _to_delete/ for review
- Added AGENTS.md with structure documentation
- autogen-migration/ and semantic-kernel-migration/ preserved at root

* fix: switch to AzureOpenAI Foundry, fix CI failures

- Switch all 01-get-started samples to AzureOpenAIResponsesClient with
  Azure AI Foundry project endpoint (AZURE_AI_PROJECT_ENDPOINT +
  AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME + AzureCliCredential)
- Add _to_delete/ and 05-end-to-end/ to pyrightconfig.samples.json excludes
- Fix test paths in packages/ that referenced old getting_started/ dirs:
  durabletask conftest + streaming test, azurefunctions conftest,
  devui conftest + capture_messages + openai_sdk_integration
- Fix workflow_as_agent_human_in_the_loop.py import (sibling import)
- Update hosting READMEs and tool comment paths
- Replace root README.md with new structure overview
- Update AGENTS.md to document Azure OpenAI Foundry as default provider

* cleanup: remove _to_delete folder, copy resource files to active dirs

All files in _to_delete/ were either:
- Exact duplicates of files in the new structure (240 files)
- Same file with only comment path updates (100 files)
- One import-fix diff (workflow_as_agent_human_in_the_loop.py)
- One superseded minimal_sample.py

Resource files (sample.pdf, countries.json, employees.pdf, weather.json)
copied to 02-agents/sample_assets/ and 02-agents/resources/ since active
samples reference them.

* fix: address PR review comments, centralize resources, remove root duplicates

- Fix type annotation in 04_memory.py (string union -> proper types)
- Fix old sample paths in observability files
- Fix grammar/spelling in observability samples
- Move sample_assets/ and resources/ to shared/ folder
- Remove 8 duplicate observability files from 02-agents root
- Update resource path references in multimodal_input and provider samples

* fix: update broken links from old getting_started paths to new structure

- Update relative paths in READMEs: getting_started/ → 01-get-started/,
  02-agents/, 03-workflows/, 04-hosting/, 05-end-to-end/
- Fix absolute GitHub URLs in package READMEs
- Fix broken link in ollama package README

* fix: convert absolute GitHub URLs to relative paths for link checker

Absolute URLs to python/samples/ on main branch 404 until PR merges.
Converted to relative paths that linkspector can verify locally.

* fix: update link for handoff sample moved to orchestrations/

* fix: update chatkit-integration README path from demos/ to 05-end-to-end/

* fix: update broken links in orchestrations README to match flat directory structure
This commit is contained in:
Eduard van Valkenburg
2026-02-12 17:36:36 +00:00
committed by GitHub
parent 69dcfe31ee
commit a2856d3b92
536 changed files with 3816 additions and 1632 deletions
@@ -0,0 +1,46 @@
# Anthropic Examples
This folder contains examples demonstrating how to use Anthropic's Claude models with the Agent Framework.
## Anthropic Client Examples
| File | Description |
|------|-------------|
| [`anthropic_basic.py`](anthropic_basic.py) | Demonstrates how to setup a simple agent using the AnthropicClient, with both streaming and non-streaming responses. |
| [`anthropic_advanced.py`](anthropic_advanced.py) | Shows advanced usage of the AnthropicClient, including hosted tools and `thinking`. |
| [`anthropic_skills.py`](anthropic_skills.py) | Illustrates how to use Anthropic-managed Skills with an agent, including the Code Interpreter tool and file generation and saving. |
| [`anthropic_foundry.py`](anthropic_foundry.py) | Example of using Foundry's Anthropic integration with the Agent Framework. |
## Claude Agent Examples
| File | Description |
|------|-------------|
| [`anthropic_claude_basic.py`](anthropic_claude_basic.py) | Basic usage of ClaudeAgent with streaming, non-streaming, and custom tools. |
| [`anthropic_claude_with_tools.py`](anthropic_claude_with_tools.py) | Using built-in tools (Read, Glob, Grep, etc.). |
| [`anthropic_claude_with_shell.py`](anthropic_claude_with_shell.py) | Shell command execution with interactive permission handling. |
| [`anthropic_claude_with_multiple_permissions.py`](anthropic_claude_with_multiple_permissions.py) | Combining multiple tools (Bash, Read, Write) with permission prompts. |
| [`anthropic_claude_with_url.py`](anthropic_claude_with_url.py) | Fetching and processing web content with WebFetch. |
| [`anthropic_claude_with_mcp.py`](anthropic_claude_with_mcp.py) | Local (stdio) and remote (HTTP) MCP server configuration. |
| [`anthropic_claude_with_session.py`](anthropic_claude_with_session.py) | Session management, persistence, and resumption. |
## Environment Variables
### Anthropic Client
- `ANTHROPIC_API_KEY`: Your Anthropic API key (get one from [Anthropic Console](https://console.anthropic.com/))
- `ANTHROPIC_CHAT_MODEL_ID`: The Claude model to use (e.g., `claude-haiku-4-5`, `claude-sonnet-4-5-20250929`)
### Foundry
- `ANTHROPIC_FOUNDRY_API_KEY`: Your Foundry Anthropic API key
- `ANTHROPIC_FOUNDRY_ENDPOINT`: The endpoint URL for your Foundry Anthropic resource
- `ANTHROPIC_CHAT_MODEL_ID`: The Claude model to use in Foundry (e.g., `claude-haiku-4-5`)
### Claude Agent
- `CLAUDE_AGENT_CLI_PATH`: Path to the Claude Code CLI executable
- `CLAUDE_AGENT_MODEL`: Model to use (sonnet, opus, haiku)
- `CLAUDE_AGENT_CWD`: Working directory for Claude CLI
- `CLAUDE_AGENT_PERMISSION_MODE`: Permission mode (default, acceptEdits, plan, bypassPermissions)
- `CLAUDE_AGENT_MAX_TURNS`: Maximum number of conversation turns
- `CLAUDE_AGENT_MAX_BUDGET_USD`: Maximum budget in USD
@@ -0,0 +1,58 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.anthropic import AnthropicChatOptions, AnthropicClient
"""
Anthropic Chat Agent Example
This sample demonstrates using Anthropic with:
- Setting up an Anthropic-based agent with hosted tools.
- Using the `thinking` feature.
- Displaying both thinking and usage information during streaming responses.
"""
async def main() -> None:
"""Example of streaming response (get results as they are generated)."""
client = AnthropicClient[AnthropicChatOptions]()
# Create MCP tool configuration using instance method
mcp_tool = client.get_mcp_tool(
name="Microsoft_Learn_MCP",
url="https://learn.microsoft.com/api/mcp",
)
# Create web search tool configuration using instance method
web_search_tool = client.get_web_search_tool()
agent = client.as_agent(
name="DocsAgent",
instructions="You are a helpful agent for both Microsoft docs questions and general questions.",
tools=[mcp_tool, web_search_tool],
default_options={
# anthropic needs a value for the max_tokens parameter
# we set it to 1024, but you can override like this:
"max_tokens": 20000,
"thinking": {"type": "enabled", "budget_tokens": 10000},
},
)
query = "Can you compare Python decorators with C# attributes?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
for content in chunk.contents:
if content.type == "text_reasoning":
print(f"\033[32m{content.text}\033[0m", end="", flush=True)
if content.type == "usage":
print(f"\n\033[34m[Usage so far: {content.usage_details}]\033[0m\n", end="", flush=True)
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,72 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.anthropic import AnthropicClient
"""
Anthropic Chat Agent Example
This sample demonstrates using Anthropic with an agent and a single custom tool.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, "The location to get the weather for."],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
agent = AnthropicClient(
).as_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
agent = AnthropicClient(
).as_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Portland and in Paris?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Anthropic Example ===")
await streaming_example()
await non_streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,76 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent Basic Example
This sample demonstrates using ClaudeAgent for basic interactions
with Claude Agent SDK.
Prerequisites:
- Claude Code CLI must be installed and configured
- pip install agent-framework-claude
Environment variables:
- CLAUDE_AGENT_MODEL: Model to use (sonnet, opus, haiku)
- CLAUDE_AGENT_PERMISSION_MODE: Permission mode (default, acceptEdits, bypassPermissions)
"""
import asyncio
from typing import Annotated
from agent_framework import tool
from agent_framework_claude import ClaudeAgent
@tool
def get_weather(location: Annotated[str, "The city name"]) -> str:
"""Get the current weather for a location."""
return f"The weather in {location} is sunny with a high of 25C."
async def non_streaming_example() -> None:
"""Example of non-streaming response."""
print("=== Non-streaming Example ===")
agent = ClaudeAgent(
name="BasicAgent",
instructions="You are a helpful assistant. Keep responses concise.",
tools=[get_weather],
)
async with agent:
query = "What's the weather in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}\n")
async def streaming_example() -> None:
"""Example of streaming response."""
print("=== Streaming Example ===")
agent = ClaudeAgent(
name="StreamingAgent",
instructions="You are a helpful assistant.",
tools=[get_weather],
)
async with agent:
query = "What's the weather in Paris?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Claude Agent Basic Example ===\n")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,81 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent with MCP Servers
This sample demonstrates how to configure MCP (Model Context Protocol) servers
with ClaudeAgent. It shows both local (stdio) and remote (HTTP) server
configurations, giving the agent access to external tools and data sources.
Supported MCP server types:
- "stdio": Local process-based server
- "http": Remote HTTP server
- "sse": Remote SSE (Server-Sent Events) server
SECURITY NOTE: MCP servers can expose powerful capabilities. Only configure
servers you trust. Use permission handlers to control what actions are allowed.
"""
import asyncio
from typing import Any
from agent_framework_claude import ClaudeAgent
from claude_agent_sdk import PermissionResultAllow, PermissionResultDeny
async def prompt_permission(
tool_name: str,
tool_input: dict[str, Any],
context: object,
) -> PermissionResultAllow | PermissionResultDeny:
"""Permission handler that prompts the user for approval."""
print(f"\n[Permission Request: {tool_name}]")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionResultAllow()
return PermissionResultDeny(message="Denied by user")
async def main() -> None:
print("=== Claude Agent with MCP Servers ===\n")
# Configure both local and remote MCP servers
mcp_servers: dict[str, Any] = {
# Local stdio server: provides filesystem access tools
"filesystem": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
},
# Remote HTTP server: Microsoft Learn documentation
"microsoft-learn": {
"type": "http",
"url": "https://learn.microsoft.com/api/mcp",
},
}
agent = ClaudeAgent(
instructions="You are a helpful assistant with access to the local filesystem and Microsoft Learn.",
default_options={
"can_use_tool": prompt_permission,
"mcp_servers": mcp_servers,
},
)
async with agent:
# Query that exercises the local filesystem MCP server
query1 = "List the first three files in the current directory"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1.text}\n")
# Query that exercises the remote Microsoft Learn MCP server
query2 = "Search Microsoft Learn for 'Azure Functions Python' and summarize the top result"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent with Multiple Permissions
This sample demonstrates how to enable multiple permission types with ClaudeAgent.
By combining different tools and using a permission handler, the agent can perform
complex tasks that require multiple capabilities.
Available built-in tools:
- "Bash": Execute shell commands
- "Read": Read files from the filesystem
- "Write": Write files to the filesystem
- "Edit": Edit existing files
- "Glob": Search for files by pattern
- "Grep": Search file contents
SECURITY NOTE: Only enable permissions that are necessary for your use case.
More permissions mean more potential for unintended actions.
"""
import asyncio
from typing import Any
from agent_framework_claude import ClaudeAgent
from claude_agent_sdk import PermissionResultAllow, PermissionResultDeny
async def prompt_permission(
tool_name: str,
tool_input: dict[str, Any],
context: object,
) -> PermissionResultAllow | PermissionResultDeny:
"""Permission handler that prompts the user for approval."""
print(f"\n[Permission Request: {tool_name}]")
if "command" in tool_input:
print(f" Command: {tool_input.get('command')}")
if "file_path" in tool_input:
print(f" Path: {tool_input.get('file_path')}")
if "pattern" in tool_input:
print(f" Pattern: {tool_input.get('pattern')}")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionResultAllow()
return PermissionResultDeny(message="Denied by user")
async def main() -> None:
print("=== Claude Agent with Multiple Permissions ===\n")
agent = ClaudeAgent(
instructions="You are a helpful development assistant that can read, write files and run commands.",
tools=["Bash", "Read", "Write", "Glob"],
default_options={
"can_use_tool": prompt_permission,
},
)
async with agent:
query = "List the first 3 Python files, then read the first one and create a summary in summary.txt"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,145 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent with Session Management
This sample demonstrates session management with ClaudeAgent, showing
persistent conversation capabilities. Sessions are automatically persisted
by the Claude Code CLI.
"""
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework_claude import ClaudeAgent
from pydantic import Field
@tool
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_session_creation() -> None:
"""Each agent instance creates a new session."""
print("=== Automatic Session Creation Example ===")
# First agent - first session
agent1 = ClaudeAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent1:
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent1.run(query1)
print(f"Agent: {result1.text}")
# Second agent - new session, no memory of previous conversation
agent2 = ClaudeAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent2:
query2 = "What was the last city I asked about?"
print(f"\nUser: {query2}")
result2 = await agent2.run(query2)
print(f"Agent: {result2.text}")
print("Note: Each agent instance creates a separate session, so the agent doesn't remember previous context.\n")
async def example_with_session_persistence() -> None:
"""Reuse session via thread object for multi-turn conversations."""
print("=== Session Persistence Example ===")
agent = ClaudeAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent:
# Create a thread to maintain conversation context
thread = agent.get_new_thread()
# First query
query1 = "What's the weather like in Tokyo?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# Second query - using same thread maintains context
query2 = "How about London?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2, thread=thread)
print(f"Agent: {result2.text}")
# Third query - agent should remember both previous cities
query3 = "Which of the cities I asked about has better weather?"
print(f"\nUser: {query3}")
result3 = await agent.run(query3, thread=thread)
print(f"Agent: {result3.text}")
print("Note: The agent remembers context from previous messages in the same session.\n")
async def example_with_existing_session_id() -> None:
"""Resume session in new agent instance using service_thread_id."""
print("=== Existing Session ID Example ===")
existing_session_id = None
# First agent instance - start a conversation
agent1 = ClaudeAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent1:
thread = agent1.get_new_thread()
query1 = "What's the weather in Paris?"
print(f"User: {query1}")
result1 = await agent1.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# Capture the session ID for later use
existing_session_id = thread.service_thread_id
print(f"Session ID: {existing_session_id}")
if existing_session_id:
print("\n--- Continuing with the same session ID in a new agent instance ---")
# Second agent instance - resume the conversation
agent2 = ClaudeAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent2:
# Create thread with existing session ID
thread = agent2.get_new_thread(service_thread_id=existing_session_id)
query2 = "What was the last city I asked about?"
print(f"User: {query2}")
result2 = await agent2.run(query2, thread=thread)
print(f"Agent: {result2.text}")
print("Note: The agent continues the conversation using the session ID.\n")
async def main() -> None:
print("=== Claude Agent Session Management Examples ===\n")
await example_with_automatic_session_creation()
await example_with_session_persistence()
await example_with_existing_session_id()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,57 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent with Shell Permissions
This sample demonstrates how to enable shell command execution with ClaudeAgent.
By providing a permission handler via `can_use_tool`, the agent can execute
shell commands to perform tasks like listing files, running scripts, or executing system commands.
SECURITY NOTE: Only enable shell permissions when you trust the agent's actions.
Shell commands have full access to your system within the permissions of the running process.
"""
import asyncio
from typing import Any
from agent_framework_claude import ClaudeAgent
from claude_agent_sdk import PermissionResultAllow, PermissionResultDeny
async def prompt_permission(
tool_name: str,
tool_input: dict[str, Any],
context: object,
) -> PermissionResultAllow | PermissionResultDeny:
"""Permission handler that prompts the user for approval."""
print(f"\n[Permission Request: {tool_name}]")
if "command" in tool_input:
print(f" Command: {tool_input.get('command')}")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionResultAllow()
return PermissionResultDeny(message="Denied by user")
async def main() -> None:
print("=== Claude Agent with Shell Permissions ===\n")
agent = ClaudeAgent(
instructions="You are a helpful assistant that can execute shell commands.",
tools=["Bash"],
default_options={
"can_use_tool": prompt_permission,
},
)
async with agent:
query = "List the first 3 Python files in the current directory"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,40 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent with Built-in Tools
This sample demonstrates using ClaudeAgent with built-in tools for file operations.
Built-in tools are specified as strings in the tools parameter.
Available built-in tools:
- "Bash": Execute shell commands
- "Read": Read files from the filesystem
- "Write": Write files to the filesystem
- "Edit": Edit existing files
- "Glob": Search for files by pattern
- "Grep": Search file contents
"""
import asyncio
from agent_framework_claude import ClaudeAgent
async def main() -> None:
print("=== Claude Agent with Built-in Tools ===\n")
# Built-in tools can be specified as strings in the tools parameter
agent = ClaudeAgent(
instructions="You are a helpful assistant that can read files.",
tools=["Read", "Glob"],
)
async with agent:
query = "List the first 3 Python files in the current directory"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,38 @@
# Copyright (c) Microsoft. All rights reserved.
"""
Claude Agent with URL Fetching
This sample demonstrates how to enable URL fetching with ClaudeAgent.
By enabling the WebFetch tool, the agent can fetch and process content from web URLs.
Available web tools:
- "WebFetch": Fetch content from URLs
- "WebSearch": Search the web
SECURITY NOTE: Only enable URL permissions when you trust the agent's actions.
URL fetching allows the agent to access any URL accessible from your network.
"""
import asyncio
from agent_framework_claude import ClaudeAgent
async def main() -> None:
print("=== Claude Agent with URL Fetching ===\n")
agent = ClaudeAgent(
instructions="You are a helpful assistant that can fetch and summarize web content.",
tools=["WebFetch"],
)
async with agent:
query = "Fetch https://learn.microsoft.com/agent-framework/tutorials/quick-start and summarize its contents"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.anthropic import AnthropicClient
from anthropic import AsyncAnthropicFoundry
"""
Anthropic Foundry Chat Agent Example
This sample demonstrates using Anthropic with:
- Setting up an Anthropic-based agent with hosted tools.
- Using the `thinking` feature.
- Displaying both thinking and usage information during streaming responses.
This example requires `anthropic>=0.74.0` and an endpoint in Foundry for Anthropic.
To use the Foundry integration ensure you have the following environment variables set:
- ANTHROPIC_FOUNDRY_API_KEY
Alternatively you can pass in a azure_ad_token_provider function to the AsyncAnthropicFoundry constructor.
- ANTHROPIC_FOUNDRY_ENDPOINT
Should be something like https://<your-resource-name>.services.ai.azure.com/anthropic/
- ANTHROPIC_CHAT_MODEL_ID
Should be something like claude-haiku-4-5
"""
async def main() -> None:
"""Example of streaming response (get results as they are generated)."""
client = AnthropicClient(anthropic_client=AsyncAnthropicFoundry())
# Create MCP tool configuration using instance method
mcp_tool = client.get_mcp_tool(
name="Microsoft_Learn_MCP",
url="https://learn.microsoft.com/api/mcp",
)
# Create web search tool configuration using instance method
web_search_tool = client.get_web_search_tool()
agent = client.as_agent(
name="DocsAgent",
instructions="You are a helpful agent for both Microsoft docs questions and general questions.",
tools=[mcp_tool, web_search_tool],
default_options={
# anthropic needs a value for the max_tokens parameter
# we set it to 1024, but you can override like this:
"max_tokens": 20000,
"thinking": {"type": "enabled", "budget_tokens": 10000},
},
)
query = "Can you compare Python decorators with C# attributes?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
for content in chunk.contents:
if content.type == "text_reasoning":
print(f"\033[32m{content.text}\033[0m", end="", flush=True)
if content.type == "usage":
print(f"\n\033[34m[Usage so far: {content.usage_details}]\033[0m\n", end="", flush=True)
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,88 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import logging
from pathlib import Path
from agent_framework import Content
from agent_framework.anthropic import AnthropicChatOptions, AnthropicClient
logger = logging.getLogger(__name__)
"""
Anthropic Skills Agent Example
This sample demonstrates using Anthropic with:
- Listing and using Anthropic-managed Skills.
- One approach to add additional beta flags.
You can also set additonal_chat_options with "additional_beta_flags" per request.
- Creating an agent with the Code Interpreter tool and a Skill.
- Catching and downloading generated files from the agent.
"""
async def main() -> None:
"""Example of streaming response (get results as they are generated)."""
client = AnthropicClient[AnthropicChatOptions](additional_beta_flags=["skills-2025-10-02"])
# List Anthropic-managed Skills
skills = await client.anthropic_client.beta.skills.list(source="anthropic", betas=["skills-2025-10-02"])
for skill in skills.data:
print(f"{skill.source}: {skill.id} (version: {skill.latest_version})")
# Create a agent with the pptx skill enabled
# Skills also need the code interpreter tool to function
agent = client.as_agent(
name="DocsAgent",
instructions="You are a helpful agent for creating powerpoint presentations.",
tools=client.get_code_interpreter_tool(),
default_options={
"max_tokens": 20000,
"thinking": {"type": "enabled", "budget_tokens": 10000},
"container": {"skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]},
},
)
print(
"The agent output will use the following colors:\n"
"\033[0mUser: (default)\033[0m\n"
"\033[0mAgent: (default)\033[0m\n"
"\033[32mAgent Reasoning: (green)\033[0m\n"
"\033[34mUsage: (blue)\033[0m\n"
)
query = "Create a presentation about renewable energy with 5 slides"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
files: list[Content] = []
async for chunk in agent.run(query, stream=True):
for content in chunk.contents:
match content.type:
case "text":
print(content.text, end="", flush=True)
case "text_reasoning":
print(f"\033[32m{content.text}\033[0m", end="", flush=True)
case "usage":
print(f"\n\033[34m[Usage so far: {content.usage_details}]\033[0m\n", end="", flush=True)
case "hosted_file":
# Catch generated files
files.append(content)
case _:
logger.debug("Unhandled content type: %s", content.type)
pass
print("\n")
if files:
# Save to a new file (will be in the folder where you are running this script)
# When running this sample multiple times, the files will be overritten
# Since I'm using the pptx skill, the files will be PowerPoint presentations
print("Generated files:")
for idx, file in enumerate(files):
file_content = await client.anthropic_client.beta.files.download(
file_id=file.file_id, betas=["files-api-2025-04-14"]
)
with open(Path(__file__).parent / f"renewable_energy-{idx}.pptx", "wb") as f:
await file_content.write_to_file(f.name)
print(f"File {idx}: renewable_energy-{idx}.pptx saved to disk.")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,95 @@
# Azure AI Agent Examples
This folder contains examples demonstrating different ways to create and use agents with the Azure AI client from the `agent_framework.azure` package. These examples use the `AzureAIClient` with the `azure-ai-projects` 2.x (V2) API surface (see [changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/CHANGELOG.md#200b1-2025-11-11)). For V1 (`azure-ai-agents` 1.x) samples using `AzureAIAgentClient`, see the [Azure AI V1 examples folder](../azure_ai_agent/).
## Examples
| File | Description |
|------|-------------|
| [`azure_ai_basic.py`](azure_ai_basic.py) | The simplest way to create an agent using `AzureAIProjectAgentProvider`. Demonstrates both streaming and non-streaming responses with function tools. Shows automatic agent creation and basic weather functionality. |
| [`azure_ai_provider_methods.py`](azure_ai_provider_methods.py) | Comprehensive guide to `AzureAIProjectAgentProvider` methods: `create_agent()` for creating new agents, `get_agent()` for retrieving existing agents (by name, reference, or details), and `as_agent()` for wrapping SDK objects without HTTP calls. |
| [`azure_ai_use_latest_version.py`](azure_ai_use_latest_version.py) | Demonstrates how to reuse the latest version of an existing agent instead of creating a new agent version on each instantiation by using `provider.get_agent()` to retrieve the latest version. |
| [`azure_ai_with_agent_as_tool.py`](azure_ai_with_agent_as_tool.py) | Shows how to use the agent-as-tool pattern with Azure AI agents, where one agent delegates work to specialized sub-agents wrapped as tools using `as_tool()`. Demonstrates hierarchical agent architectures. |
| [`azure_ai_with_agent_to_agent.py`](azure_ai_with_agent_to_agent.py) | Shows how to use Agent-to-Agent (A2A) capabilities with Azure AI agents to enable communication with other agents using the A2A protocol. Requires an A2A connection configured in your Azure AI project. |
| [`azure_ai_with_azure_ai_search.py`](azure_ai_with_azure_ai_search.py) | Shows how to use Azure AI Search with Azure AI agents to search through indexed data and answer user questions with proper citations. Requires an Azure AI Search connection and index configured in your Azure AI project. |
| [`azure_ai_with_bing_grounding.py`](azure_ai_with_bing_grounding.py) | Shows how to use Bing Grounding search with Azure AI agents to search the web for current information and provide grounded responses with citations. Requires a Bing connection configured in your Azure AI project. |
| [`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 search custom search instances and provide responses with relevant results. Requires a Bing Custom Search connection and instance configured in your Azure AI project. |
| [`azure_ai_with_browser_automation.py`](azure_ai_with_browser_automation.py) | Shows how to use Browser Automation with Azure AI agents to perform automated web browsing tasks and provide responses based on web interactions. Requires a Browser Automation connection configured in your Azure AI project. |
| [`azure_ai_with_code_interpreter.py`](azure_ai_with_code_interpreter.py) | Shows how to use `AzureAIClient.get_code_interpreter_tool()` with Azure AI agents to write and execute Python code for mathematical problem solving and data analysis. |
| [`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_file_download.py`](azure_ai_with_code_interpreter_file_download.py) | Shows how to download files generated by code interpreter using the OpenAI containers API. |
| [`azure_ai_with_content_filtering.py`](azure_ai_with_content_filtering.py) | Shows how to enable content filtering (RAI policy) on Azure AI agents using `RaiConfig`. Requires creating an RAI policy in Azure AI Foundry portal first. |
| [`azure_ai_with_existing_agent.py`](azure_ai_with_existing_agent.py) | Shows how to work with a pre-existing agent by providing the agent name and version to the Azure AI client. Demonstrates agent reuse patterns for production scenarios. |
| [`azure_ai_with_existing_conversation.py`](azure_ai_with_existing_conversation.py) | Demonstrates how to use an existing conversation created on the service side with Azure AI agents. Shows two approaches: specifying conversation ID at the client level and using AgentThread with an existing conversation ID. |
| [`azure_ai_with_application_endpoint.py`](azure_ai_with_application_endpoint.py) | Demonstrates calling the Azure AI application-scoped endpoint. |
| [`azure_ai_with_explicit_settings.py`](azure_ai_with_explicit_settings.py) | Shows how to create an agent with explicitly configured `AzureAIClient` settings, including project endpoint, model deployment, and credentials rather than relying on environment variable defaults. |
| [`azure_ai_with_file_search.py`](azure_ai_with_file_search.py) | Shows how to use `AzureAIClient.get_file_search_tool()` with Azure AI agents to upload files, create vector stores, and enable agents to search through uploaded documents to answer user questions. |
| [`azure_ai_with_hosted_mcp.py`](azure_ai_with_hosted_mcp.py) | Shows how to integrate hosted Model Context Protocol (MCP) tools with Azure AI Agent using `AzureAIClient.get_mcp_tool()`. |
| [`azure_ai_with_local_mcp.py`](azure_ai_with_local_mcp.py) | Shows how to integrate local Model Context Protocol (MCP) tools with Azure AI agents. |
| [`azure_ai_with_response_format.py`](azure_ai_with_response_format.py) | Shows how to use structured outputs (response format) with Azure AI agents using Pydantic models to enforce specific response schemas. |
| [`azure_ai_with_runtime_json_schema.py`](azure_ai_with_runtime_json_schema.py) | Shows how to use structured outputs (response format) with Azure AI agents using a JSON schema to enforce specific response schemas. |
| [`azure_ai_with_search_context_agentic.py`](../../context_providers/azure_ai_search/azure_ai_with_search_context_agentic.py) | Shows how to use AzureAISearchContextProvider with agentic mode. Uses Knowledge Bases for multi-hop reasoning across documents with query planning. Recommended for most scenarios - slightly slower with more token consumption for query planning, but more accurate results. |
| [`azure_ai_with_search_context_semantic.py`](../../context_providers/azure_ai_search/azure_ai_with_search_context_semantic.py) | Shows how to use AzureAISearchContextProvider with semantic mode. Fast hybrid search with vector + keyword search and semantic ranking for RAG. Best for simple queries where speed is critical. |
| [`azure_ai_with_sharepoint.py`](azure_ai_with_sharepoint.py) | Shows how to use SharePoint grounding with Azure AI agents to search through SharePoint content and answer user questions with proper citations. Requires a SharePoint connection configured in your Azure AI project. |
| [`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. |
| [`azure_ai_with_image_generation.py`](azure_ai_with_image_generation.py) | Shows how to use `AzureAIClient.get_image_generation_tool()` with Azure AI agents to generate images based on text prompts. |
| [`azure_ai_with_memory_search.py`](azure_ai_with_memory_search.py) | Shows how to use memory search functionality with Azure AI agents for conversation persistence. Demonstrates creating memory stores and enabling agents to search through conversation history. |
| [`azure_ai_with_microsoft_fabric.py`](azure_ai_with_microsoft_fabric.py) | Shows how to use Microsoft Fabric with Azure AI agents to query Fabric data sources and provide responses based on data analysis. Requires a Microsoft Fabric connection configured in your Azure AI project. |
| [`azure_ai_with_openapi.py`](azure_ai_with_openapi.py) | Shows how to integrate OpenAPI specifications with Azure AI agents using dictionary-based tool configuration. Demonstrates using external REST APIs for dynamic data lookup. |
| [`azure_ai_with_reasoning.py`](azure_ai_with_reasoning.py) | Shows how to enable reasoning for a model that supports it. |
| [`azure_ai_with_web_search.py`](azure_ai_with_web_search.py) | Shows how to use `AzureAIClient.get_web_search_tool()` with Azure AI agents to perform web searches and retrieve up-to-date information from the internet. |
## Environment Variables
Before running the examples, you need to set up your environment variables. You can do this in one of two ways:
### Option 1: Using a .env file (Recommended)
1. Copy the `.env.example` file from the `python` directory to create a `.env` file:
```bash
cp ../../../../.env.example ../../../../.env
```
2. Edit the `.env` file and add your values:
```env
AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
```
### Option 2: Using environment variables directly
Set the environment variables in your shell:
```bash
export AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
```
### Required Variables
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI project endpoint (required for all examples)
- `AZURE_AI_MODEL_DEPLOYMENT_NAME`: The name of your model deployment (required for all examples)
## Authentication
All examples use `AzureCliCredential` for authentication by default. Before running the examples:
1. Install the Azure CLI
2. Run `az login` to authenticate with your Azure account
3. Ensure you have appropriate permissions to the Azure AI project
Alternatively, you can replace `AzureCliCredential` with other authentication options like `DefaultAzureCredential` or environment-based credentials.
## Running the Examples
Each example can be run independently. Navigate to this directory and run any example:
```bash
python azure_ai_basic.py
python azure_ai_with_code_interpreter.py
# ... etc
```
The examples demonstrate various patterns for working with Azure AI agents, from basic usage to advanced scenarios like thread management and structured outputs.
@@ -0,0 +1,87 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent Basic Example
This sample demonstrates basic usage of AzureAIProjectAgentProvider.
Shows both streaming and non-streaming responses with function tools.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="BasicWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="BasicWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Tokyo?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Basic Azure AI Chat Client Agent Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,254 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import AgentReference, PromptAgentDefinition
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Project Agent Provider Methods Example
This sample demonstrates the three main methods of AzureAIProjectAgentProvider:
1. create_agent() - Create a new agent on the Azure AI service
2. get_agent() - Retrieve an existing agent from the service
3. as_agent() - Wrap an SDK agent version object without making HTTP calls
It also shows how to use a single provider instance to spawn multiple agents
with different configurations, which is efficient for multi-agent scenarios.
Each method returns a Agent that can be used for conversations.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}C."
async def create_agent_example() -> None:
"""Example of using provider.create_agent() to create a new agent.
This method creates a new agent version on the Azure AI service and returns
a Agent. Use this when you want to create a fresh agent with
specific configuration.
"""
print("=== provider.create_agent() Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a new agent with custom configuration
agent = await provider.create_agent(
name="WeatherAssistant",
instructions="You are a helpful weather assistant. Always be concise.",
description="An agent that provides weather information.",
tools=get_weather,
)
print(f"Created agent: {agent.name}")
print(f"Agent ID: {agent.id}")
query = "What's the weather in Paris?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
async def get_agent_by_name_example() -> None:
"""Example of using provider.get_agent(name=...) to retrieve an agent by name.
This method fetches the latest version of an existing agent from the service.
Use this when you know the agent name and want to use the most recent version.
"""
print("=== provider.get_agent(name=...) Example ===")
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
):
# First, create an agent using the SDK directly
created_agent = await project_client.agents.create_version(
agent_name="TestAgentByName",
description="Test agent for get_agent by name example.",
definition=PromptAgentDefinition(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
instructions="You are a helpful assistant. End each response with '- Your Assistant'.",
),
)
try:
# Get the agent using the provider by name (fetches latest version)
provider = AzureAIProjectAgentProvider(project_client=project_client)
agent = await provider.get_agent(name=created_agent.name)
print(f"Retrieved agent: {agent.name}")
query = "Hello!"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
finally:
# Clean up the agent
await project_client.agents.delete_version(
agent_name=created_agent.name, agent_version=created_agent.version
)
async def get_agent_by_reference_example() -> None:
"""Example of using provider.get_agent(reference=...) to retrieve a specific agent version.
This method fetches a specific version of an agent using an AgentReference.
Use this when you need to use a particular version of an agent.
"""
print("=== provider.get_agent(reference=...) Example ===")
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
):
# First, create an agent using the SDK directly
created_agent = await project_client.agents.create_version(
agent_name="TestAgentByReference",
description="Test agent for get_agent by reference example.",
definition=PromptAgentDefinition(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
instructions="You are a helpful assistant. Always respond in uppercase.",
),
)
try:
# Get the agent using an AgentReference with specific version
provider = AzureAIProjectAgentProvider(project_client=project_client)
reference = AgentReference(name=created_agent.name, version=created_agent.version)
agent = await provider.get_agent(reference=reference)
print(f"Retrieved agent: {agent.name} (version via reference)")
query = "Say hello"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
finally:
# Clean up the agent
await project_client.agents.delete_version(
agent_name=created_agent.name, agent_version=created_agent.version
)
async def multiple_agents_example() -> None:
"""Example of using a single provider to spawn multiple agents.
A single provider instance can create multiple agents with different
configurations.
"""
print("=== Multiple Agents from Single Provider Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create multiple specialized agents from the same provider
weather_agent = await provider.create_agent(
name="WeatherExpert",
instructions="You are a weather expert. Provide brief weather information.",
tools=get_weather,
)
translator_agent = await provider.create_agent(
name="Translator",
instructions="You are a translator. Translate any text to French. Only output the translation.",
)
poet_agent = await provider.create_agent(
name="Poet",
instructions="You are a poet. Respond to everything with a short haiku.",
)
print(f"Created agents: {weather_agent.name}, {translator_agent.name}, {poet_agent.name}\n")
# Use each agent for its specialty
weather_query = "What's the weather in London?"
print(f"User to WeatherExpert: {weather_query}")
weather_result = await weather_agent.run(weather_query)
print(f"WeatherExpert: {weather_result}\n")
translate_query = "Hello, how are you today?"
print(f"User to Translator: {translate_query}")
translate_result = await translator_agent.run(translate_query)
print(f"Translator: {translate_result}\n")
poet_query = "Tell me about the morning sun"
print(f"User to Poet: {poet_query}")
poet_result = await poet_agent.run(poet_query)
print(f"Poet: {poet_result}\n")
async def as_agent_example() -> None:
"""Example of using provider.as_agent() to wrap an SDK object without HTTP calls.
This method wraps an existing AgentVersionDetails into a Agent without
making additional HTTP calls. Use this when you already have the full
AgentVersionDetails from a previous SDK operation.
"""
print("=== provider.as_agent() Example ===")
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
):
# Create an agent using the SDK directly - this returns AgentVersionDetails
agent_version_details = await project_client.agents.create_version(
agent_name="TestAgentAsAgent",
description="Test agent for as_agent example.",
definition=PromptAgentDefinition(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
instructions="You are a helpful assistant. Keep responses under 20 words.",
),
)
try:
# Wrap the SDK object directly without any HTTP calls
provider = AzureAIProjectAgentProvider(project_client=project_client)
agent = provider.as_agent(agent_version_details)
print(f"Wrapped agent: {agent.name} (no HTTP call needed)")
print(f"Agent version: {agent_version_details.version}")
query = "What can you do?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
finally:
# Clean up the agent
await project_client.agents.delete_version(
agent_name=agent_version_details.name, agent_version=agent_version_details.version
)
async def main() -> None:
print("=== Azure AI Project Agent Provider Methods Example ===\n")
await create_agent_example()
await get_agent_by_name_example()
await get_agent_by_reference_example()
await as_agent_example()
await multiple_agents_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent Latest Version Example
This sample demonstrates how to reuse the latest version of an existing agent
instead of creating a new agent version on each instantiation. The first call creates a new agent,
while subsequent calls with `get_agent()` reuse the latest agent version.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# First call creates a new agent
agent = await provider.create_agent(
name="MyWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
# Second call retrieves the existing agent (latest version) instead of creating a new one
# This is useful when you want to reuse an agent that was created earlier
agent2 = await provider.get_agent(
name="MyWeatherAgent",
tools=get_weather, # Tools must be provided for function tools
)
query = "What's the weather like in Tokyo?"
print(f"User: {query}")
result = await agent2.run(query)
print(f"Agent: {result}\n")
print(f"First agent ID with version: {agent.id}")
print(f"Second agent ID with version: {agent2.id}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,70 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from collections.abc import Awaitable, Callable
from agent_framework import FunctionInvocationContext
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent-as-Tool Example
Demonstrates hierarchical agent architectures where one agent delegates
work to specialized sub-agents wrapped as tools using as_tool().
This pattern is useful when you want a coordinator agent to orchestrate
multiple specialized agents, each focusing on specific tasks.
"""
async def logging_middleware(
context: FunctionInvocationContext,
call_next: Callable[[], Awaitable[None]],
) -> None:
"""MiddlewareTypes that logs tool invocations to show the delegation flow."""
print(f"[Calling tool: {context.function.name}]")
print(f"[Request: {context.arguments}]")
await call_next()
print(f"[Response: {context.result}]")
async def main() -> None:
print("=== Azure AI Agent-as-Tool Pattern ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a specialized writer agent
writer = await provider.create_agent(
name="WriterAgent",
instructions="You are a creative writer. Write short, engaging content.",
)
# Convert writer agent to a tool using as_tool()
writer_tool = writer.as_tool(
name="creative_writer",
description="Generate creative content like taglines, slogans, or short copy",
arg_name="request",
arg_description="What to write",
)
# Create coordinator agent with writer as a tool
coordinator = await provider.create_agent(
name="CoordinatorAgent",
instructions="You coordinate with specialized agents. Delegate writing tasks to the creative_writer tool.",
tools=[writer_tool],
middleware=[logging_middleware],
)
query = "Create a tagline for a coffee shop"
print(f"User: {query}")
result = await coordinator.run(query)
print(f"Coordinator: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,53 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Agent-to-Agent (A2A) Example
This sample demonstrates usage of AzureAIProjectAgentProvider with Agent-to-Agent (A2A) capabilities
to enable communication with other agents using the A2A protocol.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have an A2A connection configured in your Azure AI project
and set A2A_PROJECT_CONNECTION_ID environment variable.
3. (Optional) A2A_ENDPOINT - If the connection is missing target (e.g., "Custom keys" type),
set the A2A endpoint URL directly.
"""
async def main() -> None:
# Configure A2A tool with connection ID
a2a_tool = {
"type": "a2a_preview",
"project_connection_id": os.environ["A2A_PROJECT_CONNECTION_ID"],
}
# If the connection is missing a target, we need to set the A2A endpoint URL
if os.environ.get("A2A_ENDPOINT"):
a2a_tool["base_url"] = os.environ["A2A_ENDPOINT"]
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyA2AAgent",
instructions="""You are a helpful assistant that can communicate with other agents.
Use the A2A tool when you need to interact with other agents to complete tasks
or gather information from specialized agents.""",
tools=a2a_tool,
)
query = "What can the secondary agent do?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,39 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework import Agent
from agent_framework.azure import AzureAIClient
from azure.ai.projects.aio import AIProjectClient
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Application Endpoint Example
This sample demonstrates working with pre-existing Azure AI Agents by providing
application endpoint instead of project endpoint.
"""
async def main() -> None:
# Create the client
async with (
AzureCliCredential() as credential,
# Endpoint here should be application endpoint with format:
# /api/projects/<project-name>/applications/<application-name>/protocols
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
Agent(
client=AzureAIClient(
project_client=project_client,
),
) as agent,
):
query = "How are you?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,52 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Azure AI Search Example
This sample demonstrates usage of AzureAIProjectAgentProvider with Azure AI Search
to search through indexed data and answer user questions about it.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have an Azure AI Search connection configured in your Azure AI project
and set AI_SEARCH_PROJECT_CONNECTION_ID and AI_SEARCH_INDEX_NAME environment variable.
"""
async def main() -> None:
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MySearchAgent",
instructions="""You are a helpful assistant. You must always provide citations for
answers using the tool and render them as: `[message_idx:search_idx†source]`.""",
tools={
"type": "azure_ai_search",
"azure_ai_search": {
"indexes": [
{
"project_connection_id": os.environ["AI_SEARCH_PROJECT_CONNECTION_ID"],
"index_name": os.environ["AI_SEARCH_INDEX_NAME"],
# For query_type=vector, ensure your index has a field with vectorized data.
"query_type": "simple",
}
]
},
},
)
query = "Tell me about insurance options"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,50 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Bing Custom Search Example
This sample demonstrates usage of AzureAIProjectAgentProvider with Bing Custom Search
to search custom search instances and provide responses with relevant results.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have a Bing Custom Search connection configured in your Azure AI project
and set BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID and BING_CUSTOM_SEARCH_INSTANCE_NAME environment variables.
"""
async def main() -> None:
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyCustomSearchAgent",
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={
"type": "bing_custom_search_preview",
"bing_custom_search_preview": {
"search_configurations": [
{
"project_connection_id": os.environ["BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID"],
"instance_name": os.environ["BING_CUSTOM_SEARCH_INSTANCE_NAME"],
}
]
},
},
)
query = "Tell me more about foundry agent service"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,56 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Bing Grounding Example
This sample demonstrates usage of AzureAIProjectAgentProvider with Bing Grounding
to search the web for current information and provide grounded responses.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have a Bing connection configured in your Azure AI project
and set BING_PROJECT_CONNECTION_ID environment variable.
To get your Bing connection ID:
- Go to Azure AI Foundry portal (https://ai.azure.com)
- Navigate to your project's "Connected resources" section
- Add a new connection for "Grounding with Bing Search"
- Copy the connection ID and set it as the BING_PROJECT_CONNECTION_ID environment variable
"""
async def main() -> None:
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyBingGroundingAgent",
instructions="""You are a helpful assistant that can search the web for current information.
Use the Bing search tool to find up-to-date information and provide accurate, well-sourced answers.
Always cite your sources when possible.""",
tools={
"type": "bing_grounding",
"bing_grounding": {
"search_configurations": [
{
"project_connection_id": os.environ["BING_PROJECT_CONNECTION_ID"],
}
]
},
},
)
query = "What is today's date and weather in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,54 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Browser Automation Example
This sample demonstrates usage of AzureAIProjectAgentProvider with Browser Automation
to perform automated web browsing tasks and provide responses based on web interactions.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have a Browser Automation connection configured in your Azure AI project
and set BROWSER_AUTOMATION_PROJECT_CONNECTION_ID environment variable.
"""
async def main() -> None:
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyBrowserAutomationAgent",
instructions="""You are an Agent helping with browser automation tasks.
You can answer questions, provide information, and assist with various tasks
related to web browsing using the Browser Automation tool available to you.""",
tools={
"type": "browser_automation_preview",
"browser_automation_preview": {
"connection": {
"project_connection_id": os.environ["BROWSER_AUTOMATION_PROJECT_CONNECTION_ID"],
}
},
},
)
query = """Your goal is to report the percent of Microsoft year-to-date stock price change.
To do that, go to the website finance.yahoo.com.
At the top of the page, you will find a search bar.
Enter the value 'MSFT', to get information about the Microsoft stock price.
At the top of the resulting page you will see a default chart of Microsoft stock price.
Click on 'YTD' at the top of that chart, and report the percent value that shows up just below it."""
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,62 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import ChatResponse
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
from openai.types.responses.response import Response as OpenAIResponse
from openai.types.responses.response_code_interpreter_tool_call import ResponseCodeInterpreterToolCall
"""
Azure AI Agent Code Interpreter Example
This sample demonstrates using get_code_interpreter_tool() with AzureAIProjectAgentProvider
for Python code execution and mathematical problem solving.
"""
async def main() -> None:
"""Example showing how to use the code interpreter tool with AzureAIProjectAgentProvider."""
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="MyCodeInterpreterAgent",
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
tools=[code_interpreter_tool],
)
query = "Use code to get the factorial of 100?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if (
isinstance(result.raw_representation, ChatResponse)
and isinstance(result.raw_representation.raw_representation, OpenAIResponse)
and len(result.raw_representation.raw_representation.output) > 0
):
# Find the first ResponseCodeInterpreterToolCall item
code_interpreter_item = next(
(
item
for item in result.raw_representation.raw_representation.output
if isinstance(item, ResponseCodeInterpreterToolCall)
),
None,
)
if code_interpreter_item is not None:
generated_code = code_interpreter_item.code
print(f"Generated code:\n{generated_code}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,232 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import tempfile
from pathlib import Path
from agent_framework import (
Agent,
AgentResponseUpdate,
Annotation,
Content,
)
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI V2 Code Interpreter File Download Sample
This sample demonstrates how the AzureAIProjectAgentProvider handles file annotations
when code interpreter generates text files. It shows:
1. How to extract file IDs and container IDs from annotations
2. How to download container files using the OpenAI containers API
3. How to save downloaded files locally
Note: Code interpreter generates files in containers, which require both
file_id and container_id to download via client.containers.files.content.retrieve().
"""
QUERY = (
"Write a simple Python script that creates a text file called 'sample.txt' containing "
"'Hello from the code interpreter!' and save it to disk."
)
async def download_container_files(file_contents: list[Annotation | Content], agent: Agent) -> list[Path]:
"""Download container files using the OpenAI containers API.
Code interpreter generates files in containers, which require both file_id
and container_id to download. The container_id is stored in additional_properties.
This function works for both streaming (Content with type="hosted_file") and non-streaming
(Annotation) responses.
Args:
file_contents: List of Annotation or Content objects
containing file_id and container_id.
agent: The Agent instance with access to the AzureAIClient.
Returns:
List of Path objects for successfully downloaded files.
"""
if not file_contents:
return []
# Create output directory in system temp folder
temp_dir = Path(tempfile.gettempdir())
output_dir = temp_dir / "agent_framework_downloads"
output_dir.mkdir(exist_ok=True)
print(f"\nDownloading {len(file_contents)} container file(s) to {output_dir.absolute()}...")
# Access the OpenAI client from AzureAIClient
openai_client = agent.client.client # type: ignore[attr-defined]
downloaded_files: list[Path] = []
for content in file_contents:
# Handle both Annotation (TypedDict) and Content objects
if isinstance(content, dict): # Annotation TypedDict
file_id = content.get("file_id")
additional_props = content.get("additional_properties", {})
url = content.get("url")
else: # Content object
file_id = content.file_id
additional_props = content.additional_properties or {}
url = content.uri
# Extract container_id from additional_properties
if not additional_props or "container_id" not in additional_props:
print(f" File {file_id}: ✗ Missing container_id")
continue
container_id = additional_props["container_id"]
# Extract filename based on content type
if isinstance(content, dict): # Annotation TypedDict
filename = url or f"{file_id}.txt"
# Extract filename from sandbox URL if present (e.g., sandbox:/mnt/data/sample.txt)
if filename.startswith("sandbox:"):
filename = filename.split("/")[-1]
else: # Content
filename = additional_props.get("filename") or f"{file_id}.txt"
output_path = output_dir / filename
try:
# Download using containers API
print(f" Downloading {filename}...", end="", flush=True)
file_content = await openai_client.containers.files.content.retrieve(
file_id=file_id,
container_id=container_id,
)
# file_content is HttpxBinaryResponseContent, read it
content_bytes = file_content.read()
# Save to disk
output_path.write_bytes(content_bytes)
file_size = output_path.stat().st_size
print(f"({file_size} bytes)")
downloaded_files.append(output_path)
except Exception as e:
print(f"Failed: {e}")
return downloaded_files
async def non_streaming_example() -> None:
"""Example of downloading files from non-streaming response using Annotation."""
print("=== Non-Streaming Response Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="V2CodeInterpreterFileAgent",
instructions="You are a helpful assistant that can write and execute Python code to create files.",
tools=[code_interpreter_tool],
)
print(f"User: {QUERY}\n")
result = await agent.run(QUERY)
print(f"Agent: {result.text}\n")
# Check for annotations in the response
annotations_found: list[Annotation] = []
# AgentResponse has messages property, which contains Message objects
for message in result.messages:
for content in message.contents:
if content.type == "text" and content.annotations:
for annotation in content.annotations:
if annotation.get("file_id"):
annotations_found.append(annotation)
print(f"Found file annotation: file_id={annotation['file_id']}")
additional_props = annotation.get("additional_properties", {})
if additional_props and "container_id" in additional_props:
print(f" container_id={additional_props['container_id']}")
if annotations_found:
print(f"SUCCESS: Found {len(annotations_found)} file annotation(s)")
# Download the container files (cast to Sequence for type compatibility)
downloaded_paths = await download_container_files(list(annotations_found), agent)
if downloaded_paths:
print("\nDownloaded files available at:")
for path in downloaded_paths:
print(f" - {path.absolute()}")
else:
print("WARNING: No file annotations found in non-streaming response")
async def streaming_example() -> None:
"""Example of downloading files from streaming response using Content with type='hosted_file'."""
print("\n=== Streaming Response Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="V2CodeInterpreterFileAgentStreaming",
instructions="You are a helpful assistant that can write and execute Python code to create files.",
tools=[code_interpreter_tool],
)
print(f"User: {QUERY}\n")
file_contents_found: list[Content] = []
text_chunks: list[str] = []
async for update in agent.run(QUERY, stream=True):
if isinstance(update, AgentResponseUpdate):
for content in update.contents:
if content.type == "text":
if content.text:
text_chunks.append(content.text)
if content.annotations:
for annotation in content.annotations:
if annotation.get("file_id"):
print(f"Found streaming annotation: file_id={annotation['file_id']}")
elif content.type == "hosted_file":
file_contents_found.append(content)
print(f"Found streaming hosted_file: file_id={content.file_id}")
if content.additional_properties and "container_id" in content.additional_properties:
print(f" container_id={content.additional_properties['container_id']}")
print(f"\nAgent response: {''.join(text_chunks)[:200]}...")
if file_contents_found:
print(f"SUCCESS: Found {len(file_contents_found)} file reference(s) in streaming")
# Download the container files
downloaded_paths = await download_container_files(file_contents_found, agent)
if downloaded_paths:
print("\n✓ Downloaded files available at:")
for path in downloaded_paths:
print(f" - {path.absolute()}")
else:
print("WARNING: No file annotations found in streaming response")
async def main() -> None:
print("AzureAIClient Code Interpreter File Download Sample\n")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,119 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import (
AgentResponseUpdate,
)
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI V2 Code Interpreter File Generation Sample
This sample demonstrates how the AzureAIProjectAgentProvider handles file annotations
when code interpreter generates text files. It shows both non-streaming
and streaming approaches to verify file ID extraction.
"""
QUERY = (
"Write a simple Python script that creates a text file called 'sample.txt' containing "
"'Hello from the code interpreter!' and save it to disk."
)
async def non_streaming_example() -> None:
"""Example of extracting file annotations from non-streaming response."""
print("=== Non-Streaming Response Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="CodeInterpreterFileAgent",
instructions="You are a helpful assistant that can write and execute Python code to create files.",
tools=[code_interpreter_tool],
)
print(f"User: {QUERY}\n")
result = await agent.run(QUERY)
print(f"Agent: {result.text}\n")
# Check for annotations in the response
annotations_found: list[str] = []
# AgentResponse has messages property, which contains Message objects
for message in result.messages:
for content in message.contents:
if content.type == "text" and content.annotations:
for annotation in content.annotations:
if annotation.get("file_id"):
annotations_found.append(annotation["file_id"])
print(f"Found file annotation: file_id={annotation['file_id']}")
if annotations_found:
print(f"SUCCESS: Found {len(annotations_found)} file annotation(s)")
else:
print("WARNING: No file annotations found in non-streaming response")
async def streaming_example() -> None:
"""Example of extracting file annotations from streaming response."""
print("\n=== Streaming Response Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
code_interpreter_tool = client.get_code_interpreter_tool()
agent = await provider.create_agent(
name="V2CodeInterpreterFileAgentStreaming",
instructions="You are a helpful assistant that can write and execute Python code to create files.",
tools=[code_interpreter_tool],
)
print(f"User: {QUERY}\n")
annotations_found: list[str] = []
text_chunks: list[str] = []
file_ids_found: list[str] = []
async for update in agent.run(QUERY, stream=True):
if isinstance(update, AgentResponseUpdate):
for content in update.contents:
if content.type == "text":
if content.text:
text_chunks.append(content.text)
if content.annotations:
for annotation in content.annotations:
if annotation.get("file_id"):
annotations_found.append(annotation["file_id"])
print(f"Found streaming annotation: file_id={annotation['file_id']}")
elif content.type == "hosted_file":
file_ids_found.append(content.file_id)
print(f"Found streaming HostedFileContent: file_id={content.file_id}")
print(f"\nAgent response: {''.join(text_chunks)[:200]}...")
if annotations_found or file_ids_found:
total = len(annotations_found) + len(file_ids_found)
print(f"SUCCESS: Found {total} file reference(s) in streaming")
else:
print("WARNING: No file annotations found in streaming response")
async def main() -> None:
print("AzureAIClient Code Interpreter File Generation Sample\n")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,66 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.ai.projects.models import RaiConfig
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Content Filtering (RAI Policy) Example
This sample demonstrates how to enable content filtering on Azure AI agents using RaiConfig.
Prerequisites:
1. Create an RAI Policy in Azure AI Foundry portal:
- Go to Azure AI Foundry > Your Project > Guardrails + Controls > Content Filters
- Create a new content filter or use an existing one
- Note the policy name
2. Set environment variables:
- AZURE_AI_PROJECT_ENDPOINT: Your Azure AI Foundry project endpoint
- AZURE_AI_MODEL_DEPLOYMENT_NAME: Your model deployment name
3. Run `az login` to authenticate
"""
async def main() -> None:
print("=== Azure AI Agent with Content Filtering ===\n")
# Replace with your RAI policy from Azure AI Foundry portal
rai_policy_name = (
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/"
"Microsoft.CognitiveServices/accounts/{accountName}/raiPolicies/{policyName}"
)
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create agent with content filtering enabled via default_options
agent = await provider.create_agent(
name="ContentFilteredAgent",
instructions="You are a helpful assistant.",
default_options={"rai_config": RaiConfig(rai_policy_name=rai_policy_name)},
)
# Test with a normal query
query = "What is the capital of France?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
# Test with a query that might trigger content filtering
# (depending on your RAI policy configuration)
query2 = "Tell me something inappropriate."
print(f"User: {query2}")
try:
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
except Exception as e:
print(f"Content filter triggered: {e}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,66 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Existing Agent Example
This sample demonstrates working with pre-existing Azure AI Agents by using provider.get_agent() method,
showing agent reuse patterns for production scenarios.
"""
async def using_provider_get_agent() -> None:
print("=== Get existing Azure AI agent with provider.get_agent() ===")
# Create the client
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
):
# Create remote agent using SDK directly
azure_ai_agent = await project_client.agents.create_version(
agent_name="MyNewTestAgent",
description="Agent for testing purposes.",
definition=PromptAgentDefinition(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
# Setting specific requirements to verify that this agent is used.
instructions="End each response with [END].",
),
)
try:
# Get newly created agent as Agent by using provider.get_agent()
provider = AzureAIProjectAgentProvider(project_client=project_client)
agent = await provider.get_agent(name=azure_ai_agent.name)
# Verify agent properties
print(f"Agent ID: {agent.id}")
print(f"Agent name: {agent.name}")
print(f"Agent description: {agent.description}")
query = "How are you?"
print(f"User: {query}")
result = await agent.run(query)
# Response that indicates that previously created agent was used:
# "I'm here and ready to help you! How can I assist you today? [END]"
print(f"Agent: {result}\n")
finally:
# Clean up the agent manually
await project_client.agents.delete_version(
agent_name=azure_ai_agent.name, agent_version=azure_ai_agent.version
)
async def main() -> None:
await using_provider_get_agent()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,104 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.ai.projects.aio import AIProjectClient
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent Existing Conversation Example
This sample demonstrates usage of AzureAIProjectAgentProvider with existing conversation created on service side.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_conversation_id() -> None:
"""Example shows how to use existing conversation ID with the provider."""
print("=== Azure AI Agent With Existing Conversation ===")
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
):
# Create a conversation using OpenAI client
openai_client = project_client.get_openai_client()
conversation = await openai_client.conversations.create()
conversation_id = conversation.id
print(f"Conversation ID: {conversation_id}")
provider = AzureAIProjectAgentProvider(project_client=project_client)
agent = await provider.create_agent(
name="BasicAgent",
instructions="You are a helpful agent.",
tools=get_weather,
)
# Pass conversation_id at run level
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query, conversation_id=conversation_id)
print(f"Agent: {result.text}\n")
query = "What was my last question?"
print(f"User: {query}")
result = await agent.run(query, conversation_id=conversation_id)
print(f"Agent: {result.text}\n")
async def example_with_thread() -> None:
"""This example shows how to specify existing conversation ID with AgentThread."""
print("=== Azure AI Agent With Existing Conversation and Thread ===")
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
):
provider = AzureAIProjectAgentProvider(project_client=project_client)
agent = await provider.create_agent(
name="BasicAgent",
instructions="You are a helpful agent.",
tools=get_weather,
)
# Create a conversation using OpenAI client
openai_client = project_client.get_openai_client()
conversation = await openai_client.conversations.create()
conversation_id = conversation.id
print(f"Conversation ID: {conversation_id}")
# Create a thread with the existing ID
thread = agent.get_new_thread(service_thread_id=conversation_id)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query, thread=thread)
print(f"Agent: {result.text}\n")
query = "What was my last question?"
print(f"User: {query}")
result = await agent.run(query, thread=thread)
print(f"Agent: {result.text}\n")
async def main() -> None:
await example_with_conversation_id()
await example_with_thread()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,57 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent with Explicit Settings Example
This sample demonstrates creating Azure AI Agents with explicit configuration
settings rather than relying on environment variable defaults.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=credential,
) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in New York?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,75 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from pathlib import Path
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.ai.agents.aio import AgentsClient
from azure.ai.agents.models import FileInfo, VectorStore
from azure.identity.aio import AzureCliCredential
"""
The following sample demonstrates how to create a simple, Azure AI agent that
uses a file search tool to answer user questions.
"""
# Simulate a conversation with the agent
USER_INPUTS = [
"Who is the youngest employee?",
"Who works in sales?",
"I have a customer request, who can help me?",
]
async def main() -> None:
"""Main function demonstrating Azure AI agent with file search capabilities."""
file: FileInfo | None = None
vector_store: VectorStore | None = None
async with (
AzureCliCredential() as credential,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
try:
# 1. Upload file and create vector store
pdf_file_path = Path(__file__).parents[2] / "shared" / "resources" / "employees.pdf"
print(f"Uploading file from: {pdf_file_path}")
file = await agents_client.files.upload_and_poll(file_path=str(pdf_file_path), purpose="assistants")
print(f"Uploaded file, file ID: {file.id}")
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 a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
file_search_tool = client.get_file_search_tool(vector_store_ids=[vector_store.id])
# 3. Create an agent with file search capabilities using the provider
agent = await provider.create_agent(
name="EmployeeSearchAgent",
instructions=(
"You are a helpful assistant that can search through uploaded employee files "
"to answer questions about employees."
),
tools=[file_search_tool],
)
# 4. Simulate conversation with the agent
for user_input in USER_INPUTS:
print(f"# User: '{user_input}'")
response = await agent.run(user_input)
print(f"# Agent: {response.text}")
finally:
# 5. Cleanup: Delete the vector store and file in case of earlier failure to prevent orphaned resources.
if vector_store:
await agents_client.vector_stores.delete(vector_store.id)
if file:
await agents_client.files.delete(file.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,129 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Any
from agent_framework import AgentResponse, AgentThread, Message, SupportsAgentRun
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Hosted MCP Example
This sample demonstrates integrating hosted Model Context Protocol (MCP) tools with Azure AI Agent.
"""
async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun") -> AgentResponse:
"""When we don't have a thread, we need to ensure we return with the input, approval request and approval."""
result = await agent.run(query, store=False)
while len(result.user_input_requests) > 0:
new_inputs: list[Any] = [query]
for user_input_needed in result.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
new_inputs.append(Message("assistant", [user_input_needed]))
user_approval = input("Approve function call? (y/n): ")
new_inputs.append(
Message("user", [user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
)
result = await agent.run(new_inputs, store=False)
return result
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread") -> AgentResponse:
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
result = await agent.run(query, thread=thread)
while len(result.user_input_requests) > 0:
new_input: list[Any] = []
for user_input_needed in result.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
user_approval = input("Approve function call? (y/n): ")
new_input.append(
Message(
role="user",
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
result = await agent.run(new_input, thread=thread)
return result
async def run_hosted_mcp_without_approval() -> None:
"""Example showing MCP Tools without approval."""
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(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",
approval_mode="never_require",
)
agent = await provider.create_agent(
name="MyLearnDocsAgent",
instructions="You are a helpful assistant that can help with Microsoft documentation questions.",
tools=[mcp_tool],
)
query = "How to create an Azure storage account using az cli?"
print(f"User: {query}")
result = await handle_approvals_without_thread(query, agent)
print(f"{agent.name}: {result}\n")
async def run_hosted_mcp_with_approval_and_thread() -> None:
"""Example showing MCP Tools with approvals using a thread."""
print("=== MCP with approvals and with thread ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
# Create MCP tool using instance method
mcp_tool = client.get_mcp_tool(
name="api-specs",
url="https://gitmcp.io/Azure/azure-rest-api-specs",
approval_mode="always_require",
)
agent = await provider.create_agent(
name="MyApiSpecsAgent",
instructions="You are a helpful agent that can use MCP tools to assist users.",
tools=[mcp_tool],
)
thread = agent.get_new_thread()
query = "Please summarize the Azure REST API specifications Readme"
print(f"User: {query}")
result = await handle_approvals_with_thread(query, agent, thread)
print(f"{agent.name}: {result}\n")
async def main() -> None:
print("=== Azure AI Agent with Hosted MCP Tools Example ===\n")
await run_hosted_mcp_without_approval()
await run_hosted_mcp_with_approval_and_thread()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,107 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import base64
import tempfile
from pathlib import Path
from urllib import request as urllib_request
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Image Generation Example
This sample demonstrates basic usage of AzureAIProjectAgentProvider to create an agent
that can generate images based on user requirements.
Pre-requisites:
- Make sure to set up the AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME
environment variables before running this sample.
"""
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
# Create image generation tool using instance method
image_gen_tool = client.get_image_generation_tool(
model="gpt-image-1",
size="1024x1024",
output_format="png",
quality="low",
background="opaque",
)
agent = await provider.create_agent(
name="ImageGenAgent",
instructions="Generate images based on user requirements.",
tools=[image_gen_tool],
)
query = "Generate an image of Microsoft logo."
print(f"User: {query}")
result = await agent.run(
query,
# These additional options are required for image generation
options={
"extra_headers": {"x-ms-oai-image-generation-deployment": "gpt-image-1-mini"},
},
)
print(f"Agent: {result}\n")
# Save the image to a file
print("Downloading generated image...")
image_data = [
content.outputs
for content in result.messages[0].contents
if content.type == "image_generation_tool_result" and content.outputs is not None
]
if image_data and image_data[0]:
# Save to the OS temporary directory
filename = "microsoft.png"
file_path = Path(tempfile.gettempdir()) / filename
# outputs can be a list of Content items (data/uri) or a single item
out = image_data[0][0] if isinstance(image_data[0], list) else image_data[0]
data_bytes: bytes | None = None
uri = getattr(out, "uri", None)
if isinstance(uri, str):
if ";base64," in uri:
try:
b64 = uri.split(";base64,", 1)[1]
data_bytes = base64.b64decode(b64)
except Exception:
data_bytes = None
else:
try:
data_bytes = await asyncio.to_thread(lambda: urllib_request.urlopen(uri).read())
except Exception:
data_bytes = None
if data_bytes is None:
raise RuntimeError("Image output present but could not retrieve bytes.")
with open(file_path, "wb") as f:
f.write(data_bytes)
print(f"Image downloaded and saved to: {file_path}")
else:
print("No image data found in the agent response.")
"""
Sample output:
User: Generate an image of Microsoft logo.
Agent: Here is the Microsoft logo image featuring its iconic four quadrants.
Downloading generated image...
Image downloaded and saved to: .../microsoft.png
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,56 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import MCPStreamableHTTPTool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Local MCP Example
This sample demonstrates integration of Azure AI Agents with local Model Context Protocol (MCP)
servers.
Pre-requisites:
- Make sure to set up the AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME
environment variables before running this sample.
"""
async def main() -> None:
"""Example showing use of Local MCP Tool with AzureAIProjectAgentProvider."""
print("=== Azure AI Agent with Local MCP Tools Example ===\n")
mcp_tool = MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
)
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with Microsoft documentation questions.",
tools=mcp_tool,
)
# Use agent as context manager to ensure proper cleanup
async with agent:
# First query
first_query = "How to create an Azure storage account using az cli?"
print(f"User: {first_query}")
first_result = await agent.run(first_query)
print(f"Agent: {first_result}")
print("\n=======================================\n")
# Second query
second_query = "What is Microsoft Agent Framework?"
print(f"User: {second_query}")
second_result = await agent.run(second_query)
print(f"Agent: {second_result}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,88 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
import uuid
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import MemoryStoreDefaultDefinition, MemoryStoreDefaultOptions
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Memory Search Example
This sample demonstrates usage of AzureAIProjectAgentProvider with memory search capabilities
to retrieve relevant past user messages and maintain conversation context across sessions.
It shows explicit memory store creation using Azure AI Projects client and agent creation
using the Agent Framework.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Set AZURE_AI_CHAT_MODEL_DEPLOYMENT_NAME for the memory chat model.
3. Set AZURE_AI_EMBEDDING_MODEL_DEPLOYMENT_NAME for the memory embedding model.
4. Deploy both a chat model (e.g. gpt-4.1) and an embedding model (e.g. text-embedding-3-small).
"""
async def main() -> None:
endpoint = os.environ["AZURE_AI_PROJECT_ENDPOINT"]
# Generate a unique memory store name to avoid conflicts
memory_store_name = f"agent_framework_memory_store_{uuid.uuid4().hex[:8]}"
async with AzureCliCredential() as credential:
# Create the memory store using Azure AI Projects client
async with AIProjectClient(endpoint=endpoint, credential=credential) as project_client:
# Create a memory store using proper model classes
memory_store_definition = MemoryStoreDefaultDefinition(
chat_model=os.environ["AZURE_AI_CHAT_MODEL_DEPLOYMENT_NAME"],
embedding_model=os.environ["AZURE_AI_EMBEDDING_MODEL_DEPLOYMENT_NAME"],
options=MemoryStoreDefaultOptions(user_profile_enabled=True, chat_summary_enabled=True),
)
memory_store = await project_client.memory_stores.create(
name=memory_store_name,
description="Memory store for Agent Framework conversations",
definition=memory_store_definition,
)
print(f"Created memory store: {memory_store.name} ({memory_store.id}): {memory_store.description}")
# Then, create the agent using Agent Framework provider
async with AzureAIProjectAgentProvider(credential=credential) as provider:
agent = await provider.create_agent(
name="MyMemoryAgent",
instructions="""You are a helpful assistant that remembers past conversations.
Use the memory search tool to recall relevant information from previous interactions.""",
tools={
"type": "memory_search",
"memory_store_name": memory_store.name,
"scope": "user_123",
"update_delay": 1, # Wait 1 second before updating memories (use higher value in production)
},
)
# First interaction - establish some preferences
print("=== First conversation ===")
query1 = "I prefer dark roast coffee"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}\n")
# Wait for memories to be processed
print("Waiting for memories to be stored...")
await asyncio.sleep(5) # Reduced wait time for demo purposes
# Second interaction - test memory recall
print("=== Second conversation ===")
query2 = "Please order my usual coffee"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
# Clean up - delete the memory store
async with AIProjectClient(endpoint=endpoint, credential=credential) as project_client:
await project_client.memory_stores.delete(memory_store_name)
print("Memory store deleted")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,48 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Microsoft Fabric Example
This sample demonstrates usage of AzureAIProjectAgentProvider with Microsoft Fabric
to query Fabric data sources and provide responses based on data analysis.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have a Microsoft Fabric connection configured in your Azure AI project
and set FABRIC_PROJECT_CONNECTION_ID environment variable.
"""
async def main() -> None:
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyFabricAgent",
instructions="You are a helpful assistant.",
tools={
"type": "fabric_dataagent_preview",
"fabric_dataagent_preview": {
"project_connections": [
{
"project_connection_id": os.environ["FABRIC_PROJECT_CONNECTION_ID"],
}
]
},
},
)
query = "Tell me about sales records"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,54 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import json
from pathlib import Path
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with OpenAPI Tool Example
This sample demonstrates usage of AzureAIProjectAgentProvider with OpenAPI tools
to call external APIs defined by OpenAPI specifications.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. The countries.json OpenAPI specification is included in the resources folder.
"""
async def main() -> None:
# Load the OpenAPI specification
resources_path = Path(__file__).parents[2] / "shared" / "resources" / "countries.json"
with open(resources_path) as f:
openapi_countries = json.load(f)
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyOpenAPIAgent",
instructions="""You are a helpful assistant that can use country APIs to provide information.
Use the available OpenAPI tools to answer questions about countries, currencies, and demographics.""",
tools={
"type": "openapi",
"openapi": {
"name": "get_countries",
"spec": openapi_countries,
"description": "Retrieve information about countries by currency code",
"auth": {"type": "anonymous"},
},
},
)
query = "What is the name and population of the country that uses currency with abbreviation THB?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,94 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.ai.projects.models import Reasoning
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Reasoning Example
Demonstrates how to enable reasoning capabilities using the Reasoning option.
Shows both non-streaming and streaming approaches, including how to access
reasoning content (type="text_reasoning") separately from answer content.
Requires a reasoning-capable model (e.g., gpt-5.2) deployed in your Azure AI Project configured
as `AZURE_AI_MODEL_DEPLOYMENT_NAME` in your environment.
"""
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="ReasoningWeatherAgent",
instructions="You are a helpful weather agent who likes to understand the underlying physics.",
default_options={"reasoning": Reasoning(effort="medium", summary="concise")},
)
query = "How does the Bernoulli effect work?"
print(f"User: {query}")
result = await agent.run(query)
for msg in result.messages:
for content in msg.contents:
if content.type == "text_reasoning":
print(f"[Reasoning]: {content.text}")
elif content.type == "text":
print(f"[Answer]: {content.text}")
print()
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="ReasoningWeatherAgent",
instructions="You are a helpful weather agent who likes to understand the underlying physics.",
default_options={"reasoning": Reasoning(effort="medium", summary="concise")},
)
query = "Help explain how air updrafts work?"
print(f"User: {query}")
shown_reasoning_label = False
shown_text_label = False
async for chunk in agent.run(query, stream=True):
for content in chunk.contents:
if content.type == "text_reasoning":
if not shown_reasoning_label:
print("[Reasoning]: ", end="", flush=True)
shown_reasoning_label = True
print(content.text, end="", flush=True)
elif content.type == "text":
if not shown_text_label:
print("\n\n[Answer]: ", end="", flush=True)
shown_text_label = True
print(content.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Azure AI Agent with Reasoning Example ===")
# await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,55 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
from pydantic import BaseModel, ConfigDict
"""
Azure AI Agent Response Format Example
This sample demonstrates basic usage of AzureAIProjectAgentProvider with response format,
also known as structured outputs.
"""
class ReleaseBrief(BaseModel):
feature: str
benefit: str
launch_date: str
model_config = ConfigDict(extra="forbid")
async def main() -> None:
"""Example of using response_format property."""
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="ProductMarketerAgent",
instructions="Return launch briefs as structured JSON.",
# Specify Pydantic model for structured output via default_options
default_options={"response_format": ReleaseBrief},
)
query = "Draft a launch brief for the Contoso Note app."
print(f"User: {query}")
result = await agent.run(query)
try:
release_brief = result.value
print("Agent:")
print(f"Feature: {release_brief.feature}")
print(f"Benefit: {release_brief.benefit}")
print(f"Launch date: {release_brief.launch_date}")
except Exception:
print(f"Failed to parse response: {result.text}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,64 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent Response Format Example with Runtime JSON Schema
This sample demonstrates basic usage of AzureAIProjectAgentProvider with response format,
also known as structured outputs.
"""
runtime_schema = {
"title": "WeatherDigest",
"type": "object",
"properties": {
"location": {"type": "string"},
"conditions": {"type": "string"},
"temperature_c": {"type": "number"},
"advisory": {"type": "string"},
},
# OpenAI strict mode requires every property to appear in required.
"required": ["location", "conditions", "temperature_c", "advisory"],
"additionalProperties": False,
}
async def main() -> None:
"""Example of using response_format property with a runtime JSON schema."""
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Pass response_format via default_options using dict schema format
agent = await provider.create_agent(
name="WeatherDigestAgent",
instructions="Return sample weather digest as structured JSON.",
default_options={
"response_format": {
"type": "json_schema",
"json_schema": {
"name": runtime_schema["title"],
"strict": True,
"schema": runtime_schema,
},
}
},
)
query = "Draft a sample weather digest."
print(f"User: {query}")
result = await agent.run(query)
print(result.text)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,49 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with SharePoint Example
This sample demonstrates usage of AzureAIProjectAgentProvider with SharePoint
to search through SharePoint content and answer user questions about it.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables.
2. Ensure you have a SharePoint connection configured in your Azure AI project
and set SHAREPOINT_PROJECT_CONNECTION_ID environment variable.
"""
async def main() -> None:
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MySharePointAgent",
instructions="""You are a helpful agent that can use SharePoint tools to assist users.
Use the available SharePoint tools to answer questions and perform tasks.""",
tools={
"type": "sharepoint_grounding_preview",
"sharepoint_grounding_preview": {
"project_connections": [
{
"project_connection_id": os.environ["SHAREPOINT_PROJECT_CONNECTION_ID"],
}
]
},
},
)
query = "What is Contoso whistleblower policy?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,162 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent with Thread Management Example
This sample demonstrates thread management with Azure AI Agent, showing
persistent conversation capabilities using service-managed threads as well as storing messages in-memory.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production
# See:
# samples/02-agents/tools/function_tool_with_approval.py
# samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_thread_creation() -> None:
"""Example showing automatic thread creation."""
print("=== Automatic Thread Creation Example ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="BasicWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# First conversation - no thread provided, will be created automatically
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1.text}")
# Second conversation - still no thread provided, will create another new thread
query2 = "What was the last city I asked about?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2.text}")
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
async def example_with_thread_persistence_in_memory() -> None:
"""
Example showing thread persistence across multiple conversations.
In this example, messages are stored in-memory.
"""
print("=== Thread Persistence Example (In-Memory) ===")
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="BasicWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a new thread that will be reused
thread = agent.get_new_thread()
# First conversation
first_query = "What's the weather like in Tokyo?"
print(f"User: {first_query}")
first_result = await agent.run(first_query, thread=thread, options={"store": False})
print(f"Agent: {first_result.text}")
# Second conversation using the same thread - maintains context
second_query = "How about London?"
print(f"\nUser: {second_query}")
second_result = await agent.run(second_query, thread=thread, options={"store": False})
print(f"Agent: {second_result.text}")
# Third conversation - agent should remember both previous cities
third_query = "Which of the cities I asked about has better weather?"
print(f"\nUser: {third_query}")
third_result = await agent.run(third_query, thread=thread, options={"store": False})
print(f"Agent: {third_result.text}")
print("Note: The agent remembers context from previous messages in the same thread.\n")
async def example_with_existing_thread_id() -> None:
"""
Example showing how to work with an existing thread ID from the service.
In this example, messages are stored on the server.
"""
print("=== Existing Thread ID Example ===")
# First, create a conversation and capture the thread ID
existing_thread_id = None
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="BasicWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Start a conversation and get the thread ID
thread = agent.get_new_thread()
first_query = "What's the weather in Paris?"
print(f"User: {first_query}")
first_result = await agent.run(first_query, thread=thread)
print(f"Agent: {first_result.text}")
# The thread ID is set after the first response
existing_thread_id = thread.service_thread_id
print(f"Thread ID: {existing_thread_id}")
if existing_thread_id:
print("\n--- Continuing with the same thread ID in a new agent instance ---")
# Create a new agent instance from the same provider
second_agent = await provider.create_agent(
name="BasicWeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a thread with the existing ID
thread = second_agent.get_new_thread(service_thread_id=existing_thread_id)
second_query = "What was the last city I asked about?"
print(f"User: {second_query}")
second_result = await second_agent.run(second_query, thread=thread)
print(f"Agent: {second_result.text}")
print("Note: The agent continues the conversation from the previous thread by using thread ID.\n")
async def main() -> None:
print("=== Azure AI Agent Thread Management Examples ===\n")
await example_with_automatic_thread_creation()
await example_with_thread_persistence_in_memory()
await example_with_existing_thread_id()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,53 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIClient, AzureAIProjectAgentProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent With Web Search
This sample demonstrates basic usage of AzureAIProjectAgentProvider to create an agent
that can perform web searches using get_web_search_tool().
Pre-requisites:
- Make sure to set up the AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME
environment variables before running this sample.
"""
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIProjectAgentProvider(credential=credential) as provider,
):
# Create a client to access hosted tool factory methods
client = AzureAIClient(credential=credential)
# Create web search tool using instance method
web_search_tool = client.get_web_search_tool()
agent = await provider.create_agent(
name="WebsearchAgent",
instructions="You are a helpful assistant that can search the web",
tools=[web_search_tool],
)
query = "What's the weather today in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
"""
Sample output:
User: What's the weather today in Seattle?
Agent: Here is the updated weather forecast for Seattle: The current temperature is approximately 57°F,
mostly cloudy conditions, with light winds and a chance of rain later tonight. Check out more details
at the [National Weather Service](https://forecast.weather.gov/zipcity.php?inputstring=Seattle%2CWA).
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,114 @@
# Azure AI Agent Examples
This folder contains examples demonstrating different ways to create and use agents with Azure AI using the `AzureAIAgentsProvider` from the `agent_framework.azure` package. These examples use the `azure-ai-agents` 1.x (V1) API surface. For updated V2 (`azure-ai-projects` 2.x) samples, see the [Azure AI V2 examples folder](../azure_ai/).
## Provider Pattern
All examples in this folder use the `AzureAIAgentsProvider` class which provides a high-level interface for agent operations:
- **`create_agent()`** - Create a new agent on the Azure AI service
- **`get_agent()`** - Retrieve an existing agent by ID or from a pre-fetched Agent object
- **`as_agent()`** - Wrap an SDK Agent object as a Agent without HTTP calls
```python
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="MyAgent",
instructions="You are a helpful assistant.",
tools=my_function,
)
result = await agent.run("Hello!")
```
## Examples
| File | Description |
|------|-------------|
| [`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 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 `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 `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 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 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. |
## Environment Variables
Before running the examples, you need to set up your environment variables. You can do this in one of two ways:
### Option 1: Using a .env file (Recommended)
1. Copy the `.env.example` file from the `python` directory to create a `.env` file:
```bash
cp ../../.env.example ../../.env
```
2. Edit the `.env` file and add your values:
```
AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
```
3. For samples using Bing Grounding search (like `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`), you'll also need:
```
BING_CONNECTION_ID="your-bing-connection-id"
```
To get your Bing connection details:
- Go to [Azure AI Foundry portal](https://ai.azure.com)
- Navigate to your project's "Connected resources" section
- Add a new connection for "Grounding with Bing Search"
- Copy the ID
4. For samples using Bing Custom Search (like `azure_ai_with_bing_custom_search.py`), you'll also need:
```
BING_CUSTOM_CONNECTION_ID="your-bing-custom-connection-id"
BING_CUSTOM_INSTANCE_NAME="your-bing-custom-instance-name"
```
To get your Bing Custom Search connection details:
- Go to [Azure AI Foundry portal](https://ai.azure.com)
- Navigate to your project's "Connected resources" section
- Add a new connection for "Grounding with Bing Custom Search"
- Copy the connection ID and instance name
### Option 2: Using environment variables directly
Set the environment variables in your shell:
```bash
export AZURE_AI_PROJECT_ENDPOINT="your-project-endpoint"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="your-model-deployment-name"
export BING_CONNECTION_ID="your-bing-connection-id"
export BING_CUSTOM_CONNECTION_ID="your-bing-custom-connection-id"
export BING_CUSTOM_INSTANCE_NAME="your-bing-custom-instance-name"
```
### Required Variables
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI project endpoint (required for all examples)
- `AZURE_AI_MODEL_DEPLOYMENT_NAME`: The name of your model deployment (required for all examples)
### Optional Variables
- `BING_CONNECTION_ID`: Your Bing connection ID (required for `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`)
- `BING_CUSTOM_CONNECTION_ID`: Your Bing Custom Search connection ID (required for `azure_ai_with_bing_custom_search.py`)
- `BING_CUSTOM_INSTANCE_NAME`: Your Bing Custom Search instance name (required for `azure_ai_with_bing_custom_search.py`)
@@ -0,0 +1,83 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent Basic Example
This sample demonstrates basic usage of AzureAIAgentsProvider to create agents with automatic
lifecycle management. Shows both streaming and non-streaming responses with function tools.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Portland?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Basic Azure AI Chat Client Agent Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,145 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIAgentsProvider
from azure.ai.agents.aio import AgentsClient
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent Provider Methods Example
This sample demonstrates the methods available on the AzureAIAgentsProvider class:
- create_agent(): Create a new agent on the service
- get_agent(): Retrieve an existing agent by ID
- as_agent(): Wrap an SDK Agent object without making HTTP calls
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def create_agent_example() -> None:
"""Create a new agent using provider.create_agent()."""
print("\n--- create_agent() ---")
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather assistant.",
tools=get_weather,
)
print(f"Created: {agent.name} (ID: {agent.id})")
result = await agent.run("What's the weather in Seattle?")
print(f"Response: {result}")
async def get_agent_example() -> None:
"""Retrieve an existing agent by ID using provider.get_agent()."""
print("\n--- get_agent() ---")
async with (
AzureCliCredential() as credential,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
# Create an agent directly with SDK (simulating pre-existing agent)
sdk_agent = await agents_client.create_agent(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
name="ExistingAgent",
instructions="You always respond with 'Hello!'",
)
try:
# Retrieve using provider
agent = await provider.get_agent(sdk_agent.id)
print(f"Retrieved: {agent.name} (ID: {agent.id})")
result = await agent.run("Hi there!")
print(f"Response: {result}")
finally:
await agents_client.delete_agent(sdk_agent.id)
async def as_agent_example() -> None:
"""Wrap an SDK Agent object using provider.as_agent()."""
print("\n--- as_agent() ---")
async with (
AzureCliCredential() as credential,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
# Create agent using SDK
sdk_agent = await agents_client.create_agent(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
name="WrappedAgent",
instructions="You respond with poetry.",
)
try:
# Wrap synchronously (no HTTP call)
agent = provider.as_agent(sdk_agent)
print(f"Wrapped: {agent.name} (ID: {agent.id})")
result = await agent.run("Tell me about the sunset.")
print(f"Response: {result}")
finally:
await agents_client.delete_agent(sdk_agent.id)
async def multiple_agents_example() -> None:
"""Create and manage multiple agents with a single provider."""
print("\n--- Multiple Agents ---")
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
weather_agent = await provider.create_agent(
name="WeatherSpecialist",
instructions="You are a weather specialist.",
tools=get_weather,
)
greeter_agent = await provider.create_agent(
name="GreeterAgent",
instructions="You are a friendly greeter.",
)
print(f"Created: {weather_agent.name}, {greeter_agent.name}")
greeting = await greeter_agent.run("Hello!")
print(f"Greeter: {greeting}")
weather = await weather_agent.run("What's the weather in Tokyo?")
print(f"Weather: {weather}")
async def main() -> None:
print("Azure AI Agent Provider Methods")
await create_agent_example()
await get_agent_example()
await as_agent_example()
await multiple_agents_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,116 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework import Annotation
from agent_framework.azure import AzureAIAgentsProvider
from azure.ai.agents.aio import AgentsClient
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import ConnectionType
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Azure AI Search Example
This sample demonstrates how to create an Azure AI agent that uses Azure AI Search
to search through indexed hotel data and answer user questions about hotels.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables
2. Ensure you have an Azure AI Search connection configured in your Azure AI project
3. The search index "hotels-sample-index" should exist in your Azure AI Search service
(you can create this using the Azure portal with sample hotel data)
NOTE: To ensure consistent search tool usage:
- Include explicit instructions for the agent to use the search tool
- Mention the search requirement in your queries
- Use `tool_choice="required"` to force tool usage
More info on `query type` can be found here:
https://learn.microsoft.com/en-us/python/api/azure-ai-agents/azure.ai.agents.models.aisearchindexresource?view=azure-python-preview
"""
async def main() -> None:
"""Main function demonstrating Azure AI agent with raw Azure AI Search tool."""
print("=== Azure AI Agent with Raw Azure AI Search Tool ===")
# Create the client and manually create an agent with Azure AI Search tool
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
ai_search_conn_id = ""
async for connection in project_client.connections.list():
if connection.type == ConnectionType.AZURE_AI_SEARCH:
ai_search_conn_id = connection.id
break
# 1. Create Azure AI agent with the search tool using SDK directly
# (Azure AI Search tool requires special tool_resources configuration)
azure_ai_agent = await agents_client.create_agent(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
name="HotelSearchAgent",
instructions=(
"You are a helpful agent that searches hotel information using Azure AI Search. "
"Always use the search tool and index to find hotel data and provide accurate information."
),
tools=[{"type": "azure_ai_search"}],
tool_resources={
"azure_ai_search": {
"indexes": [
{
"index_connection_id": ai_search_conn_id,
"index_name": "hotels-sample-index",
"query_type": "vector",
}
]
}
},
)
try:
# 2. Use provider.as_agent() to wrap the existing agent
agent = provider.as_agent(agent=azure_ai_agent)
print("This agent uses raw Azure AI Search tool to search hotel data.\n")
# 3. Simulate conversation with the agent
user_input = (
"Use Azure AI search knowledge tool to find detailed information about a winter hotel."
" Use the search tool and index." # You can modify prompt to force tool usage
)
print(f"User: {user_input}")
print("Agent: ", end="", flush=True)
# Stream the response and collect citations
citations: list[Annotation] = []
async for chunk in agent.run(user_input, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
# Collect citations from Azure AI Search responses
for content in getattr(chunk, "contents", []):
annotations = getattr(content, "annotations", [])
if annotations:
citations.extend(annotations)
print()
# Display collected citation
if citations:
print("\n\nCitation:")
for i, citation in enumerate(citations, 1):
print(f"[{i}] {citation.get('url')}")
print("\n" + "=" * 50 + "\n")
print("Hotel search conversation completed!")
finally:
# Clean up the agent manually
await agents_client.delete_agent(azure_ai_agent.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,63 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
The following sample demonstrates how to create an Azure AI agent that
uses Bing Custom Search to find real-time information from the web.
More information on Bing Custom Search and difference from Bing Grounding can be found here:
https://learn.microsoft.com/en-us/azure/ai-foundry/agents/how-to/tools/bing-custom-search
Prerequisites:
1. A connected Grounding with Bing Custom Search resource in your Azure AI project
2. Set BING_CUSTOM_CONNECTION_ID environment variable
Example: BING_CUSTOM_CONNECTION_ID="your-bing-custom-connection-id"
3. Set BING_CUSTOM_INSTANCE_NAME environment variable
Example: BING_CUSTOM_INSTANCE_NAME="your-bing-custom-instance-name"
To set up Bing Custom Search:
1. Go to Azure AI Foundry portal (https://ai.azure.com)
2. Navigate to your project's "Connected resources" section
3. Add a new connection for "Grounding with Bing Custom Search"
4. Copy the connection ID and instance name and set the appropriate environment variables
"""
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Custom Search."""
# 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],
)
# 3. Demonstrate agent capabilities with bing custom search
print("=== Azure AI Agent with Bing Custom Search ===\n")
user_input = "Tell me more about foundry agent service"
print(f"User: {user_input}")
response = await agent.run(user_input)
print(f"Agent: {response.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,58 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
The following sample demonstrates how to create an Azure AI agent that
uses Bing Grounding search to find real-time information from the web.
Prerequisites:
1. A connected Grounding with Bing Search resource in your Azure AI project
2. Set BING_CONNECTION_ID environment variable
Example: BING_CONNECTION_ID="your-bing-connection-id"
To set up Bing Grounding:
1. Go to Azure AI Foundry portal (https://ai.azure.com)
2. Navigate to your project's "Connected resources" section
3. Add a new connection for "Grounding with Bing Search"
4. Copy either the connection name or ID and set the appropriate environment variable
"""
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Grounding search."""
# 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=(
"You are a helpful assistant that can search the web for current information. "
"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],
)
# 3. Demonstrate agent capabilities with web search
print("=== Azure AI Agent with Bing Grounding Search ===\n")
user_input = "What is the most popular programming language?"
print(f"User: {user_input}")
response = await agent.run(user_input)
print(f"Agent: {response.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,86 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Annotation
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
This sample demonstrates how to create an Azure AI agent that uses Bing Grounding
search to find real-time information from the web with comprehensive citation support.
It shows how to extract and display citations (title, URL, and snippet) from Bing
Grounding responses, enabling users to verify sources and explore referenced content.
Prerequisites:
1. A connected Grounding with Bing Search resource in your Azure AI project
2. Set BING_CONNECTION_ID environment variable
Example: BING_CONNECTION_ID="your-bing-connection-id"
To set up Bing Grounding:
1. Go to Azure AI Foundry portal (https://ai.azure.com)
2. Navigate to your project's "Connected resources" section
3. Add a new connection for "Grounding with Bing Search"
4. Copy the connection ID and set the BING_CONNECTION_ID environment variable
"""
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Grounding search."""
# 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=(
"You are a helpful assistant that can search the web for current information. "
"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],
)
# 3. Demonstrate agent capabilities with web search
print("=== Azure AI Agent with Bing Grounding Search ===\n")
user_input = "What is the most popular programming language?"
print(f"User: {user_input}")
print("Agent: ", end="", flush=True)
# Stream the response and collect citations
citations: list[Annotation] = []
async for chunk in agent.run(user_input, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
# Collect citations from Bing Grounding responses
for content in getattr(chunk, "contents", []):
annotations = getattr(content, "annotations", [])
if annotations:
citations.extend(annotations)
print()
# Display collected citations
if citations:
print("\n\nCitations:")
for i, citation in enumerate(citations, 1):
print(f"[{i}] {citation['title']}: {citation.get('url')}")
if "snippet" in citation:
print(f" Snippet: {citation.get('snippet')}")
else:
print("\nNo citations found in the response.")
print()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,63 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import AgentResponse, ChatResponseUpdate
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.ai.agents.models import (
RunStepDeltaCodeInterpreterDetailItemObject,
)
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Code Interpreter Example
This sample demonstrates using get_code_interpreter_tool() with Azure AI Agents
for Python code execution and mathematical problem solving.
"""
def print_code_interpreter_inputs(response: AgentResponse) -> None:
"""Helper method to access code interpreter data."""
print("\nCode Interpreter Inputs during the run:")
if response.raw_representation is None:
return
for chunk in response.raw_representation:
if isinstance(chunk, ChatResponseUpdate) and isinstance(
chunk.raw_representation, RunStepDeltaCodeInterpreterDetailItemObject
):
print(chunk.raw_representation.input, end="")
print("\n")
async def main() -> None:
"""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
# authentication option.
async with (
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=[code_interpreter_tool],
)
query = "Generate the factorial of 100 using python code, show the code and execute it."
print(f"User: {query}")
response = await agent.run(query)
print(f"Agent: {response}")
# To review the code interpreter outputs, you can access
# them from the response raw_representations, just uncomment the next line:
# print_code_interpreter_inputs(response)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,102 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
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 get_code_interpreter_tool() with AzureAIAgentsProvider
to generate a text file and then retrieve it.
The test flow:
1. Create an agent with code interpreter tool
2. Ask the agent to generate a txt file using Python code
3. Capture the file_id from HostedFileContent in the response
4. Retrieve the file using the agents_client.files API
"""
async def main() -> None:
"""Test file generation and retrieval with code interpreter."""
async with (
AzureCliCredential() as credential,
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=(
"You are a Python code execution assistant. "
"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=[code_interpreter_tool],
)
# Be very explicit about wanting code execution and a download link
query = (
"Use the code interpreter to execute this Python code and then provide me "
"with a download link for the generated file:\n"
"```python\n"
"with open('/mnt/data/sample.txt', 'w') as f:\n"
" f.write('Hello, World! This is a test file.')\n"
"'/mnt/data/sample.txt'\n" # Return the path so it becomes downloadable
"```"
)
print(f"User: {query}\n")
print("=" * 60)
# Collect file_ids from the response
file_ids: list[str] = []
async for chunk in agent.run(query, stream=True):
for content in chunk.contents:
if content.type == "text":
print(content.text, end="", flush=True)
elif content.type == "hosted_file" and content.file_id:
file_ids.append(content.file_id)
print(f"\n[File generated: {content.file_id}]")
print("\n" + "=" * 60)
# Attempt to retrieve discovered files
if file_ids:
print(f"\nAttempting to retrieve {len(file_ids)} file(s):")
for file_id in file_ids:
try:
file_info = await agents_client.files.get(file_id)
print(f" File {file_id}: Retrieved successfully")
print(f" Filename: {file_info.filename}")
print(f" Purpose: {file_info.purpose}")
print(f" Bytes: {file_info.bytes}")
except Exception as e:
print(f" File {file_id}: FAILED to retrieve - {e}")
else:
print("No file IDs were captured from the response.")
# List all files to see if any exist
print("\nListing all files in the agent service:")
try:
files_list = await agents_client.files.list()
count = 0
for file_info in files_list.data:
count += 1
print(f" - {file_info.id}: {file_info.filename} ({file_info.purpose})")
if count == 0:
print(" No files found.")
except Exception as e:
print(f" Failed to list files: {e}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,48 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.azure import AzureAIAgentsProvider
from azure.ai.agents.aio import AgentsClient
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Existing Agent Example
This sample demonstrates working with pre-existing Azure AI Agents by providing
agent IDs, showing agent reuse patterns for production scenarios.
"""
async def main() -> None:
print("=== Azure AI Agent with Existing Agent ===")
# Create the client and provider
async with (
AzureCliCredential() as credential,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
# Create an agent on the service with default instructions
# These instructions will persist on created agent for every run.
azure_ai_agent = await agents_client.create_agent(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
instructions="End each response with [END].",
)
try:
# Wrap existing agent instance using provider.as_agent()
agent = provider.as_agent(azure_ai_agent)
query = "How are you?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
finally:
# Clean up the agent manually
await agents_client.delete_agent(azure_ai_agent.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,64 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIAgentsProvider
from azure.ai.agents.aio import AgentsClient
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent with Existing Thread Example
This sample demonstrates working with pre-existing conversation threads
by providing thread IDs for thread reuse patterns.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
print("=== Azure AI Agent with Existing Thread ===")
# Create the client and provider
async with (
AzureCliCredential() as credential,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
# Create a thread that will persist
created_thread = await agents_client.threads.create()
try:
# Create agent using provider
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
thread = agent.get_new_thread(service_thread_id=created_thread.id)
assert thread.is_initialized
result = await agent.run("What's the weather like in Tokyo?", thread=thread)
print(f"Result: {result}\n")
finally:
# Clean up the thread manually
await agents_client.threads.delete(created_thread.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,56 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent with Explicit Settings Example
This sample demonstrates creating Azure AI Agents with explicit configuration
settings rather than relying on environment variable defaults.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
print("=== Azure AI Agent with Explicit Settings ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
credential=credential,
) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
instructions="You are a helpful weather agent.",
tools=get_weather,
)
result = await agent.run("What's the weather like in New York?")
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,80 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from pathlib import Path
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
"""
The following sample demonstrates how to create a simple, Azure AI agent that
uses a file search tool to answer user questions.
"""
# Simulate a conversation with the agent
USER_INPUTS = [
"Who is the youngest employee?",
"Who works in sales?",
"I have a customer request, who can help me?",
]
async def main() -> None:
"""Main function demonstrating Azure AI agent with file search capabilities."""
file: FileInfo | None = None
vector_store: VectorStore | None = None
async with (
AzureCliCredential() as credential,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
AzureAIAgentsProvider(agents_client=agents_client) as provider,
):
try:
# 1. Upload file and create vector store
pdf_file_path = Path(__file__).parent.parent / "resources" / "employees.pdf"
print(f"Uploading file from: {pdf_file_path}")
file = await agents_client.files.upload_and_poll(file_path=str(pdf_file_path), purpose="assistants")
print(f"Uploaded file, file ID: {file.id}")
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 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(
name="EmployeeSearchAgent",
instructions=(
"You are a helpful assistant that can search through uploaded employee files "
"to answer questions about employees."
),
tools=[file_search_tool],
)
# 4. Simulate conversation with the agent
for user_input in USER_INPUTS:
print(f"# User: '{user_input}'")
response = await agent.run(user_input)
print(f"# Agent: {response.text}")
finally:
# 5. Cleanup: Delete the vector store and file
try:
if vector_store:
await agents_client.vector_stores.delete(vector_store.id)
if file:
await agents_client.files.delete(file.id)
except Exception:
# Ignore cleanup errors to avoid masking issues
pass
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,151 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from datetime import datetime, timezone
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent with Function Tools Example
This sample demonstrates function tool integration with Azure AI Agents,
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
@tool(approval_mode="never_require")
def get_time() -> str:
"""Get the current UTC time."""
current_time = datetime.now(timezone.utc)
return f"The current UTC time is {current_time.strftime('%Y-%m-%d %H:%M:%S')}."
async def tools_on_agent_level() -> None:
"""Example showing tools defined when creating the agent."""
print("=== Tools Defined on Agent Level ===")
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="AssistantAgent",
instructions="You are a helpful assistant that can provide weather and time information.",
tools=[get_weather, get_time], # Tools defined at agent creation
)
# First query - agent can use weather tool
query1 = "What's the weather like in New York?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}\n")
# Second query - agent can use time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
# Third query - agent can use both tools if needed
query3 = "What's the weather in London and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3)
print(f"Agent: {result3}\n")
async def tools_on_run_level() -> None:
"""Example showing tools passed to the run method."""
print("=== Tools Passed to Run Method ===")
# Agent created without tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="AssistantAgent",
instructions="You are a helpful assistant.",
# No tools defined here
)
# First query with weather tool
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1, tools=[get_weather]) # Tool passed to run method
print(f"Agent: {result1}\n")
# Second query with time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2, tools=[get_time]) # Different tool for this query
print(f"Agent: {result2}\n")
# Third query with multiple tools
query3 = "What's the weather in Chicago and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3, tools=[get_weather, get_time]) # Multiple tools
print(f"Agent: {result3}\n")
async def mixed_tools_example() -> None:
"""Example showing both agent-level tools and run-method tools."""
print("=== Mixed Tools Example (Agent + Run Method) ===")
# Agent created with some base tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="AssistantAgent",
instructions="You are a comprehensive assistant that can help with various information requests.",
tools=[get_weather], # Base tool available for all queries
)
# Query using both agent tool and additional run-method tools
query = "What's the weather in Denver and what's the current UTC time?"
print(f"User: {query}")
# Agent has access to get_weather (from creation) + additional tools from run method
result = await agent.run(
query,
tools=[get_time], # Additional tools for this specific query
)
print(f"Agent: {result}\n")
async def main() -> None:
print("=== Azure AI Chat Client Agent with Function Tools Examples ===\n")
await tools_on_agent_level()
await tools_on_run_level()
await mixed_tools_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,76 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Any
from agent_framework import AgentResponse, AgentThread, SupportsAgentRun
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Hosted MCP Example
This sample demonstrates integration of Azure AI Agents with hosted Model Context Protocol (MCP)
servers, including user approval workflows for function call security.
"""
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread") -> AgentResponse:
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
from agent_framework import Message
result = await agent.run(query, thread=thread, store=True)
while len(result.user_input_requests) > 0:
new_input: list[Any] = []
for user_input_needed in result.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
user_approval = input("Approve function call? (y/n): ")
new_input.append(
Message(
role="user",
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
result = await agent.run(new_input, thread=thread, store=True)
return result
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=[mcp_tool],
)
thread = agent.get_new_thread()
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await handle_approvals_with_thread(query1, agent, thread)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
result2 = await handle_approvals_with_thread(query2, agent, thread)
print(f"{agent.name}: {result2}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,91 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import MCPStreamableHTTPTool
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Local MCP Example
This sample demonstrates integration of Azure AI Agents with local Model Context Protocol (MCP)
servers, showing both agent-level and run-level tool configuration patterns.
"""
async def mcp_tools_on_run_level() -> None:
"""Example showing MCP tools defined when running the agent."""
print("=== Tools Defined on Run Level ===")
# Tools are provided when running the agent
# This means we have to ensure we connect to the MCP server before running the agent
# and pass the tools to the run method.
async with (
AzureCliCredential() as credential,
MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
) as mcp_server,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
)
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await agent.run(query1, tools=mcp_server)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
result2 = await agent.run(query2, tools=mcp_server)
print(f"{agent.name}: {result2}\n")
async def mcp_tools_on_agent_level() -> None:
"""Example showing local MCP tools passed when creating the agent."""
print("=== Tools Defined on Agent Level ===")
# Tools are provided when creating the agent
# The Agent will connect to the MCP server through its context manager
# and discover tools at runtime
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
),
)
# Use agent as context manager to connect MCP tools
async with agent:
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"{agent.name}: {result2}\n")
async def main() -> None:
print("=== Azure AI Chat Client Agent with MCP Tools Examples ===\n")
await mcp_tools_on_agent_level()
await mcp_tools_on_run_level()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,109 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from datetime import datetime, timezone
from typing import Any
from agent_framework import (
AgentThread,
SupportsAgentRun,
tool,
)
from agent_framework.azure import AzureAIAgentClient, AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
"""
Azure AI Agent with Multiple Tools Example
This sample demonstrates integrating multiple tools (MCP and Web Search) with Azure AI Agents,
including user approval workflows for function call security.
Prerequisites:
1. Set AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables
2. For Bing search functionality, set BING_CONNECTION_ID environment variable to your Bing connection ID
Example: BING_CONNECTION_ID="/subscriptions/{subscription-id}/resourceGroups/{resource-group}/
providers/Microsoft.CognitiveServices/accounts/{ai-service-name}/projects/{project-name}/
connections/{connection-name}"
To set up Bing Grounding:
1. Go to Azure AI Foundry portal (https://ai.azure.com)
2. Navigate to your project's "Connected resources" section
3. Add a new connection for "Grounding with Bing Search"
4. Copy the connection ID and set it as the BING_CONNECTION_ID environment variable
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_time() -> str:
"""Get the current UTC time."""
current_time = datetime.now(timezone.utc)
return f"The current UTC time is {current_time.strftime('%Y-%m-%d %H:%M:%S')}."
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
from agent_framework import Message
result = await agent.run(query, thread=thread, store=True)
while len(result.user_input_requests) > 0:
new_input: list[Any] = []
for user_input_needed in result.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
user_approval = input("Approve function call? (y/n): ")
new_input.append(
Message(
role="user",
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
result = await agent.run(new_input, thread=thread, store=True)
return result
async def main() -> None:
"""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=[
mcp_tool,
web_search_tool,
get_time,
],
)
thread = agent.get_new_thread()
# First query
query1 = "How to create an Azure storage account using az cli and what time is it?"
print(f"User: {query1}")
result1 = await handle_approvals_with_thread(query1, agent, thread)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework and use a web search to see what is Reddit saying about it?"
print(f"User: {query2}")
result2 = await handle_approvals_with_thread(query2, agent, thread)
print(f"{agent.name}: {result2}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,93 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import json
from pathlib import Path
from typing import Any
from agent_framework.azure import AzureAIAgentsProvider
from azure.ai.agents.models import OpenApiAnonymousAuthDetails, OpenApiTool
from azure.identity.aio import AzureCliCredential
"""
The following sample demonstrates how to create a simple, Azure AI agent that
uses OpenAPI tools to answer user questions.
"""
# Simulate a conversation with the agent
USER_INPUTS = [
"What is the name and population of the country that uses currency with abbreviation THB?",
"What is the current weather in the capital city of that country?",
]
def load_openapi_specs() -> tuple[dict[str, Any], dict[str, Any]]:
"""Load OpenAPI specification files."""
resources_path = Path(__file__).parents[2] / "shared" / "resources"
with open(resources_path / "weather.json") as weather_file:
weather_spec = json.load(weather_file)
with open(resources_path / "countries.json") as countries_file:
countries_spec = json.load(countries_file)
return weather_spec, countries_spec
async def main() -> None:
"""Main function demonstrating Azure AI agent with OpenAPI tools."""
# 1. Load OpenAPI specifications (synchronous operation)
weather_openapi_spec, countries_openapi_spec = load_openapi_specs()
# 2. Use AzureAIAgentsProvider for agent creation and management
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# 3. Create OpenAPI tools using Azure AI's OpenApiTool
auth = OpenApiAnonymousAuthDetails()
openapi_weather = OpenApiTool(
name="get_weather",
spec=weather_openapi_spec,
description="Retrieve weather information for a location using wttr.in service",
auth=auth,
)
openapi_countries = OpenApiTool(
name="get_country_info",
spec=countries_openapi_spec,
description="Retrieve country information including population and capital city",
auth=auth,
)
# 4. Create an agent with OpenAPI tools
# Note: We need to pass the Azure AI native OpenApiTool definitions directly
# since the agent framework doesn't have a HostedOpenApiTool wrapper yet
agent = await provider.create_agent(
name="OpenAPIAgent",
instructions=(
"You are a helpful assistant that can search for country information "
"and weather data using APIs. When asked about countries, use the country "
"API to find information. When asked about weather, use the weather API. "
"Provide clear, informative answers based on the API results."
),
# Pass the raw tool definitions from Azure AI's OpenApiTool
tools=[*openapi_countries.definitions, *openapi_weather.definitions],
)
# 5. Simulate conversation with the agent maintaining thread context
print("=== Azure AI Agent with OpenAPI Tools ===\n")
# Create a thread to maintain conversation context across multiple runs
thread = agent.get_new_thread()
for user_input in USER_INPUTS:
print(f"User: {user_input}")
# Pass the thread to maintain context across multiple agent.run() calls
response = await agent.run(user_input, thread=thread)
print(f"Agent: {response.text}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,87 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
from pydantic import BaseModel, ConfigDict
"""
Azure AI Agent Provider Response Format Example
This sample demonstrates using AzureAIAgentsProvider with response_format
for structured outputs in two ways:
1. Setting default response_format at agent creation time (default_options)
2. Overriding response_format at runtime (options parameter in agent.run)
"""
class WeatherInfo(BaseModel):
"""Structured weather information."""
location: str
temperature: int
conditions: str
recommendation: str
model_config = ConfigDict(extra="forbid")
class CityInfo(BaseModel):
"""Structured city information."""
city_name: str
population: int
country: str
model_config = ConfigDict(extra="forbid")
async def main() -> None:
"""Example of using response_format at creation time and runtime."""
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
# Create agent with default response_format (WeatherInfo)
agent = await provider.create_agent(
name="StructuredReporter",
instructions="Return structured JSON based on the requested format.",
default_options={"response_format": WeatherInfo},
)
# Request 1: Uses default response_format from agent creation
print("--- Request 1: Using default response_format (WeatherInfo) ---")
query1 = "What's the weather like in Paris today?"
print(f"User: {query1}")
result1 = await agent.run(query1)
try:
weather = result1.value
print("Agent:")
print(f" Location: {weather.location}")
print(f" Temperature: {weather.temperature}")
print(f" Conditions: {weather.conditions}")
print(f" Recommendation: {weather.recommendation}")
except Exception:
print(f"Failed to parse response: {result1.text}")
# Request 2: Override response_format at runtime with CityInfo
print("\n--- Request 2: Runtime override with CityInfo ---")
query2 = "Tell me about Tokyo."
print(f"User: {query2}")
result2 = await agent.run(query2, options={"response_format": CityInfo})
try:
city = result2.value
print("Agent:")
print(f" City: {city.city_name}")
print(f" Population: {city.population}")
print(f" Country: {city.country}")
except Exception:
print(f"Failed to parse response: {result2.text}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,166 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import AgentThread, tool
from agent_framework.azure import AzureAIAgentsProvider
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Agent with Thread Management Example
This sample demonstrates thread management with Azure AI Agents, comparing
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_thread_creation() -> None:
"""Example showing automatic thread creation (service-managed thread)."""
print("=== Automatic Thread Creation Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# First conversation - no thread provided, will be created automatically
first_query = "What's the weather like in Seattle?"
print(f"User: {first_query}")
first_result = await agent.run(first_query)
print(f"Agent: {first_result.text}")
# Second conversation - still no thread provided, will create another new thread
second_query = "What was the last city I asked about?"
print(f"\nUser: {second_query}")
second_result = await agent.run(second_query)
print(f"Agent: {second_result.text}")
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
async def example_with_thread_persistence() -> None:
"""Example showing thread persistence across multiple conversations."""
print("=== Thread Persistence Example ===")
print("Using the same thread across multiple conversations to maintain context.\n")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a new thread that will be reused
thread = agent.get_new_thread()
# First conversation
first_query = "What's the weather like in Tokyo?"
print(f"User: {first_query}")
first_result = await agent.run(first_query, thread=thread)
print(f"Agent: {first_result.text}")
# Second conversation using the same thread - maintains context
second_query = "How about London?"
print(f"\nUser: {second_query}")
second_result = await agent.run(second_query, thread=thread)
print(f"Agent: {second_result.text}")
# Third conversation - agent should remember both previous cities
third_query = "Which of the cities I asked about has better weather?"
print(f"\nUser: {third_query}")
third_result = await agent.run(third_query, thread=thread)
print(f"Agent: {third_result.text}")
print("Note: The agent remembers context from previous messages in the same thread.\n")
async def example_with_existing_thread_id() -> None:
"""Example showing how to work with an existing thread ID from the service."""
print("=== Existing Thread ID Example ===")
print("Using a specific thread ID to continue an existing conversation.\n")
# First, create a conversation and capture the thread ID
existing_thread_id = None
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Start a conversation and get the thread ID
thread = agent.get_new_thread()
first_query = "What's the weather in Paris?"
print(f"User: {first_query}")
first_result = await agent.run(first_query, thread=thread)
print(f"Agent: {first_result.text}")
# The thread ID is set after the first response
existing_thread_id = thread.service_thread_id
print(f"Thread ID: {existing_thread_id}")
if existing_thread_id:
print("\n--- Continuing with the same thread ID in a new agent instance ---")
# Create a new provider and agent but use the existing thread ID
async with (
AzureCliCredential() as credential,
AzureAIAgentsProvider(credential=credential) as provider,
):
agent = await provider.create_agent(
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a thread with the existing ID
thread = AgentThread(service_thread_id=existing_thread_id)
second_query = "What was the last city I asked about?"
print(f"User: {second_query}")
second_result = await agent.run(second_query, thread=thread)
print(f"Agent: {second_result.text}")
print("Note: The agent continues the conversation from the previous thread.\n")
async def main() -> None:
print("=== Azure AI Chat Client Agent Thread Management Examples ===\n")
await example_with_automatic_thread_creation()
await example_with_thread_persistence()
await example_with_existing_thread_id()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,60 @@
# Azure OpenAI Agent Examples
This folder contains examples demonstrating different ways to create and use agents with the different Azure OpenAI chat client from the `agent_framework.azure` package.
## Examples
| File | Description |
|------|-------------|
| [`azure_assistants_basic.py`](azure_assistants_basic.py) | The simplest way to create an agent using `Agent` with `AzureOpenAIAssistantsClient`. Shows both streaming and non-streaming responses with automatic assistant creation and cleanup. |
| [`azure_assistants_with_code_interpreter.py`](azure_assistants_with_code_interpreter.py) | Shows how to use `AzureOpenAIAssistantsClient.get_code_interpreter_tool()` with Azure agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
| [`azure_assistants_with_existing_assistant.py`](azure_assistants_with_existing_assistant.py) | Shows how to work with a pre-existing assistant by providing the assistant ID to the Azure Assistants client. Demonstrates proper cleanup of manually created assistants. |
| [`azure_assistants_with_explicit_settings.py`](azure_assistants_with_explicit_settings.py) | Shows how to initialize an agent with a specific assistants client, configuring settings explicitly including endpoint and deployment name. |
| [`azure_assistants_with_function_tools.py`](azure_assistants_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_assistants_with_thread.py`](azure_assistants_with_thread.py) | Demonstrates thread management with Azure agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
| [`azure_chat_client_basic.py`](azure_chat_client_basic.py) | The simplest way to create an agent using `Agent` with `AzureOpenAIChatClient`. Shows both streaming and non-streaming responses for chat-based interactions with Azure OpenAI models. |
| [`azure_chat_client_with_explicit_settings.py`](azure_chat_client_with_explicit_settings.py) | Shows how to initialize an agent with a specific chat client, configuring settings explicitly including endpoint and deployment name. |
| [`azure_chat_client_with_function_tools.py`](azure_chat_client_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_chat_client_with_thread.py`](azure_chat_client_with_thread.py) | Demonstrates thread management with Azure agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
| [`azure_responses_client_basic.py`](azure_responses_client_basic.py) | The simplest way to create an agent using `Agent` with `AzureOpenAIResponsesClient`. Shows both streaming and non-streaming responses for structured response generation with Azure OpenAI models. |
| [`azure_responses_client_code_interpreter_files.py`](azure_responses_client_code_interpreter_files.py) | Demonstrates using `AzureOpenAIResponsesClient.get_code_interpreter_tool()` with file uploads for data analysis. Shows how to create, upload, and analyze CSV files using Python code execution with Azure OpenAI Responses. |
| [`azure_responses_client_image_analysis.py`](azure_responses_client_image_analysis.py) | Shows how to use Azure OpenAI Responses for image analysis and vision tasks. Demonstrates multi-modal messages combining text and image content using remote URLs. |
| [`azure_responses_client_with_code_interpreter.py`](azure_responses_client_with_code_interpreter.py) | Shows how to use `AzureOpenAIResponsesClient.get_code_interpreter_tool()` with Azure agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
| [`azure_responses_client_with_explicit_settings.py`](azure_responses_client_with_explicit_settings.py) | Shows how to initialize an agent with a specific responses client, configuring settings explicitly including endpoint and deployment name. |
| [`azure_responses_client_with_file_search.py`](azure_responses_client_with_file_search.py) | Demonstrates using `AzureOpenAIResponsesClient.get_file_search_tool()` with Azure OpenAI Responses Client for direct document-based question answering and information retrieval from vector stores. |
| [`azure_responses_client_with_foundry.py`](azure_responses_client_with_foundry.py) | Shows how to create an agent using an Azure AI Foundry project endpoint instead of a direct Azure OpenAI endpoint. Requires the `azure-ai-projects` package. |
| [`azure_responses_client_with_function_tools.py`](azure_responses_client_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_responses_client_with_hosted_mcp.py`](azure_responses_client_with_hosted_mcp.py) | Shows how to integrate Azure OpenAI Responses Client with hosted Model Context Protocol (MCP) servers using `AzureOpenAIResponsesClient.get_mcp_tool()` for extended functionality. |
| [`azure_responses_client_with_local_mcp.py`](azure_responses_client_with_local_mcp.py) | Shows how to integrate Azure OpenAI Responses Client with local Model Context Protocol (MCP) servers using MCPStreamableHTTPTool for extended functionality. |
| [`azure_responses_client_with_thread.py`](azure_responses_client_with_thread.py) | Demonstrates thread management with Azure agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
## Environment Variables
Make sure to set the following environment variables before running the examples:
- `AZURE_OPENAI_ENDPOINT`: Your Azure OpenAI endpoint
- `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`: The name of your Azure OpenAI chat model deployment
- `AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME`: The name of your Azure OpenAI Responses deployment
For the Foundry project sample (`azure_responses_client_with_foundry.py`), also set:
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI Foundry project endpoint
Optionally, you can set:
- `AZURE_OPENAI_API_VERSION`: The API version to use (default is `2024-02-15-preview`)
- `AZURE_OPENAI_API_KEY`: Your Azure OpenAI API key (if not using `AzureCliCredential`)
- `AZURE_OPENAI_BASE_URL`: Your Azure OpenAI base URL (if different from the endpoint)
## Authentication
All examples use `AzureCliCredential` for authentication. Run `az login` in your terminal before running the examples, or replace `AzureCliCredential` with your preferred authentication method.
## Required role-based access control (RBAC) roles
To access the Azure OpenAI API, your Azure account or service principal needs one of the following RBAC roles assigned to the Azure OpenAI resource:
- **Cognitive Services OpenAI User**: Provides read access to Azure OpenAI resources and the ability to call the inference APIs. This is the minimum role required for running these examples.
- **Cognitive Services OpenAI Contributor**: Provides full access to Azure OpenAI resources, including the ability to create, update, and delete deployments and models.
For most scenarios, the **Cognitive Services OpenAI User** role is sufficient. You can assign this role through the Azure portal under the Azure OpenAI resource's "Access control (IAM)" section.
For more detailed information about Azure OpenAI RBAC roles, see: [Role-based access control for Azure OpenAI Service](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/role-based-access-control)
@@ -0,0 +1,75 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIAssistantsClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Assistants Basic Example
This sample demonstrates basic usage of AzureOpenAIAssistantsClient with automatic
assistant lifecycle management, showing both streaming and non-streaming responses.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# Since no assistant ID is provided, the assistant will be automatically created
# and deleted after getting a response
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with AzureOpenAIAssistantsClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# Since no assistant ID is provided, the assistant will be automatically created
# and deleted after getting a response
async with AzureOpenAIAssistantsClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
query = "What's the weather like in Portland?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Basic Azure OpenAI Assistants Chat Client Agent Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,72 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Agent, AgentResponseUpdate, ChatResponseUpdate
from agent_framework.azure import AzureOpenAIAssistantsClient
from openai.types.beta.threads.runs import (
CodeInterpreterToolCallDelta,
RunStepDelta,
RunStepDeltaEvent,
ToolCallDeltaObject,
)
from openai.types.beta.threads.runs.code_interpreter_tool_call_delta import CodeInterpreter
"""
Azure OpenAI Assistants with Code Interpreter Example
This sample demonstrates using get_code_interpreter_tool() with Azure OpenAI Assistants
for Python code execution and mathematical problem solving.
"""
def get_code_interpreter_chunk(chunk: AgentResponseUpdate) -> str | None:
"""Helper method to access code interpreter data."""
if (
isinstance(chunk.raw_representation, ChatResponseUpdate)
and isinstance(chunk.raw_representation.raw_representation, RunStepDeltaEvent)
and isinstance(chunk.raw_representation.raw_representation.delta, RunStepDelta)
and isinstance(chunk.raw_representation.raw_representation.delta.step_details, ToolCallDeltaObject)
and chunk.raw_representation.raw_representation.delta.step_details.tool_calls
):
for tool_call in chunk.raw_representation.raw_representation.delta.step_details.tool_calls:
if (
isinstance(tool_call, CodeInterpreterToolCallDelta)
and isinstance(tool_call.code_interpreter, CodeInterpreter)
and tool_call.code_interpreter.input is not None
):
return tool_call.code_interpreter.input
return None
async def main() -> None:
"""Example showing how to use the code interpreter tool with Azure OpenAI Assistants."""
print("=== Azure OpenAI Assistants Agent with Code Interpreter Example ===")
# Create code interpreter tool using static method
client = AzureOpenAIAssistantsClient()
code_interpreter_tool = client.get_code_interpreter_tool()
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=client,
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
tools=[code_interpreter_tool],
) as agent:
query = "What is current datetime?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
generated_code = ""
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
code_interpreter_chunk = get_code_interpreter_chunk(chunk)
if code_interpreter_chunk is not None:
generated_code += code_interpreter_chunk
print(f"\nGenerated code:\n{generated_code}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,64 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIAssistantsClient
from azure.identity import AzureCliCredential, get_bearer_token_provider
from openai import AsyncAzureOpenAI
from pydantic import Field
"""
Azure OpenAI Assistants with Existing Assistant Example
This sample demonstrates working with pre-existing Azure OpenAI Assistants
using existing assistant IDs rather than creating new ones.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
print("=== Azure OpenAI Assistants Chat Client with Existing Assistant ===")
token_provider = get_bearer_token_provider(AzureCliCredential(), "https://cognitiveservices.azure.com/.default")
client = AsyncAzureOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
azure_ad_token_provider=token_provider,
api_version="2025-01-01-preview",
)
# Create an assistant that will persist
created_assistant = await client.beta.assistants.create(
model=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"], name="WeatherAssistant"
)
try:
async with Agent(
client=AzureOpenAIAssistantsClient(async_client=client, assistant_id=created_assistant.id),
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
result = await agent.run("What's the weather like in Tokyo?")
print(f"Result: {result}\n")
finally:
# Clean up the assistant manually
await client.beta.assistants.delete(created_assistant.id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,51 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIAssistantsClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Assistants with Explicit Settings Example
This sample demonstrates creating Azure OpenAI Assistants with explicit configuration
settings rather than relying on environment variable defaults.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
print("=== Azure Assistants Client with Explicit Settings ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with AzureOpenAIAssistantsClient(
endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
deployment_name=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
result = await agent.run("What's the weather like in New York?")
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,136 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from datetime import datetime, timezone
from random import randint
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIAssistantsClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Assistants with Function Tools Example
This sample demonstrates function tool integration with Azure OpenAI Assistants,
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
@tool(approval_mode="never_require")
def get_time() -> str:
"""Get the current UTC time."""
current_time = datetime.now(timezone.utc)
return f"The current UTC time is {current_time.strftime('%Y-%m-%d %H:%M:%S')}."
async def tools_on_agent_level() -> None:
"""Example showing tools defined when creating the agent."""
print("=== Tools Defined on Agent Level ===")
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
instructions="You are a helpful assistant that can provide weather and time information.",
tools=[get_weather, get_time], # Tools defined at agent creation
) as agent:
# First query - agent can use weather tool
query1 = "What's the weather like in New York?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}\n")
# Second query - agent can use time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
# Third query - agent can use both tools if needed
query3 = "What's the weather in London and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3)
print(f"Agent: {result3}\n")
async def tools_on_run_level() -> None:
"""Example showing tools passed to the run method."""
print("=== Tools Passed to Run Method ===")
# Agent created without tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
instructions="You are a helpful assistant.",
# No tools defined here
) as agent:
# First query with weather tool
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1, tools=[get_weather]) # Tool passed to run method
print(f"Agent: {result1}\n")
# Second query with time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2, tools=[get_time]) # Different tool for this query
print(f"Agent: {result2}\n")
# Third query with multiple tools
query3 = "What's the weather in Chicago and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3, tools=[get_weather, get_time]) # Multiple tools
print(f"Agent: {result3}\n")
async def mixed_tools_example() -> None:
"""Example showing both agent-level tools and run-method tools."""
print("=== Mixed Tools Example (Agent + Run Method) ===")
# Agent created with some base tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
instructions="You are a comprehensive assistant that can help with various information requests.",
tools=[get_weather], # Base tool available for all queries
) as agent:
# Query using both agent tool and additional run-method tools
query = "What's the weather in Denver and what's the current UTC time?"
print(f"User: {query}")
# Agent has access to get_weather (from creation) + additional tools from run method
result = await agent.run(
query,
tools=[get_time], # Additional tools for this specific query
)
print(f"Agent: {result}\n")
async def main() -> None:
print("=== Azure OpenAI Assistants Chat Client Agent with Function Tools Examples ===\n")
await tools_on_agent_level()
await tools_on_run_level()
await mixed_tools_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,146 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import Agent, AgentThread, tool
from agent_framework.azure import AzureOpenAIAssistantsClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Assistants with Thread Management Example
This sample demonstrates thread management with Azure OpenAI Assistants, comparing
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_thread_creation() -> None:
"""Example showing automatic thread creation (service-managed thread)."""
print("=== Automatic Thread Creation Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
# First conversation - no thread provided, will be created automatically
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1.text}")
# Second conversation - still no thread provided, will create another new thread
query2 = "What was the last city I asked about?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2.text}")
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
async def example_with_thread_persistence() -> None:
"""Example showing thread persistence across multiple conversations."""
print("=== Thread Persistence Example ===")
print("Using the same thread across multiple conversations to maintain context.\n")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
# Create a new thread that will be reused
thread = agent.get_new_thread()
# First conversation
query1 = "What's the weather like in Tokyo?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# Second conversation using the same thread - maintains context
query2 = "How about London?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2, thread=thread)
print(f"Agent: {result2.text}")
# Third conversation - agent should remember both previous cities
query3 = "Which of the cities I asked about has better weather?"
print(f"\nUser: {query3}")
result3 = await agent.run(query3, thread=thread)
print(f"Agent: {result3.text}")
print("Note: The agent remembers context from previous messages in the same thread.\n")
async def example_with_existing_thread_id() -> None:
"""Example showing how to work with an existing thread ID from the service."""
print("=== Existing Thread ID Example ===")
print("Using a specific thread ID to continue an existing conversation.\n")
# First, create a conversation and capture the thread ID
existing_thread_id = None
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with Agent(
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
# Start a conversation and get the thread ID
thread = agent.get_new_thread()
query1 = "What's the weather in Paris?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# The thread ID is set after the first response
existing_thread_id = thread.service_thread_id
print(f"Thread ID: {existing_thread_id}")
if existing_thread_id:
print("\n--- Continuing with the same thread ID in a new agent instance ---")
# Create a new agent instance but use the existing thread ID
async with Agent(
client=AzureOpenAIAssistantsClient(thread_id=existing_thread_id, credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
# Create a thread with the existing ID
thread = AgentThread(service_thread_id=existing_thread_id)
query2 = "What was the last city I asked about?"
print(f"User: {query2}")
result2 = await agent.run(query2, thread=thread)
print(f"Agent: {result2.text}")
print("Note: The agent continues the conversation from the previous thread.\n")
async def main() -> None:
print("=== Azure OpenAI Assistants Chat Client Agent Thread Management Examples ===\n")
await example_with_automatic_thread_creation()
await example_with_thread_persistence()
await example_with_existing_thread_id()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,79 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Chat Client Basic Example
This sample demonstrates basic usage of AzureOpenAIChatClient for direct chat-based
interactions, showing both streaming and non-streaming responses.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# Create agent with Azure Chat Client
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# Create agent with Azure Chat Client
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Portland?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Basic Azure Chat Client Agent Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,52 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Chat Client with Explicit Settings Example
This sample demonstrates creating Azure OpenAI Chat Client with explicit configuration
settings rather than relying on environment variable defaults.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
print("=== Azure Chat Client with Explicit Settings ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = AzureOpenAIChatClient(
deployment_name=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"],
endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
credential=AzureCliCredential(),
).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
result = await agent.run("What's the weather like in New York?")
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,139 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from datetime import datetime, timezone
from random import randint
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Chat Client with Function Tools Example
This sample demonstrates function tool integration with Azure OpenAI Chat Client,
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
@tool(approval_mode="never_require")
def get_time() -> str:
"""Get the current UTC time."""
current_time = datetime.now(timezone.utc)
return f"The current UTC time is {current_time.strftime('%Y-%m-%d %H:%M:%S')}."
async def tools_on_agent_level() -> None:
"""Example showing tools defined when creating the agent."""
print("=== Tools Defined on Agent Level ===")
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a helpful assistant that can provide weather and time information.",
tools=[get_weather, get_time], # Tools defined at agent creation
)
# First query - agent can use weather tool
query1 = "What's the weather like in New York?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}\n")
# Second query - agent can use time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
# Third query - agent can use both tools if needed
query3 = "What's the weather in London and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3)
print(f"Agent: {result3}\n")
async def tools_on_run_level() -> None:
"""Example showing tools passed to the run method."""
print("=== Tools Passed to Run Method ===")
# Agent created without tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a helpful assistant.",
# No tools defined here
)
# First query with weather tool
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1, tools=[get_weather]) # Tool passed to run method
print(f"Agent: {result1}\n")
# Second query with time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2, tools=[get_time]) # Different tool for this query
print(f"Agent: {result2}\n")
# Third query with multiple tools
query3 = "What's the weather in Chicago and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3, tools=[get_weather, get_time]) # Multiple tools
print(f"Agent: {result3}\n")
async def mixed_tools_example() -> None:
"""Example showing both agent-level tools and run-method tools."""
print("=== Mixed Tools Example (Agent + Run Method) ===")
# Agent created with some base tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a comprehensive assistant that can help with various information requests.",
tools=[get_weather], # Base tool available for all queries
)
# Query using both agent tool and additional run-method tools
query = "What's the weather in Denver and what's the current UTC time?"
print(f"User: {query}")
# Agent has access to get_weather (from creation) + additional tools from run method
result = await agent.run(
query,
tools=[get_time], # Additional tools for this specific query
)
print(f"Agent: {result}\n")
async def main() -> None:
print("=== Azure Chat Client Agent with Function Tools Examples ===\n")
await tools_on_agent_level()
await tools_on_run_level()
await mixed_tools_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,157 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import Agent, AgentThread, ChatMessageStore, tool
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Chat Client with Thread Management Example
This sample demonstrates thread management with Azure OpenAI Chat Client, comparing
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_thread_creation() -> None:
"""Example showing automatic thread creation (service-managed thread)."""
print("=== Automatic Thread Creation Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# First conversation - no thread provided, will be created automatically
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1.text}")
# Second conversation - still no thread provided, will create another new thread
query2 = "What was the last city I asked about?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2.text}")
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
async def example_with_thread_persistence() -> None:
"""Example showing thread persistence across multiple conversations."""
print("=== Thread Persistence Example ===")
print("Using the same thread across multiple conversations to maintain context.\n")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a new thread that will be reused
thread = agent.get_new_thread()
# First conversation
query1 = "What's the weather like in Tokyo?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# Second conversation using the same thread - maintains context
query2 = "How about London?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2, thread=thread)
print(f"Agent: {result2.text}")
# Third conversation - agent should remember both previous cities
query3 = "Which of the cities I asked about has better weather?"
print(f"\nUser: {query3}")
result3 = await agent.run(query3, thread=thread)
print(f"Agent: {result3.text}")
print("Note: The agent remembers context from previous messages in the same thread.\n")
async def example_with_existing_thread_messages() -> None:
"""Example showing how to work with existing thread messages for Azure."""
print("=== Existing Thread Messages Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Start a conversation and build up message history
thread = agent.get_new_thread()
query1 = "What's the weather in Paris?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# The thread now contains the conversation history in memory
if thread.message_store:
messages = await thread.message_store.list_messages()
print(f"Thread contains {len(messages or [])} messages")
print("\n--- Continuing with the same thread in a new agent instance ---")
# Create a new agent instance but use the existing thread with its message history
new_agent = Agent(
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Use the same thread object which contains the conversation history
query2 = "What was the last city I asked about?"
print(f"User: {query2}")
result2 = await new_agent.run(query2, thread=thread)
print(f"Agent: {result2.text}")
print("Note: The agent continues the conversation using the local message history.\n")
print("\n--- Alternative: Creating a new thread from existing messages ---")
# You can also create a new thread from existing messages
messages = await thread.message_store.list_messages() if thread.message_store else []
new_thread = AgentThread(message_store=ChatMessageStore(messages))
query3 = "How does the Paris weather compare to London?"
print(f"User: {query3}")
result3 = await new_agent.run(query3, thread=new_thread)
print(f"Agent: {result3.text}")
print("Note: This creates a new thread with the same conversation history.\n")
async def main() -> None:
print("=== Azure Chat Client Agent Thread Management Examples ===\n")
await example_with_automatic_thread_creation()
await example_with_thread_persistence()
await example_with_existing_thread_messages()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,77 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Responses Client Basic Example
This sample demonstrates basic usage of AzureOpenAIResponsesClient for structured
response generation, showing both streaming and non-streaming responses.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = AzureOpenAIResponsesClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = AzureOpenAIResponsesClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
query = "What's the weather like in Portland?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Basic Azure OpenAI Responses Client Agent Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,100 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
import tempfile
from agent_framework import Agent
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from openai import AsyncAzureOpenAI
"""
Azure OpenAI Responses Client with Code Interpreter and Files Example
This sample demonstrates using get_code_interpreter_tool() with Azure OpenAI Responses
for Python code execution and data analysis with uploaded files.
"""
# Helper functions
async def create_sample_file_and_upload(openai_client: AsyncAzureOpenAI) -> tuple[str, str]:
"""Create a sample CSV file and upload it to Azure OpenAI."""
csv_data = """name,department,salary,years_experience
Alice Johnson,Engineering,95000,5
Bob Smith,Sales,75000,3
Carol Williams,Engineering,105000,8
David Brown,Marketing,68000,2
Emma Davis,Sales,82000,4
Frank Wilson,Engineering,88000,6
"""
# Create temporary CSV file
with tempfile.NamedTemporaryFile(mode="w", suffix=".csv", delete=False) as temp_file:
temp_file.write(csv_data)
temp_file_path = temp_file.name
# Upload file to Azure OpenAI
print("Uploading file to Azure OpenAI...")
with open(temp_file_path, "rb") as file:
uploaded_file = await openai_client.files.create(
file=file,
purpose="assistants", # Required for code interpreter
)
print(f"File uploaded with ID: {uploaded_file.id}")
return temp_file_path, uploaded_file.id
async def cleanup_files(openai_client: AsyncAzureOpenAI, temp_file_path: str, file_id: str) -> None:
"""Clean up both local temporary file and uploaded file."""
# Clean up: delete the uploaded file
await openai_client.files.delete(file_id)
print(f"Cleaned up uploaded file: {file_id}")
# Clean up temporary local file
os.unlink(temp_file_path)
print(f"Cleaned up temporary file: {temp_file_path}")
async def main() -> None:
print("=== Azure OpenAI Code Interpreter with File Upload ===")
# Initialize Azure OpenAI client for file operations
credential = AzureCliCredential()
async def get_token():
token = credential.get_token("https://cognitiveservices.azure.com/.default")
return token.token
openai_client = AsyncAzureOpenAI(
azure_ad_token_provider=get_token,
api_version="2024-05-01-preview",
)
temp_file_path, file_id = await create_sample_file_and_upload(openai_client)
# Create agent using Azure OpenAI Responses client
client = AzureOpenAIResponsesClient(credential=credential)
# Create code interpreter tool with file access
code_interpreter_tool = client.get_code_interpreter_tool(file_ids=[file_id])
agent = Agent(
client=client,
instructions="You are a helpful assistant that can analyze data files using Python code.",
tools=[code_interpreter_tool],
)
# Test the code interpreter with the uploaded file
query = "Analyze the employee data in the uploaded CSV file. Calculate average salary by department."
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}")
await cleanup_files(openai_client, temp_file_path, file_id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,46 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Content, Message
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
"""
Azure OpenAI Responses Client with Image Analysis Example
This sample demonstrates using Azure OpenAI Responses for image analysis and vision tasks,
showing multi-modal messages combining text and image content.
"""
async def main():
print("=== Azure Responses Agent with Image Analysis ===")
# 1. Create an Azure Responses agent with vision capabilities
agent = AzureOpenAIResponsesClient(credential=AzureCliCredential()).as_agent(
name="VisionAgent",
instructions="You are a helpful agent that can analyze images.",
)
# 2. Create a simple message with both text and image content
user_message = Message(
role="user",
contents=[
Content.from_text("What do you see in this image?"),
Content.from_uri(
uri="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800",
media_type="image/jpeg",
),
],
)
# 3. Get the agent's response
print("User: What do you see in this image? [Image provided]")
result = await agent.run(user_message)
print(f"Agent: {result.text}")
print()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,53 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Agent, ChatResponse
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from openai.types.responses.response import Response as OpenAIResponse
from openai.types.responses.response_code_interpreter_tool_call import ResponseCodeInterpreterToolCall
"""
Azure OpenAI Responses Client with Code Interpreter Example
This sample demonstrates using get_code_interpreter_tool() with Azure OpenAI Responses
for Python code execution and mathematical problem solving.
"""
async def main() -> None:
"""Example showing how to use the code interpreter tool with Azure OpenAI Responses."""
print("=== Azure OpenAI Responses Agent with Code Interpreter Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
client = AzureOpenAIResponsesClient(credential=AzureCliCredential())
# Create code interpreter tool using instance method
code_interpreter_tool = client.get_code_interpreter_tool()
agent = Agent(
client=client,
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
tools=[code_interpreter_tool],
)
query = "Use code to calculate the factorial of 100?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
if (
isinstance(result.raw_representation, ChatResponse)
and isinstance(result.raw_representation.raw_representation, OpenAIResponse)
and len(result.raw_representation.raw_representation.output) > 0
and isinstance(result.raw_representation.raw_representation.output[0], ResponseCodeInterpreterToolCall)
):
generated_code = result.raw_representation.raw_representation.output[0].code
print(f"Generated code:\n{generated_code}")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,52 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Responses Client with Explicit Settings Example
This sample demonstrates creating Azure OpenAI Responses Client with explicit configuration
settings rather than relying on environment variable defaults.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production;
# see samples/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
print("=== Azure Responses Client with Explicit Settings ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = AzureOpenAIResponsesClient(
deployment_name=os.environ["AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME"],
endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
credential=AzureCliCredential(),
).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
result = await agent.run("What's the weather like in New York?")
print(f"Result: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,74 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Agent, Content
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
"""
Azure OpenAI Responses Client with File Search Example
This sample demonstrates using get_file_search_tool() with Azure OpenAI Responses Client
for direct document-based question answering and information retrieval.
Prerequisites:
- Set environment variables:
- AZURE_OPENAI_ENDPOINT: Your Azure OpenAI endpoint URL
- AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME: Your Responses API deployment name
- Authenticate via 'az login' for AzureCliCredential
"""
# Helper functions
async def create_vector_store(client: AzureOpenAIResponsesClient) -> tuple[str, Content]:
"""Create a vector store with sample documents."""
file = await client.client.files.create(
file=("todays_weather.txt", b"The weather today is sunny with a high of 75F."), purpose="assistants"
)
vector_store = await client.client.vector_stores.create(
name="knowledge_base",
expires_after={"anchor": "last_active_at", "days": 1},
)
result = await client.client.vector_stores.files.create_and_poll(vector_store_id=vector_store.id, file_id=file.id)
if result.last_error is not None:
raise Exception(f"Vector store file processing failed with status: {result.last_error.message}")
return file.id, Content.from_hosted_vector_store(vector_store_id=vector_store.id)
async def delete_vector_store(client: AzureOpenAIResponsesClient, file_id: str, vector_store_id: str) -> None:
"""Delete the vector store after using it."""
await client.client.vector_stores.delete(vector_store_id=vector_store_id)
await client.client.files.delete(file_id=file_id)
async def main() -> None:
print("=== Azure OpenAI Responses Client with File Search Example ===\n")
# Initialize Responses client
# Make sure you're logged in via 'az login' before running this sample
client = AzureOpenAIResponsesClient(credential=AzureCliCredential())
file_id, vector_store_id = await create_vector_store(client)
# Create file search tool using instance method
file_search_tool = client.get_file_search_tool(vector_store_ids=[vector_store_id])
agent = Agent(
client=client,
instructions="You are a helpful assistant that can search through files to find information.",
tools=[file_search_tool],
)
query = "What is the weather today? Do a file search to find the answer."
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
await delete_vector_store(client, file_id, vector_store_id)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,113 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
from pydantic import Field
"""
Azure OpenAI Responses Client with Foundry Project Example
This sample demonstrates how to create an AzureOpenAIResponsesClient using an
Azure AI Foundry project endpoint. Instead of providing an Azure OpenAI endpoint
directly, you provide a Foundry project endpoint and the client is created via
the Azure AI Foundry project SDK.
This requires:
- The `azure-ai-projects` package to be installed.
- The `AZURE_AI_PROJECT_ENDPOINT` environment variable set to your Foundry project endpoint.
- The `AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME` environment variable set to the model deployment name.
"""
load_dotenv() # Load environment variables from .env file if present
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
# 1. Create the AzureOpenAIResponsesClient using a Foundry project endpoint.
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
credential = AzureCliCredential()
agent = AzureOpenAIResponsesClient(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
deployment_name=os.environ["AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME"],
credential=credential,
).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# 2. Run a query and print the result.
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
# 1. Create the AzureOpenAIResponsesClient using a Foundry project endpoint.
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
credential = AzureCliCredential()
agent = AzureOpenAIResponsesClient(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
deployment_name=os.environ["AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME"],
credential=credential,
).as_agent(
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# 2. Stream the response and print each chunk as it arrives.
query = "What's the weather like in Portland?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Azure OpenAI Responses Client with Foundry Project Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
"""
Sample output:
=== Azure OpenAI Responses Client with Foundry Project Example ===
=== Non-streaming Response Example ===
User: What's the weather like in Seattle?
Result: The weather in Seattle is cloudy with a high of 18°C.
=== Streaming Response Example ===
User: What's the weather like in Portland?
Agent: The weather in Portland is sunny with a high of 25°C.
"""
@@ -0,0 +1,139 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from datetime import datetime, timezone
from random import randint
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Responses Client with Function Tools Example
This sample demonstrates function tool integration with Azure OpenAI Responses Client,
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
@tool(approval_mode="never_require")
def get_time() -> str:
"""Get the current UTC time."""
current_time = datetime.now(timezone.utc)
return f"The current UTC time is {current_time.strftime('%Y-%m-%d %H:%M:%S')}."
async def tools_on_agent_level() -> None:
"""Example showing tools defined when creating the agent."""
print("=== Tools Defined on Agent Level ===")
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a helpful assistant that can provide weather and time information.",
tools=[get_weather, get_time], # Tools defined at agent creation
)
# First query - agent can use weather tool
query1 = "What's the weather like in New York?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}\n")
# Second query - agent can use time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
# Third query - agent can use both tools if needed
query3 = "What's the weather in London and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3)
print(f"Agent: {result3}\n")
async def tools_on_run_level() -> None:
"""Example showing tools passed to the run method."""
print("=== Tools Passed to Run Method ===")
# Agent created without tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a helpful assistant.",
# No tools defined here
)
# First query with weather tool
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1, tools=[get_weather]) # Tool passed to run method
print(f"Agent: {result1}\n")
# Second query with time tool
query2 = "What's the current UTC time?"
print(f"User: {query2}")
result2 = await agent.run(query2, tools=[get_time]) # Different tool for this query
print(f"Agent: {result2}\n")
# Third query with multiple tools
query3 = "What's the weather in Chicago and what's the current UTC time?"
print(f"User: {query3}")
result3 = await agent.run(query3, tools=[get_weather, get_time]) # Multiple tools
print(f"Agent: {result3}\n")
async def mixed_tools_example() -> None:
"""Example showing both agent-level tools and run-method tools."""
print("=== Mixed Tools Example (Agent + Run Method) ===")
# Agent created with some base tools
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a comprehensive assistant that can help with various information requests.",
tools=[get_weather], # Base tool available for all queries
)
# Query using both agent tool and additional run-method tools
query = "What's the weather in Denver and what's the current UTC time?"
print(f"User: {query}")
# Agent has access to get_weather (from creation) + additional tools from run method
result = await agent.run(
query,
tools=[get_time], # Additional tools for this specific query
)
print(f"Agent: {result}\n")
async def main() -> None:
print("=== Azure OpenAI Responses Client Agent with Function Tools Examples ===\n")
await tools_on_agent_level()
await tools_on_run_level()
await mixed_tools_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,256 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import TYPE_CHECKING, Any
from agent_framework import Agent
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
"""
Azure OpenAI Responses Client with Hosted MCP Example
This sample demonstrates integrating hosted Model Context Protocol (MCP) tools with
Azure OpenAI Responses Client, including user approval workflows for function call security.
"""
if TYPE_CHECKING:
from agent_framework import AgentThread, SupportsAgentRun
async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun"):
"""When we don't have a thread, we need to ensure we return with the input, approval request and approval."""
from agent_framework import Message
result = await agent.run(query)
while len(result.user_input_requests) > 0:
new_inputs: list[Any] = [query]
for user_input_needed in result.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
new_inputs.append(Message(role="assistant", contents=[user_input_needed]))
user_approval = input("Approve function call? (y/n): ")
new_inputs.append(
Message(
role="user",
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
result = await agent.run(new_inputs)
return result
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
from agent_framework import Message
result = await agent.run(query, thread=thread, store=True)
while len(result.user_input_requests) > 0:
new_input: list[Any] = []
for user_input_needed in result.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
user_approval = input("Approve function call? (y/n): ")
new_input.append(
Message(
role="user",
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
result = await agent.run(new_input, thread=thread, store=True)
return result
async def handle_approvals_with_thread_streaming(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
from agent_framework import Message
new_input: list[Message] = []
new_input_added = True
while new_input_added:
new_input_added = False
new_input.append(Message(role="user", text=query))
async for update in agent.run(new_input, thread=thread, options={"store": True}, stream=True):
if update.user_input_requests:
for user_input_needed in update.user_input_requests:
print(
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
f" with arguments: {user_input_needed.function_call.arguments}"
)
user_approval = input("Approve function call? (y/n): ")
new_input.append(
Message(
role="user",
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
new_input_added = True
else:
yield update
async def run_hosted_mcp_without_thread_and_specific_approval() -> None:
"""Example showing Mcp Tools with approvals without using a thread."""
print("=== Mcp with approvals and without thread ===")
credential = AzureCliCredential()
client = AzureOpenAIResponsesClient(credential=credential)
# Create MCP tool with specific approval settings
mcp_tool = client.get_mcp_tool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
# we don't require approval for microsoft_docs_search tool calls
# but we do for any other tool
approval_mode={"never_require_approval": ["microsoft_docs_search"]},
)
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
async with Agent(
client=client,
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=[mcp_tool],
) as agent:
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await handle_approvals_without_thread(query1, agent)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
result2 = await handle_approvals_without_thread(query2, agent)
print(f"{agent.name}: {result2}\n")
async def run_hosted_mcp_without_approval() -> None:
"""Example showing Mcp Tools without approvals."""
print("=== Mcp without approvals ===")
credential = AzureCliCredential()
client = AzureOpenAIResponsesClient(credential=credential)
# Create MCP tool without approval requirements
mcp_tool = client.get_mcp_tool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
# we don't require approval for any function calls
# this means we will not see the approval messages,
# it is fully handled by the service and a final response is returned.
approval_mode="never_require",
)
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
async with Agent(
client=client,
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=[mcp_tool],
) as agent:
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await handle_approvals_without_thread(query1, agent)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
result2 = await handle_approvals_without_thread(query2, agent)
print(f"{agent.name}: {result2}\n")
async def run_hosted_mcp_with_thread() -> None:
"""Example showing Mcp Tools with approvals using a thread."""
print("=== Mcp with approvals and with thread ===")
credential = AzureCliCredential()
client = AzureOpenAIResponsesClient(credential=credential)
# Create MCP tool with always require approval
mcp_tool = client.get_mcp_tool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
# we require approval for all function calls
approval_mode="always_require",
)
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
async with Agent(
client=client,
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=[mcp_tool],
) as agent:
# First query
thread = agent.get_new_thread()
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await handle_approvals_with_thread(query1, agent, thread)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
result2 = await handle_approvals_with_thread(query2, agent, thread)
print(f"{agent.name}: {result2}\n")
async def run_hosted_mcp_with_thread_streaming() -> None:
"""Example showing Mcp Tools with approvals using a thread."""
print("=== Mcp with approvals and with thread ===")
credential = AzureCliCredential()
client = AzureOpenAIResponsesClient(credential=credential)
# Create MCP tool with always require approval
mcp_tool = client.get_mcp_tool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
# we require approval for all function calls
approval_mode="always_require",
)
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
async with Agent(
client=client,
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=[mcp_tool],
) as agent:
# First query
thread = agent.get_new_thread()
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
print(f"{agent.name}: ", end="")
async for update in handle_approvals_with_thread_streaming(query1, agent, thread):
print(update, end="")
print("\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Agent Framework?"
print(f"User: {query2}")
print(f"{agent.name}: ", end="")
async for update in handle_approvals_with_thread_streaming(query2, agent, thread):
print(update, end="")
print("\n")
async def main() -> None:
print("=== OpenAI Responses Client Agent with Hosted Mcp Tools Examples ===\n")
await run_hosted_mcp_without_approval()
await run_hosted_mcp_without_thread_and_specific_approval()
await run_hosted_mcp_with_thread()
await run_hosted_mcp_with_thread_streaming()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,62 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
"""
Azure OpenAI Responses Client with local Model Context Protocol (MCP) Example
This sample demonstrates integration of Azure OpenAI Responses Client with local Model Context Protocol (MCP)
servers.
"""
# --- Below code uses Microsoft Learn MCP server over Streamable HTTP ---
# --- Users can set these environment variables, or just edit the values below to their desired local MCP server
MCP_NAME = os.environ.get("MCP_NAME", "Microsoft Learn MCP") # example name
MCP_URL = os.environ.get("MCP_URL", "https://learn.microsoft.com/api/mcp") # example endpoint
# Environment variables for Azure OpenAI Responses authentication
# AZURE_OPENAI_ENDPOINT="<your-azure openai-endpoint>"
# AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME="<your-deployment-name>"
# AZURE_OPENAI_API_VERSION="<your-api-version>" # e.g. "2025-03-01-preview"
async def main():
"""Example showing local MCP tools for a Azure OpenAI Responses Agent."""
# AuthN: use Azure CLI
credential = AzureCliCredential()
# Build an agent backed by Azure OpenAI Responses
# (endpoint/deployment/api_version can also come from env vars above)
responses_client = AzureOpenAIResponsesClient(
credential=credential,
)
agent: Agent = responses_client.as_agent(
name="DocsAgent",
instructions=("You are a helpful assistant that can help with Microsoft documentation questions."),
)
# Connect to the MCP server (Streamable HTTP)
async with MCPStreamableHTTPTool(
name=MCP_NAME,
url=MCP_URL,
) as mcp_tool:
# First query — expect the agent to use the MCP tool if it helps
first_query = "How to create an Azure storage account using az cli?"
first_response = await agent.run(first_query, tools=mcp_tool)
print("\n=== Answer 1 ===\n", first_response.text)
# Follow-up query (connection is reused)
second_query = "What is Microsoft Agent Framework?"
second_response = await agent.run(second_query, tools=mcp_tool)
print("\n=== Answer 2 ===\n", second_response.text)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,155 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import Agent, AgentThread, tool
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure OpenAI Responses Client with Thread Management Example
This sample demonstrates thread management with Azure OpenAI Responses Client, comparing
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/02-agents/tools/function_tool_with_approval.py
# and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_thread_creation() -> None:
"""Example showing automatic thread creation."""
print("=== Automatic Thread Creation Example ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# First conversation - no thread provided, will be created automatically
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1.text}")
# Second conversation - still no thread provided, will create another new thread
query2 = "What was the last city I asked about?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2.text}")
print("Note: Each call creates a separate thread, so the agent doesn't remember previous context.\n")
async def example_with_thread_persistence_in_memory() -> None:
"""
Example showing thread persistence across multiple conversations.
In this example, messages are stored in-memory.
"""
print("=== Thread Persistence Example (In-Memory) ===")
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a new thread that will be reused
thread = agent.get_new_thread()
# First conversation
query1 = "What's the weather like in Tokyo?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1.text}")
# Second conversation using the same thread - maintains context
query2 = "How about London?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2, thread=thread)
print(f"Agent: {result2.text}")
# Third conversation - agent should remember both previous cities
query3 = "Which of the cities I asked about has better weather?"
print(f"\nUser: {query3}")
result3 = await agent.run(query3, thread=thread)
print(f"Agent: {result3.text}")
print("Note: The agent remembers context from previous messages in the same thread.\n")
async def example_with_existing_thread_id() -> None:
"""
Example showing how to work with an existing thread ID from the service.
In this example, messages are stored on the server using Azure OpenAI conversation state.
"""
print("=== Existing Thread ID Example ===")
# First, create a conversation and capture the thread ID
existing_thread_id = None
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Start a conversation and get the thread ID
thread = agent.get_new_thread()
query1 = "What's the weather in Paris?"
print(f"User: {query1}")
# Enable Azure OpenAI conversation state by setting `store` parameter to True
result1 = await agent.run(query1, thread=thread, store=True)
print(f"Agent: {result1.text}")
# The thread ID is set after the first response
existing_thread_id = thread.service_thread_id
print(f"Thread ID: {existing_thread_id}")
if existing_thread_id:
print("\n--- Continuing with the same thread ID in a new agent instance ---")
agent = Agent(
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
instructions="You are a helpful weather agent.",
tools=get_weather,
)
# Create a thread with the existing ID
thread = AgentThread(service_thread_id=existing_thread_id)
query2 = "What was the last city I asked about?"
print(f"User: {query2}")
result2 = await agent.run(query2, thread=thread, store=True)
print(f"Agent: {result2.text}")
print("Note: The agent continues the conversation from the previous thread by using thread ID.\n")
async def main() -> None:
print("=== Azure OpenAI Response Client Agent Thread Management Examples ===\n")
await example_with_automatic_thread_creation()
await example_with_thread_persistence_in_memory()
await example_with_existing_thread_id()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,105 @@
# Copilot Studio Agent Examples
This folder contains examples demonstrating how to create and use agents with Microsoft Copilot Studio using the Agent Framework.
## Prerequisites
Before running these examples, you need:
1. **Copilot Studio Environment**: Access to a Microsoft Copilot Studio environment with a published copilot
2. **App Registration**: An Azure AD App Registration with appropriate permissions
3. **Environment Variables**: Set the following environment variables:
- `COPILOTSTUDIOAGENT__ENVIRONMENTID` - Your Copilot Studio environment ID
- `COPILOTSTUDIOAGENT__SCHEMANAME` - Your copilot's agent identifier/schema name
- `COPILOTSTUDIOAGENT__AGENTAPPID` - Your App Registration client ID
- `COPILOTSTUDIOAGENT__TENANTID` - Your Azure AD tenant ID
## Examples
| Example | Description |
|---------|-------------|
| **[`copilotstudio_basic.py`](copilotstudio_basic.py)** | Basic non-streaming and streaming execution with simple questions |
| **[`copilotstudio_with_explicit_settings.py`](copilotstudio_with_explicit_settings.py)** | Example with explicit settings and manual token acquisition |
## Authentication
The examples use MSAL (Microsoft Authentication Library) for authentication. The first time you run an example, you may need to complete an interactive authentication flow in your browser.
### App Registration Setup
Your Azure AD App Registration should have:
1. **API Permissions**:
- Power Platform API permissions (https://api.powerplatform.com/.default)
- Appropriate delegated permissions for your organization
2. **Redirect URIs**:
- For public client flows: `http://localhost`
- Configure as appropriate for your authentication method
3. **Authentication**:
- Enable "Allow public client flows" if using interactive authentication
## Usage Patterns
### Basic Usage with Environment Variables
```python
import asyncio
from agent_framework.microsoft import CopilotStudioAgent
# Uses environment variables for configuration
async def main():
# Create agent using environment variables
agent = CopilotStudioAgent()
# Run a simple query
result = await agent.run("What is the capital of France?")
print(result)
asyncio.run(main())
```
### Explicit Configuration
```python
from agent_framework.microsoft import CopilotStudioAgent, acquire_token
from microsoft_agents.copilotstudio.client import ConnectionSettings, CopilotClient, PowerPlatformCloud, AgentType
# Acquire token manually
token = acquire_token(
client_id="your-client-id",
tenant_id="your-tenant-id"
)
# Create settings and client
settings = ConnectionSettings(
environment_id="your-environment-id",
agent_identifier="your-agent-schema-name",
cloud=PowerPlatformCloud.PROD,
copilot_agent_type=AgentType.PUBLISHED,
custom_power_platform_cloud=None
)
client = CopilotClient(settings=settings, token=token)
agent = CopilotStudioAgent(client=client)
```
## Troubleshooting
### Common Issues
1. **Authentication Errors**:
- Verify your App Registration has correct permissions
- Ensure environment variables are set correctly
- Check that your tenant ID and client ID are valid
2. **Environment/Agent Not Found**:
- Verify your environment ID is correct
- Ensure your copilot is published and the schema name is correct
- Check that you have access to the specified environment
3. **Token Acquisition Failures**:
- Interactive authentication may require browser access
- Corporate firewalls may block authentication flows
- Try running with appropriate proxy settings if needed
@@ -0,0 +1,54 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.microsoft import CopilotStudioAgent
"""
Copilot Studio Agent Basic Example
This sample demonstrates basic usage of CopilotStudioAgent with automatic configuration
from environment variables, showing both streaming and non-streaming responses.
"""
# Environment variables needed:
# COPILOTSTUDIOAGENT__ENVIRONMENTID - Environment ID where your copilot is deployed
# COPILOTSTUDIOAGENT__SCHEMANAME - Agent identifier/schema name of your copilot
# COPILOTSTUDIOAGENT__AGENTAPPID - Client ID for authentication
# COPILOTSTUDIOAGENT__TENANTID - Tenant ID for authentication
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
agent = CopilotStudioAgent()
query = "What is the capital of France?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
agent = CopilotStudioAgent()
query = "What is the capital of Spain?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,103 @@
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "microsoft-agents",
# ]
# ///
# Run with any PEP 723 compatible runner, e.g.:
# uv run samples/getting_started/agents/copilotstudio/copilotstudio_with_explicit_settings.py
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from agent_framework.microsoft import CopilotStudioAgent, acquire_token
from microsoft_agents.copilotstudio.client import AgentType, ConnectionSettings, CopilotClient, PowerPlatformCloud
"""
Copilot Studio Agent with Explicit Settings Example
This sample demonstrates explicit configuration of CopilotStudioAgent with manual
token management and custom ConnectionSettings for production environments.
"""
# Environment variables needed:
# COPILOTSTUDIOAGENT__ENVIRONMENTID - Environment ID where your copilot is deployed
# COPILOTSTUDIOAGENT__SCHEMANAME - Agent identifier/schema name of your copilot
# COPILOTSTUDIOAGENT__AGENTAPPID - Client ID for authentication
# COPILOTSTUDIOAGENT__TENANTID - Tenant ID for authentication
async def example_with_connection_settings() -> None:
"""Example using explicit ConnectionSettings and CopilotClient."""
print("=== Copilot Studio Agent with Connection Settings ===")
# Configuration from environment variables
environment_id = os.environ["COPILOTSTUDIOAGENT__ENVIRONMENTID"]
agent_identifier = os.environ["COPILOTSTUDIOAGENT__SCHEMANAME"]
client_id = os.environ["COPILOTSTUDIOAGENT__AGENTAPPID"]
tenant_id = os.environ["COPILOTSTUDIOAGENT__TENANTID"]
# Acquire token using the acquire_token function
token = acquire_token(
client_id=client_id,
tenant_id=tenant_id,
)
# Create connection settings
settings = ConnectionSettings(
environment_id=environment_id,
agent_identifier=agent_identifier,
cloud=PowerPlatformCloud.PROD, # Or PowerPlatformCloud.GOV, PowerPlatformCloud.HIGH, etc.
copilot_agent_type=AgentType.PUBLISHED, # Or AgentType.PREBUILT
custom_power_platform_cloud=None, # Optional: for custom cloud endpoints
)
# Create CopilotClient with explicit settings
client = CopilotClient(settings=settings, token=token)
# Create agent with explicit client
agent = CopilotStudioAgent(client=client)
# Run a simple query
query = "What is the capital of Italy?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}")
async def example_with_explicit_parameters() -> None:
"""Example using CopilotStudioAgent with all parameters explicitly provided."""
print("\n=== Copilot Studio Agent with All Explicit Parameters ===")
# Configuration from environment variables
environment_id = os.environ["COPILOTSTUDIOAGENT__ENVIRONMENTID"]
agent_identifier = os.environ["COPILOTSTUDIOAGENT__SCHEMANAME"]
client_id = os.environ["COPILOTSTUDIOAGENT__AGENTAPPID"]
tenant_id = os.environ["COPILOTSTUDIOAGENT__TENANTID"]
# Create agent with all parameters explicitly
agent = CopilotStudioAgent(
environment_id=environment_id,
agent_identifier=agent_identifier,
client_id=client_id,
tenant_id=tenant_id,
cloud=PowerPlatformCloud.PROD,
agent_type=AgentType.PUBLISHED,
)
# Run a simple query
query = "What is the capital of Japan?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}")
async def main() -> None:
await example_with_connection_settings()
await example_with_explicit_parameters()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,69 @@
# Custom Agent and Chat Client Examples
This folder contains examples demonstrating how to implement custom agents and chat clients using the Microsoft Agent Framework.
## Examples
| File | Description |
|------|-------------|
| [`custom_agent.py`](custom_agent.py) | Shows how to create custom agents by extending the `BaseAgent` class. Demonstrates the `EchoAgent` implementation with both streaming and non-streaming responses, proper thread management, and message history handling. |
| [`custom_chat_client.py`](../../chat_client/custom_chat_client.py) | Demonstrates how to create custom chat clients by extending the `BaseChatClient` class. Shows a `EchoingChatClient` implementation and how to integrate it with `Agent` using the `as_agent()` method. |
## Key Takeaways
### Custom Agents
- Custom agents give you complete control over the agent's behavior
- You must implement both `run()` for both the `stream=True` and `stream=False` cases
- Use `self._normalize_messages()` to handle different input message formats
- Use `self._notify_thread_of_new_messages()` to properly manage conversation history
### Custom Chat Clients
- Custom chat clients allow you to integrate any backend service or create new LLM providers
- You must implement `_inner_get_response()` with a stream parameter to handle both streaming and non-streaming responses
- Custom chat clients can be used with `Agent` to leverage all agent framework features
- Use the `as_agent()` method to easily create agents from your custom chat clients
Both approaches allow you to extend the framework for your specific use cases while maintaining compatibility with the broader Agent Framework ecosystem.
## Understanding Raw Client Classes
The framework provides `Raw...Client` classes (e.g., `RawOpenAIChatClient`, `RawOpenAIResponsesClient`, `RawAzureAIClient`) that are intermediate implementations without middleware, telemetry, or function invocation support.
### Warning: Raw Clients Should Not Normally Be Used Directly
**The `Raw...Client` classes should not normally be used directly.** They do not include the middleware, telemetry, or function invocation support that you most likely need. If you do use them, you should carefully consider which additional layers to apply.
### Layer Ordering
There is a defined ordering for applying layers that you should follow:
1. **ChatMiddlewareLayer** - Should be applied **first** because it also prepares function middleware
2. **FunctionInvocationLayer** - Handles tool/function calling loop
3. **ChatTelemetryLayer** - Must be **inside** the function calling loop for correct per-call telemetry
4. **Raw...Client** - The base implementation (e.g., `RawOpenAIChatClient`)
Example of correct layer composition:
```python
class MyCustomClient(
ChatMiddlewareLayer[TOptions],
FunctionInvocationLayer[TOptions],
ChatTelemetryLayer[TOptions],
RawOpenAIChatClient[TOptions], # or BaseChatClient for custom implementations
Generic[TOptions],
):
"""Custom client with all layers correctly applied."""
pass
```
### Use Fully-Featured Clients Instead
For most use cases, use the fully-featured public client classes which already have all layers correctly composed:
- `OpenAIChatClient` - OpenAI Chat completions with all layers
- `OpenAIResponsesClient` - OpenAI Responses API with all layers
- `AzureOpenAIChatClient` - Azure OpenAI Chat with all layers
- `AzureOpenAIResponsesClient` - Azure OpenAI Responses with all layers
- `AzureAIClient` - Azure AI Project with all layers
These clients handle the layer composition correctly and provide the full feature set out of the box.
@@ -0,0 +1,206 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from collections.abc import AsyncIterable
from typing import Any
from agent_framework import (
AgentResponse,
AgentResponseUpdate,
AgentThread,
BaseAgent,
Content,
Message,
Role,
normalize_messages,
)
"""
Custom Agent Implementation Example
This sample demonstrates implementing a custom agent by extending BaseAgent class,
showing the minimal requirements for both streaming and non-streaming responses.
"""
class EchoAgent(BaseAgent):
"""A simple custom agent that echoes user messages with a prefix.
This demonstrates how to create a fully custom agent by extending BaseAgent
and implementing the required run() method with stream support.
"""
echo_prefix: str = "Echo: "
def __init__(
self,
*,
name: str | None = None,
description: str | None = None,
echo_prefix: str = "Echo: ",
**kwargs: Any,
) -> None:
"""Initialize the EchoAgent.
Args:
name: The name of the agent.
description: The description of the agent.
echo_prefix: The prefix to add to echoed messages.
**kwargs: Additional keyword arguments passed to BaseAgent.
"""
super().__init__(
name=name,
description=description,
echo_prefix=echo_prefix, # type: ignore
**kwargs,
)
def run(
self,
messages: str | Message | list[str] | list[Message] | None = None,
*,
stream: bool = False,
thread: AgentThread | None = None,
**kwargs: Any,
) -> "AsyncIterable[AgentResponseUpdate] | asyncio.Future[AgentResponse]":
"""Execute the agent and return a response.
Args:
messages: The message(s) to process.
stream: If True, return an async iterable of updates. If False, return an awaitable response.
thread: The conversation thread (optional).
**kwargs: Additional keyword arguments.
Returns:
When stream=False: An awaitable AgentResponse containing the agent's reply.
When stream=True: An async iterable of AgentResponseUpdate objects.
"""
if stream:
return self._run_stream(messages=messages, thread=thread, **kwargs)
return self._run(messages=messages, thread=thread, **kwargs)
async def _run(
self,
messages: str | Message | list[str] | list[Message] | None = None,
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AgentResponse:
"""Non-streaming implementation."""
# Normalize input messages to a list
normalized_messages = normalize_messages(messages)
if not normalized_messages:
response_message = Message(
role=Role.ASSISTANT,
contents=[Content.from_text(text="Hello! I'm a custom echo agent. Send me a message and I'll echo it back.")],
)
else:
# For simplicity, echo the last user message
last_message = normalized_messages[-1]
if last_message.text:
echo_text = f"{self.echo_prefix}{last_message.text}"
else:
echo_text = f"{self.echo_prefix}[Non-text message received]"
response_message = Message(role=Role.ASSISTANT, contents=[Content.from_text(text=echo_text)])
# Notify the thread of new messages if provided
if thread is not None:
await self._notify_thread_of_new_messages(thread, normalized_messages, response_message)
return AgentResponse(messages=[response_message])
async def _run_stream(
self,
messages: str | Message | list[str] | list[Message] | None = None,
*,
thread: AgentThread | None = None,
**kwargs: Any,
) -> AsyncIterable[AgentResponseUpdate]:
"""Streaming implementation."""
# Normalize input messages to a list
normalized_messages = normalize_messages(messages)
if not normalized_messages:
response_text = "Hello! I'm a custom echo agent. Send me a message and I'll echo it back."
else:
# For simplicity, echo the last user message
last_message = normalized_messages[-1]
if last_message.text:
response_text = f"{self.echo_prefix}{last_message.text}"
else:
response_text = f"{self.echo_prefix}[Non-text message received]"
# Simulate streaming by yielding the response word by word
words = response_text.split()
for i, word in enumerate(words):
# Add space before word except for the first one
chunk_text = f" {word}" if i > 0 else word
yield AgentResponseUpdate(
contents=[Content.from_text(text=chunk_text)],
role=Role.ASSISTANT,
)
# Small delay to simulate streaming
await asyncio.sleep(0.1)
# Notify the thread of the complete response if provided
if thread is not None:
complete_response = Message(role=Role.ASSISTANT, contents=[Content.from_text(text=response_text)])
await self._notify_thread_of_new_messages(thread, normalized_messages, complete_response)
async def main() -> None:
"""Demonstrates how to use the custom EchoAgent."""
print("=== Custom Agent Example ===\n")
# Create EchoAgent
print("--- EchoAgent Example ---")
echo_agent = EchoAgent(
name="EchoBot", description="A simple agent that echoes messages with a prefix", echo_prefix="🔊 Echo: "
)
# Test non-streaming
print(f"Agent Name: {echo_agent.name}")
print(f"Agent ID: {echo_agent.id}")
query = "Hello, custom agent!"
print(f"\nUser: {query}")
result = await echo_agent.run(query)
print(f"Agent: {result.messages[0].text}")
# Test streaming
query2 = "This is a streaming test"
print(f"\nUser: {query2}")
print("Agent: ", end="", flush=True)
async for chunk in echo_agent.run(query2, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print()
# Example with threads
print("\n--- Using Custom Agent with Thread ---")
thread = echo_agent.get_new_thread()
# First message
result1 = await echo_agent.run("First message", thread=thread)
print("User: First message")
print(f"Agent: {result1.messages[0].text}")
# Second message in same thread
result2 = await echo_agent.run("Second message", thread=thread)
print("User: Second message")
print(f"Agent: {result2.messages[0].text}")
# Check conversation history
if thread.message_store:
messages = await thread.message_store.list_messages()
print(f"\nThread contains {len(messages)} messages in history")
else:
print("\nThread has no message store configured")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,37 @@
# GitHub Copilot Agent Examples
This directory contains examples demonstrating how to use the `GitHubCopilotAgent` from the Microsoft Agent Framework.
> **Security Note**: These examples demonstrate various permission types (shell, read, write, url). Only enable permissions that are necessary for your use case. Each permission grants the agent additional capabilities that could affect your system.
## Prerequisites
1. **GitHub Copilot CLI**: Install and authenticate the Copilot CLI
2. **GitHub Copilot Subscription**: An active GitHub Copilot subscription
3. **Install the package**:
```bash
pip install agent-framework-github-copilot --pre
```
## Environment Variables
The following environment variables can be configured:
| Variable | Description | Default |
|----------|-------------|---------|
| `GITHUB_COPILOT_CLI_PATH` | Path to the Copilot CLI executable | `copilot` |
| `GITHUB_COPILOT_MODEL` | Model to use (e.g., "gpt-5", "claude-sonnet-4") | Server default |
| `GITHUB_COPILOT_TIMEOUT` | Request timeout in seconds | `60` |
| `GITHUB_COPILOT_LOG_LEVEL` | CLI log level | `info` |
## Examples
| File | Description |
|------|-------------|
| [`github_copilot_basic.py`](github_copilot_basic.py) | The simplest way to create an agent using `GitHubCopilotAgent`. Demonstrates both streaming and non-streaming responses with function tools. |
| [`github_copilot_with_session.py`](github_copilot_with_session.py) | Shows session management with automatic creation, persistence via thread objects, and resuming sessions by ID. |
| [`github_copilot_with_shell.py`](github_copilot_with_shell.py) | Shows how to enable shell command execution permissions. Demonstrates running system commands like listing files and getting system information. |
| [`github_copilot_with_file_operations.py`](github_copilot_with_file_operations.py) | Shows how to enable file read and write permissions. Demonstrates reading file contents and creating new files. |
| [`github_copilot_with_url.py`](github_copilot_with_url.py) | Shows how to enable URL fetching permissions. Demonstrates fetching and processing web content. |
| [`github_copilot_with_mcp.py`](github_copilot_with_mcp.py) | Shows how to configure MCP (Model Context Protocol) servers, including local (stdio) and remote (HTTP) servers. |
| [`github_copilot_with_multiple_permissions.py`](github_copilot_with_multiple_permissions.py) | Shows how to combine multiple permission types for complex tasks that require shell, read, and write access. |
@@ -0,0 +1,113 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent Basic Example
This sample demonstrates basic usage of GitHubCopilotAgent.
Shows both streaming and non-streaming responses with function tools.
Environment variables (optional):
- GITHUB_COPILOT_CLI_PATH - Path to the Copilot CLI executable
- GITHUB_COPILOT_MODEL - Model to use (e.g., "gpt-5", "claude-sonnet-4")
- GITHUB_COPILOT_TIMEOUT - Request timeout in seconds
- GITHUB_COPILOT_LOG_LEVEL - CLI log level
"""
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.github import GitHubCopilotAgent
from pydantic import Field
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}C."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
agent = GitHubCopilotAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent:
query = "What's the weather like in Seattle?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
agent = GitHubCopilotAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent:
query = "What's the weather like in Tokyo?"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def runtime_options_example() -> None:
"""Example of overriding system message at runtime."""
print("=== Runtime Options Example ===")
agent = GitHubCopilotAgent(
instructions="Always respond in exactly 3 words.",
tools=[get_weather],
)
async with agent:
query = "What's the weather like in Paris?"
# First call uses default instructions (3 words response)
print("Using default instructions (3 words):")
print(f"User: {query}")
result1 = await agent.run(query)
print(f"Agent: {result1}\n")
# Second call overrides with runtime system_message in replace mode
print("Using runtime system_message with replace mode (detailed response):")
print(f"User: {query}")
result2 = await agent.run(
query,
options={
"system_message": {
"mode": "replace",
"content": "You are a weather expert. Provide detailed weather information "
"with temperature, and recommendations.",
}
},
)
print(f"Agent: {result2}\n")
async def main() -> None:
print("=== Basic GitHub Copilot Agent Example ===")
await non_streaming_example()
await streaming_example()
await runtime_options_example()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,51 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent with File Operation Permissions
This sample demonstrates how to enable file read and write operations with GitHubCopilotAgent.
By providing a permission handler that approves "read" and/or "write" requests, the agent can
read from and write to files on the filesystem.
SECURITY NOTE: Only enable file permissions when you trust the agent's actions.
- "read" allows the agent to read any accessible file
- "write" allows the agent to create or modify files
"""
import asyncio
from agent_framework.github import GitHubCopilotAgent
from copilot.types import PermissionRequest, PermissionRequestResult
def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> PermissionRequestResult:
"""Permission handler that prompts the user for approval."""
kind = request.get("kind", "unknown")
print(f"\n[Permission Request: {kind}]")
if "path" in request:
print(f" Path: {request.get('path')}")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionRequestResult(kind="approved")
return PermissionRequestResult(kind="denied-interactively-by-user")
async def main() -> None:
print("=== GitHub Copilot Agent with File Operation Permissions ===\n")
agent = GitHubCopilotAgent(
instructions="You are a helpful assistant that can read and write files.",
default_options={"on_permission_request": prompt_permission},
)
async with agent:
query = "Read the contents of README.md and summarize it"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,75 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent with MCP Servers
This sample demonstrates how to configure MCP (Model Context Protocol) servers
with GitHubCopilotAgent. It shows both local (stdio) and remote (HTTP) server
configurations, giving the agent access to external tools and data sources.
SECURITY NOTE: MCP servers can expose powerful capabilities. Only configure
servers you trust. The permission handler below prompts the user for approval
of MCP-related actions.
"""
import asyncio
from agent_framework.github import GitHubCopilotAgent
from copilot.types import MCPServerConfig, PermissionRequest, PermissionRequestResult
def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> PermissionRequestResult:
"""Permission handler that prompts the user for approval."""
kind = request.get("kind", "unknown")
print(f"\n[Permission Request: {kind}]")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionRequestResult(kind="approved")
return PermissionRequestResult(kind="denied-interactively-by-user")
async def main() -> None:
print("=== GitHub Copilot Agent with MCP Servers ===\n")
# Configure both local and remote MCP servers
mcp_servers: dict[str, MCPServerConfig] = {
# Local stdio server: provides filesystem access tools
"filesystem": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"tools": ["*"],
},
# Remote HTTP server: Microsoft Learn documentation
"microsoft-learn": {
"type": "http",
"url": "https://learn.microsoft.com/api/mcp",
"tools": ["*"],
},
}
agent = GitHubCopilotAgent(
instructions="You are a helpful assistant with access to the local filesystem and Microsoft Learn.",
default_options={
"on_permission_request": prompt_permission,
"mcp_servers": mcp_servers,
},
)
async with agent:
# Query that exercises the local filesystem MCP server
query1 = "List the files in the current directory"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}\n")
# Query that exercises the remote Microsoft Learn MCP server
query2 = "Search Microsoft Learn for 'Azure Functions Python' and summarize the top result"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,59 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent with Multiple Permissions
This sample demonstrates how to enable multiple permission types with GitHubCopilotAgent.
By combining different permission kinds in the handler, the agent can perform complex tasks
that require multiple capabilities.
Available permission kinds:
- "shell": Execute shell commands
- "read": Read files from the filesystem
- "write": Write files to the filesystem
- "mcp": Use MCP (Model Context Protocol) servers
- "url": Fetch content from URLs
SECURITY NOTE: Only enable permissions that are necessary for your use case.
More permissions mean more potential for unintended actions.
"""
import asyncio
from agent_framework.github import GitHubCopilotAgent
from copilot.types import PermissionRequest, PermissionRequestResult
def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> PermissionRequestResult:
"""Permission handler that prompts the user for approval."""
kind = request.get("kind", "unknown")
print(f"\n[Permission Request: {kind}]")
if "command" in request:
print(f" Command: {request.get('command')}")
if "path" in request:
print(f" Path: {request.get('path')}")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionRequestResult(kind="approved")
return PermissionRequestResult(kind="denied-interactively-by-user")
async def main() -> None:
print("=== GitHub Copilot Agent with Multiple Permissions ===\n")
agent = GitHubCopilotAgent(
instructions="You are a helpful development assistant that can read, write files and run commands.",
default_options={"on_permission_request": prompt_permission},
)
async with agent:
query = "List the first 3 Python files, then read the first one and create a summary in summary.txt"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,140 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent with Session Management
This sample demonstrates session management with GitHubCopilotAgent, showing
persistent conversation capabilities. Sessions are automatically persisted
server-side by the Copilot CLI.
"""
import asyncio
from random import randint
from typing import Annotated
from agent_framework import tool
from agent_framework.github import GitHubCopilotAgent
from pydantic import Field
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/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.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def example_with_automatic_session_creation() -> None:
"""Each run() without thread creates a new session."""
print("=== Automatic Session Creation Example ===")
agent = GitHubCopilotAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent:
# First query - creates a new session
query1 = "What's the weather like in Seattle?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"Agent: {result1}")
# Second query - without thread, creates another new session
query2 = "What was the last city I asked about?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2)
print(f"Agent: {result2}")
print("Note: Each call creates a separate session, so the agent doesn't remember previous context.\n")
async def example_with_session_persistence() -> None:
"""Reuse session via thread object for multi-turn conversations."""
print("=== Session Persistence Example ===")
agent = GitHubCopilotAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent:
# Create a thread to maintain conversation context
thread = agent.get_new_thread()
# First query
query1 = "What's the weather like in Tokyo?"
print(f"User: {query1}")
result1 = await agent.run(query1, thread=thread)
print(f"Agent: {result1}")
# Second query - using same thread maintains context
query2 = "How about London?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2, thread=thread)
print(f"Agent: {result2}")
# Third query - agent should remember both previous cities
query3 = "Which of the cities I asked about has better weather?"
print(f"\nUser: {query3}")
result3 = await agent.run(query3, thread=thread)
print(f"Agent: {result3}")
print("Note: The agent remembers context from previous messages in the same session.\n")
async def example_with_existing_session_id() -> None:
"""Resume session in new agent instance using service_thread_id."""
print("=== Existing Session ID Example ===")
existing_session_id = None
# First agent instance - start a conversation
agent1 = GitHubCopilotAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent1:
thread = agent1.get_new_thread()
query1 = "What's the weather in Paris?"
print(f"User: {query1}")
result1 = await agent1.run(query1, thread=thread)
print(f"Agent: {result1}")
# Capture the session ID for later use
existing_session_id = thread.service_thread_id
print(f"Session ID: {existing_session_id}")
if existing_session_id:
print("\n--- Continuing with the same session ID in a new agent instance ---")
# Second agent instance - resume the conversation
agent2 = GitHubCopilotAgent(
instructions="You are a helpful weather agent.",
tools=[get_weather],
)
async with agent2:
# Create thread with existing session ID
thread = agent2.get_new_thread(service_thread_id=existing_session_id)
query2 = "What was the last city I asked about?"
print(f"User: {query2}")
result2 = await agent2.run(query2, thread=thread)
print(f"Agent: {result2}")
print("Note: The agent continues the conversation using the session ID.\n")
async def main() -> None:
print("=== GitHub Copilot Agent Session Management Examples ===\n")
await example_with_automatic_session_creation()
await example_with_session_persistence()
await example_with_existing_session_id()
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,50 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent with Shell Permissions
This sample demonstrates how to enable shell command execution with GitHubCopilotAgent.
By providing a permission handler that approves "shell" requests, the agent can execute
shell commands to perform tasks like listing files, running scripts, or executing system commands.
SECURITY NOTE: Only enable shell permissions when you trust the agent's actions.
Shell commands have full access to your system within the permissions of the running process.
"""
import asyncio
from agent_framework.github import GitHubCopilotAgent
from copilot.types import PermissionRequest, PermissionRequestResult
def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> PermissionRequestResult:
"""Permission handler that prompts the user for approval."""
kind = request.get("kind", "unknown")
print(f"\n[Permission Request: {kind}]")
if "command" in request:
print(f" Command: {request.get('command')}")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionRequestResult(kind="approved")
return PermissionRequestResult(kind="denied-interactively-by-user")
async def main() -> None:
print("=== GitHub Copilot Agent with Shell Permissions ===\n")
agent = GitHubCopilotAgent(
instructions="You are a helpful assistant that can execute shell commands.",
default_options={"on_permission_request": prompt_permission},
)
async with agent:
query = "List the first 3 Python files in the current directory"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,50 @@
# Copyright (c) Microsoft. All rights reserved.
"""
GitHub Copilot Agent with URL Fetching
This sample demonstrates how to enable URL fetching with GitHubCopilotAgent.
By providing a permission handler that approves "url" requests, the agent can
fetch and process content from web URLs.
SECURITY NOTE: Only enable URL permissions when you trust the agent's actions.
URL fetching allows the agent to access any URL accessible from your network.
"""
import asyncio
from agent_framework.github import GitHubCopilotAgent
from copilot.types import PermissionRequest, PermissionRequestResult
def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> PermissionRequestResult:
"""Permission handler that prompts the user for approval."""
kind = request.get("kind", "unknown")
print(f"\n[Permission Request: {kind}]")
if "url" in request:
print(f" URL: {request.get('url')}")
response = input("Approve? (y/n): ").strip().lower()
if response in ("y", "yes"):
return PermissionRequestResult(kind="approved")
return PermissionRequestResult(kind="denied-interactively-by-user")
async def main() -> None:
print("=== GitHub Copilot Agent with URL Fetching ===\n")
agent = GitHubCopilotAgent(
instructions="You are a helpful assistant that can fetch and summarize web content.",
default_options={"on_permission_request": prompt_permission},
)
async with agent:
query = "Fetch https://learn.microsoft.com/agent-framework/tutorials/quick-start and summarize its contents"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result}\n")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,56 @@
# Ollama Examples
This folder contains examples demonstrating how to use Ollama models with the Agent Framework.
## Prerequisites
1. **Install Ollama**: Download and install Ollama from [ollama.com](https://ollama.com/)
2. **Start Ollama**: Ensure Ollama is running on your local machine
3. **Pull a model**: Run `ollama pull mistral` (or any other model you prefer)
- For function calling examples, use models that support tool calling like `mistral` or `qwen2.5`
- For reasoning examples, use models that support reasoning like `qwen3:8b`
- For multimodal examples, use models like `gemma3:4b`
> **Note**: Not all models support all features. Function calling, reasoning, and multimodal capabilities depend on the specific model you're using.
## Recommended Approach
The recommended way to use Ollama with Agent Framework is via the native `OllamaChatClient` from the `agent-framework-ollama` package. This provides full support for Ollama-specific features like reasoning mode.
Alternatively, you can use the `OpenAIChatClient` configured to point to your local Ollama server, which may be useful if you're already familiar with the OpenAI client interface.
## Examples
| File | Description |
|------|-------------|
| [`ollama_agent_basic.py`](ollama_agent_basic.py) | Basic Ollama agent with tool calling using native Ollama Chat Client. Shows both streaming and non-streaming responses. |
| [`ollama_agent_reasoning.py`](ollama_agent_reasoning.py) | Ollama agent with reasoning capabilities using native Ollama Chat Client. Shows how to enable thinking/reasoning mode. |
| [`ollama_chat_client.py`](ollama_chat_client.py) | Direct usage of the native Ollama Chat Client with tool calling. |
| [`ollama_chat_multimodal.py`](ollama_chat_multimodal.py) | Ollama Chat Client with multimodal (image) input capabilities. |
| [`ollama_with_openai_chat_client.py`](ollama_with_openai_chat_client.py) | Alternative approach using OpenAI Chat Client configured to use local Ollama models. |
## Configuration
The examples use environment variables for configuration. Set the appropriate variables based on which example you're running:
### For Native Ollama Examples
Set the following environment variables:
- `OLLAMA_HOST`: The base URL for your Ollama server (optional, defaults to `http://localhost:11434`)
- Example: `export OLLAMA_HOST="http://localhost:11434"`
- `OLLAMA_MODEL_ID`: The model name to use
- Example: `export OLLAMA_MODEL_ID="qwen2.5:8b"`
- Must be a model you have pulled with Ollama
### For OpenAI Client with Ollama (`ollama_with_openai_chat_client.py`)
Set the following environment variables:
- `OLLAMA_ENDPOINT`: The base URL for your Ollama server with `/v1/` suffix
- Example: `export OLLAMA_ENDPOINT="http://localhost:11434/v1/"`
- `OLLAMA_MODEL`: The model name to use
- Example: `export OLLAMA_MODEL="mistral"`
- Must be a model you have pulled with Ollama
@@ -0,0 +1,71 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from datetime import datetime
from agent_framework import tool
from agent_framework.ollama import OllamaChatClient
"""
Ollama Agent Basic Example
This sample demonstrates implementing a Ollama agent with basic tool usage.
Ensure to install Ollama and have a model running locally before running the sample
Not all Models support function calling, to test function calling try llama3.2 or qwen3:4b
Set the model to use via the OLLAMA_MODEL_ID environment variable or modify the code below.
https://ollama.com/
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_threads.py.
@tool(approval_mode="never_require")
def get_time(location: str) -> str:
"""Get the current time."""
return f"The current time in {location} is {datetime.now().strftime('%I:%M %p')}."
async def non_streaming_example() -> None:
"""Example of non-streaming response (get the complete result at once)."""
print("=== Non-streaming Response Example ===")
agent = OllamaChatClient().as_agent(
name="TimeAgent",
instructions="You are a helpful time agent answer in one sentence.",
tools=get_time,
)
query = "What time is it in Seattle? Use a tool call"
print(f"User: {query}")
result = await agent.run(query)
print(f"Result: {result}\n")
async def streaming_example() -> None:
"""Example of streaming response (get results as they are generated)."""
print("=== Streaming Response Example ===")
agent = OllamaChatClient().as_agent(
name="TimeAgent",
instructions="You are a helpful time agent answer in one sentence.",
tools=get_time,
)
query = "What time is it in San Francisco? Use a tool call"
print(f"User: {query}")
print("Agent: ", end="", flush=True)
async for chunk in agent.run(query, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
print("\n")
async def main() -> None:
print("=== Basic Ollama Chat Client Agent Example ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())

Some files were not shown because too many files have changed in this diff Show More