mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
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:
@@ -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())
|
||||
+69
@@ -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())
|
||||
+232
@@ -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())
|
||||
+119
@@ -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())
|
||||
+86
@@ -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())
|
||||
+102
@@ -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())
|
||||
+72
@@ -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())
|
||||
+64
@@ -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())
|
||||
+51
@@ -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())
|
||||
+136
@@ -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())
|
||||
+52
@@ -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())
|
||||
+139
@@ -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())
|
||||
+100
@@ -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())
|
||||
+46
@@ -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())
|
||||
+53
@@ -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())
|
||||
+52
@@ -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())
|
||||
+74
@@ -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())
|
||||
+113
@@ -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.
|
||||
"""
|
||||
+139
@@ -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())
|
||||
+256
@@ -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())
|
||||
+62
@@ -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())
|
||||
+155
@@ -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())
|
||||
+103
@@ -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())
|
||||
+51
@@ -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())
|
||||
+59
@@ -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
Reference in New Issue
Block a user