Python: [BREAKING] Replaced AIProjectClient with AgentsClient in Foundry (#1936)

* Replaced AIProjectClient with AgentsClient in Foundry

* Update python/samples/getting_started/observability/azure_ai_agent_observability.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/samples/getting_started/observability/azure_ai_chat_client_with_observability.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Small fix

* Removed TODO item

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Dmytro Struk
2025-11-05 13:42:36 -08:00
committed by GitHub
Unverified
parent 8855bfb065
commit d701e796cb
15 changed files with 364 additions and 477 deletions
@@ -38,10 +38,8 @@ Before running the examples, you need to set up your environment variables. You
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 either:
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_NAME="bing-grounding-connection"
# OR
BING_CONNECTION_ID="your-bing-connection-id"
```
@@ -49,7 +47,7 @@ Before running the examples, you need to set up your environment variables. You
- 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 either the connection name or ID
- Copy the ID
### Option 2: Using environment variables directly
@@ -58,9 +56,7 @@ 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_NAME="your-bing-connection-name" # Optional, only needed for web search samples
# OR
export BING_CONNECTION_ID="your-bing-connection-id" # Alternative to BING_CONNECTION_NAME
export BING_CONNECTION_ID="your-bing-connection-id"
```
### Required Variables
@@ -70,4 +66,4 @@ export BING_CONNECTION_ID="your-bing-connection-id" # Alternative to BING_CONNE
### Optional Variables
- `BING_CONNECTION_NAME` or `BING_CONNECTION_ID`: Your Bing connection name or ID (required for `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`)
- `BING_CONNECTION_ID`: Your Bing connection ID (required for `azure_ai_with_bing_grounding.py` and `azure_ai_with_multiple_tools.py`)
@@ -5,6 +5,7 @@ import os
from agent_framework import ChatAgent, CitationAnnotation
from agent_framework.azure import AzureAIAgentClient
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
@@ -38,16 +39,17 @@ async def main() -> None:
# 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 client,
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,
):
ai_search_conn_id = ""
async for connection in client.connections.list():
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
azure_ai_agent = await client.agents.create_agent(
azure_ai_agent = await project_client.agents.create_agent(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
name="HotelSearchAgent",
instructions=(
@@ -69,7 +71,7 @@ async def main() -> None:
)
# 2. Create chat client with the existing agent
chat_client = AzureAIAgentClient(project_client=client, agent_id=azure_ai_agent.id)
chat_client = AzureAIAgentClient(agents_client=agents_client, agent_id=azure_ai_agent.id)
try:
async with ChatAgent(
@@ -112,7 +114,7 @@ async def main() -> None:
finally:
# Clean up the agent manually
await client.agents.delete_agent(azure_ai_agent.id)
await project_client.agents.delete_agent(azure_ai_agent.id)
if __name__ == "__main__":
@@ -12,8 +12,7 @@ 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 either BING_CONNECTION_NAME or BING_CONNECTION_ID environment variable
Example: BING_CONNECTION_NAME="bing-grounding-connection"
2. Set BING_CONNECTION_ID environment variable
Example: BING_CONNECTION_ID="your-bing-connection-id"
To set up Bing Grounding:
@@ -27,7 +26,7 @@ To set up Bing Grounding:
async def main() -> None:
"""Main function demonstrating Azure AI agent with Bing Grounding search."""
# 1. Create Bing Grounding search tool using HostedWebSearchTool
# The connection_name or ID will be automatically picked up from environment variable
# The connection ID will be automatically picked up from environment variable
bing_search_tool = HostedWebSearchTool(
name="Bing Grounding Search",
description="Search the web for current information using Bing",
@@ -5,6 +5,7 @@ import os
from agent_framework import ChatAgent
from agent_framework.azure import AzureAIAgentClient
from azure.ai.agents.aio import AgentsClient
from azure.ai.projects.aio import AIProjectClient
from azure.identity.aio import AzureCliCredential
@@ -22,16 +23,17 @@ async def main() -> None:
# Create the client
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as client,
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,
):
azure_ai_agent = await client.agents.create_agent(
azure_ai_agent = await project_client.agents.create_agent(
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
# Create remote agent with default instructions
# These instructions will persist on created agent for every run.
instructions="End each response with [END].",
)
chat_client = AzureAIAgentClient(project_client=client, agent_id=azure_ai_agent.id)
chat_client = AzureAIAgentClient(agents_client=agents_client, agent_id=azure_ai_agent.id)
try:
async with ChatAgent(
@@ -50,7 +52,7 @@ async def main() -> None:
print(f"Agent: {result}\n")
finally:
# Clean up the agent manually
await client.agents.delete_agent(azure_ai_agent.id)
await project_client.agents.delete_agent(azure_ai_agent.id)
if __name__ == "__main__":
@@ -7,7 +7,7 @@ from typing import Annotated
from agent_framework import ChatAgent
from agent_framework.azure import AzureAIAgentClient
from azure.ai.projects.aio import AIProjectClient
from azure.ai.agents.aio import AgentsClient
from azure.identity.aio import AzureCliCredential
from pydantic import Field
@@ -33,16 +33,16 @@ async def main() -> None:
# Create the client
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as client,
AgentsClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as agents_client,
):
# Create an thread that will persist
created_thread = await client.agents.threads.create()
created_thread = await agents_client.threads.create()
try:
async with ChatAgent(
# passing in the client is optional here, so if you take the agent_id from the portal
# you can use it directly without the two lines above.
chat_client=AzureAIAgentClient(project_client=client),
chat_client=AzureAIAgentClient(agents_client=agents_client),
instructions="You are a helpful weather agent.",
tools=get_weather,
) as agent:
@@ -52,7 +52,7 @@ async def main() -> None:
print(f"Result: {result}\n")
finally:
# Clean up the thread manually
await client.agents.threads.delete(created_thread.id)
await agents_client.threads.delete(created_thread.id)
if __name__ == "__main__":
@@ -44,8 +44,6 @@ async def main() -> None:
AzureCliCredential() as credential,
AzureAIAgentClient(async_credential=credential) as chat_client,
):
# enable azure-ai observability
await chat_client.setup_azure_ai_observability()
agent = chat_client.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
@@ -69,8 +69,6 @@ async def main() -> None:
AzureCliCredential() as credential,
AzureAIAgentClient(async_credential=credential) as chat_client,
):
# enable azure-ai observability
await chat_client.setup_azure_ai_observability()
agent = chat_client.create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
@@ -9,7 +9,9 @@ import dotenv
from agent_framework import ChatAgent
from agent_framework.azure import AzureAIAgentClient
from agent_framework.observability import get_tracer
from azure.ai.agents.aio import AgentsClient
from azure.ai.projects.aio import AIProjectClient
from azure.core.exceptions import ResourceNotFoundError
from azure.identity.aio import AzureCliCredential
from opentelemetry.trace import SpanKind
from opentelemetry.trace.span import format_trace_id
@@ -38,16 +40,36 @@ async def get_weather(
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def setup_azure_ai_observability(
project_client: AIProjectClient, enable_sensitive_data: bool | None = None
) -> None:
"""Use this method to setup tracing in your Azure AI Project.
This will take the connection string from the AIProjectClient.
It will override any connection string that is set in the environment variables.
It will disable any OTLP endpoint that might have been set.
"""
try:
conn_string = await project_client.telemetry.get_application_insights_connection_string()
except ResourceNotFoundError:
print("No Application Insights connection string found for the Azure AI Project.")
return
from agent_framework.observability import setup_observability
setup_observability(applicationinsights_connection_string=conn_string, enable_sensitive_data=enable_sensitive_data)
async def main():
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project,
AzureAIAgentClient(project_client=project) as client,
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,
AzureAIAgentClient(agents_client=agents_client) as client,
):
# This will enable tracing and configure the application to send telemetry data to the
# Application Insights instance attached to the Azure AI project.
# This will override any existing configuration.
await client.setup_azure_ai_observability()
await setup_azure_ai_observability(project_client)
questions = ["What's the weather in Amsterdam?", "and in Paris, and which is better?", "Why is the sky blue?"]
@@ -9,7 +9,9 @@ import dotenv
from agent_framework import HostedCodeInterpreterTool
from agent_framework.azure import AzureAIAgentClient
from agent_framework.observability import get_tracer
from azure.ai.agents.aio import AgentsClient
from azure.ai.projects.aio import AIProjectClient
from azure.core.exceptions import ResourceNotFoundError
from azure.identity.aio import AzureCliCredential
from opentelemetry.trace import SpanKind
from opentelemetry.trace.span import format_trace_id
@@ -42,6 +44,25 @@ async def get_weather(
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def setup_azure_ai_observability(
project_client: AIProjectClient, enable_sensitive_data: bool | None = None
) -> None:
"""Use this method to setup tracing in your Azure AI Project.
This will take the connection string from the AIProjectClient instance.
It will override any connection string that is set in the environment variables.
It will disable any OTLP endpoint that might have been set.
"""
try:
conn_string = await project_client.telemetry.get_application_insights_connection_string()
except ResourceNotFoundError:
print("No Application Insights connection string found for the Azure AI Project.")
return
from agent_framework.observability import setup_observability
setup_observability(applicationinsights_connection_string=conn_string, enable_sensitive_data=enable_sensitive_data)
async def main() -> None:
"""Run an AI service.
@@ -62,13 +83,14 @@ async def main() -> None:
]
async with (
AzureCliCredential() as credential,
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project,
AzureAIAgentClient(project_client=project) as client,
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,
AzureAIAgentClient(agents_client=agents_client) as client,
):
# This will enable tracing and configure the application to send telemetry data to the
# Application Insights instance attached to the Azure AI project.
# This will override any existing configuration.
await client.setup_azure_ai_observability()
await setup_azure_ai_observability(project_client)
with get_tracer().start_as_current_span(
name="Foundry Telemetry from Agent Framework", kind=SpanKind.CLIENT