diff --git a/python/packages/foundry/agent_framework_foundry/_chat_client.py b/python/packages/foundry/agent_framework_foundry/_chat_client.py index 223de14c04..aee3e33feb 100644 --- a/python/packages/foundry/agent_framework_foundry/_chat_client.py +++ b/python/packages/foundry/agent_framework_foundry/_chat_client.py @@ -165,6 +165,7 @@ class FoundryChatClient(ChatClientBase): if not async_ad_credential: raise ServiceInitializationError("Azure AD credential is required when client is not provided.") client = AIProjectClient(endpoint=foundry_settings.project_endpoint, credential=async_ad_credential) + should_close_client = True super().__init__( client=client, # type: ignore[reportCallIssue] diff --git a/python/samples/getting_started/agents/foundry/foundry_basic.py b/python/samples/getting_started/agents/foundry/foundry_basic.py index ab377b72a3..ef3d28e0de 100644 --- a/python/samples/getting_started/agents/foundry/foundry_basic.py +++ b/python/samples/getting_started/agents/foundry/foundry_basic.py @@ -23,11 +23,14 @@ async def non_streaming_example() -> None: # Since no Agent ID is provided, the agent will be automatically created # and deleted after getting a response - async with FoundryChatClient(async_ad_credential=DefaultAzureCredential()).create_agent( - name="WeatherAgent", - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + FoundryChatClient(async_ad_credential=credential).create_agent( + name="WeatherAgent", + 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) @@ -40,11 +43,14 @@ async def streaming_example() -> None: # Since no Agent ID is provided, the agent will be automatically created # and deleted after getting a response - async with FoundryChatClient(async_ad_credential=DefaultAzureCredential()).create_agent( - name="WeatherAgent", - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + FoundryChatClient(async_ad_credential=credential).create_agent( + name="WeatherAgent", + 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) diff --git a/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py b/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py index 2a70aa3f46..869d7fe153 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_code_interpreter.py @@ -37,11 +37,14 @@ async def main() -> None: """Example showing how to use the HostedCodeInterpreterTool with Foundry.""" print("=== Foundry Agent with Code Interpreter Example ===") - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - instructions="You are a helpful assistant that can write and execute Python code to solve problems.", - tools=HostedCodeInterpreterTool(), - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + instructions="You are a helpful assistant that can write and execute Python code to solve problems.", + tools=HostedCodeInterpreterTool(), + ) as agent, + ): query = "Generate the factorial of 100 using python code." print(f"User: {query}") print("Agent: ", end="", flush=True) diff --git a/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py b/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py index 5c02b25e1e..dce617e113 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_existing_agent.py @@ -8,7 +8,7 @@ from typing import Annotated from agent_framework import ChatClientAgent from agent_framework.foundry import FoundryChatClient from azure.ai.projects.aio import AIProjectClient -from azure.identity.aio import AzureCliCredential +from azure.identity.aio import DefaultAzureCredential from pydantic import Field @@ -24,9 +24,10 @@ async def main() -> None: print("=== Foundry Chat Client with Existing Agent ===") # Create the client - async with AIProjectClient( - endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], credential=AzureCliCredential() - ) as client: + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], credential=credential) as client, + ): # Create an agent that will persist created_agent = await client.agents.create_agent( model=os.environ["FOUNDRY_MODEL_DEPLOYMENT_NAME"], name="WeatherAgent" diff --git a/python/samples/getting_started/agents/foundry/foundry_with_explicit_settings.py b/python/samples/getting_started/agents/foundry/foundry_with_explicit_settings.py index b78f45ee6b..18dc87d8b1 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_explicit_settings.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_explicit_settings.py @@ -7,7 +7,7 @@ from typing import Annotated from agent_framework import ChatClientAgent from agent_framework.foundry import FoundryChatClient -from azure.identity.aio import AzureCliCredential +from azure.identity.aio import DefaultAzureCredential from pydantic import Field @@ -24,16 +24,19 @@ async def main() -> None: # Since no Agent ID is provided, the agent will be automatically created # and deleted after getting a response - async with ChatClientAgent( - chat_client=FoundryChatClient( - project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], - model_deployment_name=os.environ["FOUNDRY_MODEL_DEPLOYMENT_NAME"], - async_ad_credential=AzureCliCredential(), - agent_name="WeatherAgent", - ), - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient( + project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], + model_deployment_name=os.environ["FOUNDRY_MODEL_DEPLOYMENT_NAME"], + async_ad_credential=credential, + agent_name="WeatherAgent", + ), + 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") diff --git a/python/samples/getting_started/agents/foundry/foundry_with_function_tools.py b/python/samples/getting_started/agents/foundry/foundry_with_function_tools.py index d6dfba396b..ac7a7d26cd 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_function_tools.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_function_tools.py @@ -31,11 +31,14 @@ async def tools_on_agent_level() -> None: # Tools are provided when creating the agent # The agent can use these tools for any query during its lifetime - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - 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: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + 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}") @@ -60,11 +63,14 @@ async def tools_on_run_level() -> None: print("=== Tools Passed to Run Method ===") # Agent created without tools - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - instructions="You are a helpful assistant.", - # No tools defined here - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + 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}") @@ -89,11 +95,14 @@ async def mixed_tools_example() -> None: print("=== Mixed Tools Example (Agent + Run Method) ===") # Agent created with some base tools - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - instructions="You are a comprehensive assistant that can help with various information requests.", - tools=[get_weather], # Base tool available for all queries - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + 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}") diff --git a/python/samples/getting_started/agents/foundry/foundry_with_thread.py b/python/samples/getting_started/agents/foundry/foundry_with_thread.py index 6a2a4ebfeb..9e7a6a60fb 100644 --- a/python/samples/getting_started/agents/foundry/foundry_with_thread.py +++ b/python/samples/getting_started/agents/foundry/foundry_with_thread.py @@ -22,11 +22,14 @@ async def example_with_automatic_thread_creation() -> None: """Example showing automatic thread creation (service-managed thread).""" print("=== Automatic Thread Creation Example ===") - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + 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}") @@ -46,11 +49,14 @@ async def example_with_thread_persistence() -> None: print("=== Thread Persistence Example ===") print("Using the same thread across multiple conversations to maintain context.\n") - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + 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() @@ -82,11 +88,14 @@ async def example_with_existing_thread_id() -> None: # First, create a conversation and capture the thread ID existing_thread_id = None - async with ChatClientAgent( - chat_client=FoundryChatClient(async_ad_credential=DefaultAzureCredential()), - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(async_ad_credential=credential), + 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?" @@ -102,11 +111,14 @@ async def example_with_existing_thread_id() -> None: 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 ChatClientAgent( - chat_client=FoundryChatClient(thread_id=existing_thread_id, async_ad_credential=DefaultAzureCredential()), - instructions="You are a helpful weather agent.", - tools=get_weather, - ) as agent: + async with ( + DefaultAzureCredential() as credential, + ChatClientAgent( + chat_client=FoundryChatClient(thread_id=existing_thread_id, async_ad_credential=credential), + instructions="You are a helpful weather agent.", + tools=get_weather, + ) as agent, + ): # Create a thread with the existing ID thread = ChatClientAgentThread(id=existing_thread_id)