diff --git a/sdk/ai/azure-ai-projects/assets.json b/sdk/ai/azure-ai-projects/assets.json index 3a0bb4a43b15..19f1f7e5f9d3 100644 --- a/sdk/ai/azure-ai-projects/assets.json +++ b/sdk/ai/azure-ai-projects/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/ai/azure-ai-projects", - "Tag": "python/ai/azure-ai-projects_c84bf9341a" + "Tag": "python/ai/azure-ai-projects_875c4f833f" } diff --git a/sdk/ai/azure-ai-projects/pyproject.toml b/sdk/ai/azure-ai-projects/pyproject.toml index 3cc1de11d7af..fe2948c218ac 100644 --- a/sdk/ai/azure-ai-projects/pyproject.toml +++ b/sdk/ai/azure-ai-projects/pyproject.toml @@ -68,7 +68,7 @@ pytyped = ["py.typed"] verifytypes = false [tool.mypy] -exclude = '.*samples[\\/]hosted_agents[\\/]assets[\\/].*main\.py$' +exclude = '(^|.*[\\/])samples[\\/]hosted_agents[\\/]assets[\\/].*main\.py$|(^|.*[\\/])samples[\\/]agents[\\/]util\.py$|(^|.*[\\/])samples[\\/]agents[\\/]tools[\\/]util\.py$|(^|.*[\\/])samples[\\/]agents[\\/]telemetry[\\/]util\.py$' [tool.azure-sdk-conda] in_bundle = false diff --git a/sdk/ai/azure-ai-projects/samples/agents/__init__.py b/sdk/ai/azure-ai-projects/samples/agents/__init__.py new file mode 100644 index 000000000000..91cacbdf2f80 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/__init__.py @@ -0,0 +1 @@ +# Package marker for sample type-checking. diff --git a/sdk/ai/azure-ai-projects/samples/agents/agent_retrieve_helper.py b/sdk/ai/azure-ai-projects/samples/agents/agent_retrieve_helper.py deleted file mode 100644 index a1efd3b86a52..000000000000 --- a/sdk/ai/azure-ai-projects/samples/agents/agent_retrieve_helper.py +++ /dev/null @@ -1,69 +0,0 @@ -# pylint: disable=name-too-long -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Helper utilities for retrieve samples. - -This module centralizes setup used by the retrieve samples. It provides a -context manager that creates an agent version and conversation, yields -their identifiers for retrieve/get demonstrations, and performs agent cleanup -when the context exits. -""" - -from contextlib import contextmanager, asynccontextmanager -from typing import Generator, AsyncGenerator - -from azure.ai.projects.models import PromptAgentDefinition -from azure.ai.projects import AIProjectClient -from azure.ai.projects.aio import AIProjectClient as AsyncAIProjectClient - - -@contextmanager -def create_and_retrieve_agent_and_conversation( - project_client: AIProjectClient, model: str -) -> Generator[tuple[str, str], None, None]: - - with (project_client.get_openai_client() as openai_client,): - agent = project_client.agents.create_version( - agent_name="MyAgent", - definition=PromptAgentDefinition( - model=model, - instructions="You are a helpful assistant.", - ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - - conversation = openai_client.conversations.create() - print(f"Conversation created (id: {conversation.id})") - - try: - yield agent.name, conversation.id - finally: - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - - -@asynccontextmanager -async def create_and_retrieve_agent_and_conversation_async( - project_client: AsyncAIProjectClient, model: str -) -> AsyncGenerator[tuple[str, str], None]: - - async with (project_client.get_openai_client() as openai_client,): - agent = await project_client.agents.create_version( - agent_name="MyAgent", - definition=PromptAgentDefinition( - model=model, - instructions="You are a helpful assistant.", - ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - - conversation = await openai_client.conversations.create() - print(f"Conversation created (id: {conversation.id})") - - try: - yield agent.name, conversation.id - finally: - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic.py index 260902b53c4b..467b3f89aa56 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic.py @@ -25,58 +25,88 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient -from azure.ai.projects.models import PromptAgentDefinition +from azure.ai.projects.models import ( + AgentEndpointConfig, + FixedRatioVersionSelectionRule, + PromptAgentDefinition, + ProtocolConfiguration, + ResponsesProtocolConfiguration, + VersionSelector, +) load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, ): + created_version = None + original_agent_endpoint = None - with project_client.get_openai_client() as openai_client: - agent = project_client.agents.create_version( - agent_name="MyAgent", + try: + created_version = project_client.agents.create_version( + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", ), ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - - conversation = openai_client.conversations.create( - items=[{"type": "message", "role": "user", "content": "What is the size of France in square miles?"}], - ) - print(f"Created conversation with initial user message (id: {conversation.id})") - - response = openai_client.responses.create( - conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - print(f"Response output: {response.output_text}") - - openai_client.conversations.items.create( - conversation_id=conversation.id, - items=[{"type": "message", "role": "user", "content": "And what is the capital city?"}], + print( + f"Agent created (id: {created_version.id}, name: {created_version.name}, version: {created_version.version})" ) - print("Added a second user message to the conversation") - response = openai_client.responses.create( - conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, + original_agent_endpoint = project_client.agents.get(agent_name=agent_name).agent_endpoint + endpoint_config = AgentEndpointConfig( + version_selector=VersionSelector( + version_selection_rules=[ + FixedRatioVersionSelectionRule(agent_version=created_version.version, traffic_percentage=100), + ] + ), + protocol_configuration=ProtocolConfiguration(responses=ResponsesProtocolConfiguration()), ) - print(f"Response output: {response.output_text}") - - openai_client.conversations.delete(conversation_id=conversation.id) - print("Conversation deleted") - - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") + project_client.agents.update_details(agent_name=agent_name, agent_endpoint=endpoint_config) + print(f"Agent endpoint configured for version {created_version.version}") + + with project_client.get_openai_client(agent_name=agent_name) as openai_client: + + conversation = openai_client.conversations.create( + items=[{"type": "message", "role": "user", "content": "What is the size of France in square miles?"}], + ) + print(f"Created conversation with initial user message (id: {conversation.id})") + + response = openai_client.responses.create( + conversation=conversation.id, + ) + print(f"Response output: {response.output_text}") + + openai_client.conversations.items.create( + conversation_id=conversation.id, + items=[{"type": "message", "role": "user", "content": "And what is the capital city?"}], + ) + print("Added a second user message to the conversation") + + response = openai_client.responses.create( + conversation=conversation.id, + ) + print(f"Response output: {response.output_text}") + + openai_client.conversations.delete(conversation_id=conversation.id) + print("Conversation deleted") + finally: + if original_agent_endpoint is not None: + project_client.agents.update_details(agent_name=agent_name, agent_endpoint=original_agent_endpoint) + + if created_version is not None: + project_client.agents.delete_version( + agent_name=agent_name, agent_version=created_version.version, force=True + ) diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic_async.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic_async.py index 3936a1aec2e6..ca8fb15d1e7a 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_basic_async.py @@ -25,6 +25,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import asyncio @@ -32,57 +33,88 @@ from dotenv import load_dotenv from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient -from azure.ai.projects.models import PromptAgentDefinition +from azure.ai.projects.models import ( + AgentEndpointConfig, + FixedRatioVersionSelectionRule, + PromptAgentDefinition, + ProtocolConfiguration, + ResponsesProtocolConfiguration, + VersionSelector, +) load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main() -> None: async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, ): - - agent = await project_client.agents.create_version( - agent_name="MyAgent", - definition=PromptAgentDefinition( - model=os.environ["FOUNDRY_MODEL_NAME"], - instructions="You are a helpful assistant that answers general questions.", - ), - ) - print(f"Agent created (name: {agent.name}, id: {agent.id}, version: {agent.version})") - - conversation = await openai_client.conversations.create( - items=[{"type": "message", "role": "user", "content": "What is the size of France in square miles?"}], - ) - print(f"Created conversation with initial user message (id: {conversation.id})") - - response = await openai_client.responses.create( - conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - print(f"Response output: {response.output_text}") - - await openai_client.conversations.items.create( - conversation_id=conversation.id, - items=[{"type": "message", "role": "user", "content": "And what is the capital city?"}], - ) - print("Added a second user message to the conversation") - - response = await openai_client.responses.create( - conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - print(f"Response output: {response.output_text}") - - await openai_client.conversations.delete(conversation_id=conversation.id) - print("Conversation deleted") - - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") + created_version = None + original_agent_endpoint = None + + try: + created_version = await project_client.agents.create_version( + agent_name=agent_name, + definition=PromptAgentDefinition( + model=os.environ["FOUNDRY_MODEL_NAME"], + instructions="You are a helpful assistant that answers general questions.", + ), + ) + + original_agent_endpoint = (await project_client.agents.get(agent_name=agent_name)).agent_endpoint + endpoint_config = AgentEndpointConfig( + version_selector=VersionSelector( + version_selection_rules=[ + FixedRatioVersionSelectionRule(agent_version=created_version.version, traffic_percentage=100), + ] + ), + protocol_configuration=ProtocolConfiguration(responses=ResponsesProtocolConfiguration()), + ) + await project_client.agents.update_details(agent_name=agent_name, agent_endpoint=endpoint_config) + print(f"Agent endpoint configured for version {created_version.version}") + + openai_client = project_client.get_openai_client(agent_name=agent_name) + + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (name: {agent.name}, id: {agent.id}, version: {agent.versions.latest.version})") + + conversation = await openai_client.conversations.create( + items=[{"type": "message", "role": "user", "content": "What is the size of France in square miles?"}], + ) + print(f"Created conversation with initial user message (id: {conversation.id})") + + response = await openai_client.responses.create( + conversation=conversation.id, + ) + print(f"Response output: {response.output_text}") + + await openai_client.conversations.items.create( + conversation_id=conversation.id, + items=[{"type": "message", "role": "user", "content": "And what is the capital city?"}], + ) + print("Added a second user message to the conversation") + + response = await openai_client.responses.create( + conversation=conversation.id, + ) + print(f"Response output: {response.output_text}") + + await openai_client.conversations.delete(conversation_id=conversation.id) + print("Conversation deleted") + finally: + if original_agent_endpoint is not None: + await project_client.agents.update_details( + agent_name=agent_name, agent_endpoint=original_agent_endpoint + ) + + if created_version is not None: + await project_client.agents.delete_version( + agent_name=agent_name, agent_version=created_version.version, force=True + ) if __name__ == "__main__": diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic.py index c1f456866c9e..98fb61604346 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic.py @@ -26,37 +26,43 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv -from agent_retrieve_helper import create_and_retrieve_agent_and_conversation # pylint: disable=import-error +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import PromptAgentDefinition load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] model = os.environ["FOUNDRY_MODEL_NAME"] - +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - # Creates prerequisite resources and yields (agent_name, conversation_id). - # Then automatically deletes the created agent version when this context manager exits. - create_and_retrieve_agent_and_conversation(project_client=project_client, model=model) as ( - agent_name, - conversation_id, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, + definition=PromptAgentDefinition( + model=model, + instructions="You are a helpful assistant.", + ), ), - project_client.get_openai_client() as openai_client, + project_client.get_openai_client(agent_name=agent_name) as openai_client, ): + agent = project_client.agents.get(agent_name=agent_name) + conversation = openai_client.conversations.create() + print(f"Conversation created (id: {conversation.id})") # Retrieve latest version for the prerequisite agent. - agent = project_client.agents.get(agent_name=agent_name) print(f"Agent retrieved (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Retrieve the prerequisite conversation. - conversation = openai_client.conversations.retrieve(conversation_id=conversation_id) + conversation = openai_client.conversations.retrieve(conversation_id=conversation.id) print(f"Retrieved conversation (id: {conversation.id})") # Add a new user text message to the conversation @@ -68,6 +74,5 @@ response = openai_client.responses.create( conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic_async.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic_async.py index 8c6491746f70..94cafecfbb91 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_retrieve_basic_async.py @@ -26,40 +26,59 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os import asyncio +import sys +from pathlib import Path from dotenv import load_dotenv -from agent_retrieve_helper import create_and_retrieve_agent_and_conversation_async # pylint: disable=import-error +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient +from azure.ai.projects.models import PromptAgentDefinition + +_SAMPLES_DIR = Path(__file__).resolve().parents[1] +if str(_SAMPLES_DIR) not in sys.path: + sys.path.insert(0, str(_SAMPLES_DIR)) load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] model = os.environ["FOUNDRY_MODEL_NAME"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main(): async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - # Creates prerequisite resources and yields (agent_name, conversation_id). - # Then automatically deletes the created agent version when this context manager exits. - create_and_retrieve_agent_and_conversation_async(project_client=project_client, model=model) as ( - agent_name, - conversation_id, + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, + definition=PromptAgentDefinition( + model=model, + instructions="You are a helpful assistant.", + ), ), - project_client.get_openai_client() as openai_client, + project_client.get_openai_client(agent_name=agent_name) as openai_client, ): + agent_version = await project_client.agents.get(agent_name=agent_name) + print( + f"Agent created (id: {agent_version.id}, name: {agent_version.name}, " + f"version: {agent_version.versions.latest.version})" + ) + + conversation = await openai_client.conversations.create() + print(f"Conversation created (id: {conversation.id})") # Retrieve latest version for the prerequisite agent. agent = await project_client.agents.get(agent_name=agent_name) print(f"Agent retrieved (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Retrieve the prerequisite conversation. - conversation = await openai_client.conversations.retrieve(conversation_id=conversation_id) + conversation = await openai_client.conversations.retrieve(conversation_id=conversation.id) print(f"Retrieved conversation (id: {conversation.id})") # Add a new user text message to the conversation @@ -71,7 +90,6 @@ async def main(): response = await openai_client.responses.create( conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_stream_events.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_stream_events.py index 417baa7d3ee5..f62263413ad6 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_stream_events.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_stream_events.py @@ -25,10 +25,12 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition @@ -36,22 +38,21 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): conversation = openai_client.conversations.create( items=[{"type": "message", "role": "user", "content": "Tell me about the capital city of France"}], ) @@ -59,7 +60,6 @@ with openai_client.responses.create( conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, stream=True, ) as response_stream_events: @@ -75,6 +75,3 @@ openai_client.conversations.delete(conversation_id=conversation.id) print("Conversation deleted") - - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output.py index 5579038bac2c..ed7f5cb01917 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output.py @@ -28,11 +28,13 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv from pydantic import BaseModel, Field +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -52,15 +54,14 @@ class CalendarEvent(BaseModel): endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], text=PromptAgentDefinitionTextOptions( @@ -71,8 +72,9 @@ class CalendarEvent(BaseModel): and returns it in the desired structured output format. """, ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): conversation = openai_client.conversations.create( items=[ @@ -87,12 +89,8 @@ class CalendarEvent(BaseModel): response = openai_client.responses.create( conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") openai_client.conversations.delete(conversation_id=conversation.id) print("Conversation deleted") - - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output_async.py b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output_async.py index c4a652cf846b..f1eea65de8a6 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/sample_agent_structured_output_async.py @@ -28,12 +28,14 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import asyncio import os from dotenv import load_dotenv from pydantic import BaseModel, Field +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import ( @@ -45,6 +47,7 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") class CalendarEvent(BaseModel): @@ -58,10 +61,9 @@ async def main() -> None: async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], text=PromptAgentDefinitionTextOptions( @@ -72,8 +74,11 @@ async def main() -> None: and returns it in the desired structured output format. """, ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") conversation = await openai_client.conversations.create( items=[ @@ -88,16 +93,12 @@ async def main() -> None: response = await openai_client.responses.create( conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") await openai_client.conversations.delete(conversation_id=conversation.id) print("Conversation deleted") - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/telemetry/__init__.py b/sdk/ai/azure-ai-projects/samples/agents/telemetry/__init__.py new file mode 100644 index 000000000000..91cacbdf2f80 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/telemetry/__init__.py @@ -0,0 +1 @@ +# Package marker for sample type-checking. diff --git a/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_azure_monitor_tracing.py b/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_azure_monitor_tracing.py index 795d5aa7c6dc..251bd4a8fe0e 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_azure_monitor_tracing.py +++ b/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_azure_monitor_tracing.py @@ -22,14 +22,16 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING - Set to `true` to enable GenAI telemetry tracing, which is + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING - Set to `true` to enable GenAI telemetry tracing, which is disabled by default. - 4) OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT - Optional. Set to `true` to trace the content of chat + 5) OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT - Optional. Set to `true` to trace the content of chat messages, which may contain personal data. False by default. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from opentelemetry import trace from azure.monitor.opentelemetry import configure_azure_monitor @@ -41,6 +43,7 @@ load_dotenv() agent = None +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, @@ -54,28 +57,24 @@ scenario = os.path.basename(__file__) with tracer.start_as_current_span(scenario): - with project_client.get_openai_client() as openai_client: - agent_definition = PromptAgentDefinition( - model=os.environ["FOUNDRY_MODEL_NAME"], - instructions="You are a helpful assistant that answers general questions", - ) - - agent = project_client.agents.create_version(agent_name="MyAgent", definition=agent_definition) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + with ( + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, + definition=PromptAgentDefinition( + model=os.environ["FOUNDRY_MODEL_NAME"], + instructions="You are a helpful assistant that answers general questions", + ), + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): conversation = openai_client.conversations.create() print(f"Created conversation with initial user message (id: {conversation.id})") response = openai_client.responses.create( conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "id": agent.id, "type": "agent_reference"}}, input="What is the size of France in square miles?", ) print(f"Response output: {response.output_text}") openai_client.conversations.delete(conversation_id=conversation.id) - print("Conversation deleted") - - if agent: - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing.py b/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing.py index 8b9be473e7dc..f63a41d07352 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing.py +++ b/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing.py @@ -21,15 +21,17 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING - Set to `true` to enable GenAI telemetry tracing, which is + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING - Set to `true` to enable GenAI telemetry tracing, which is disabled by default. - 4) OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT - Optional. Set to `true` to trace the content of chat + 5) OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT - Optional. Set to `true` to trace the content of chat messages, which may contain personal data. False by default. """ import os from typing import Any from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.core.settings import settings @@ -82,43 +84,39 @@ def display_conversation_item(item: Any) -> None: # pylint: disable=redefined-o AIProjectInstrumentor().instrument() scenario = os.path.basename(__file__) -with tracer.start_as_current_span(scenario): - with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - agent_definition = PromptAgentDefinition( +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +with ( + tracer.start_as_current_span(scenario), + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, + definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", - ) - - agent = project_client.agents.create_version(agent_name="MyAgent", definition=agent_definition) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - - conversation = openai_client.conversations.create() - - request = "Hello, tell me a joke." - response = openai_client.responses.create( - conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - input=request, - ) - print(f"Answer: {response.output}") - - response = openai_client.responses.create( - conversation=conversation.id, - input="Tell another one about computers.", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - print(f"Answer: {response.output}") - - print("\nšŸ“‹ Listing conversation items...") - items = openai_client.conversations.items.list(conversation_id=conversation.id) - - # Print all the items - for item in items: - display_conversation_item(item) - - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") + ), + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): + conversation = openai_client.conversations.create() + + request = "Hello, tell me a joke." + response = openai_client.responses.create( + conversation=conversation.id, + input=request, + ) + print(f"Answer: {response.output}") + + response = openai_client.responses.create( + conversation=conversation.id, + input="Tell another one about computers.", + ) + print(f"Answer: {response.output}") + + print("\nšŸ“‹ Listing conversation items...") + items = openai_client.conversations.items.list(conversation_id=conversation.id) + + # Print all the items + for item in items: + display_conversation_item(item) diff --git a/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing_custom_attributes.py b/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing_custom_attributes.py index 5bfcea4034e0..5c9fd3e87dba 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing_custom_attributes.py +++ b/sdk/ai/azure-ai-projects/samples/agents/telemetry/sample_agent_basic_with_console_tracing_custom_attributes.py @@ -22,9 +22,10 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING - Set to `true` to enable GenAI telemetry tracing, which is + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING - Set to `true` to enable GenAI telemetry tracing, which is disabled by default. - 4) OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT - Optional. Set to `true` to trace the content of chat + 5) OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT - Optional. Set to `true` to trace the content of chat messages, which may contain personal data. False by default. """ @@ -83,18 +84,20 @@ def on_end(self, span: ReadableSpan): provider.add_span_processor(CustomAttributeSpanProcessor()) scenario = os.path.basename(__file__) -with tracer.start_as_current_span(scenario): - with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as client, - ): - - agent_definition = PromptAgentDefinition( - model=os.environ["FOUNDRY_MODEL_NAME"], - instructions="You are a helpful assistant that answers general questions", - ) - - agent = client.agents.create_version(agent_name="MyAgent", definition=agent_definition) - - client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") +with ( + tracer.start_as_current_span(scenario), + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as client, +): + + agent_definition = PromptAgentDefinition( + model=os.environ["FOUNDRY_MODEL_NAME"], + instructions="You are a helpful assistant that answers general questions", + ) + + agent = client.agents.create_version( + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=agent_definition + ) + + client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) + print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/telemetry/util.py b/sdk/ai/azure-ai-projects/samples/agents/telemetry/util.py new file mode 100644 index 000000000000..bc55b40b1291 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/telemetry/util.py @@ -0,0 +1,27 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +import sys +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from samples.agents.util import create_version_with_endpoint, create_version_with_endpoint_async +else: + _AGENTS_UTIL_PATH = Path(__file__).resolve().parents[1] / "util.py" + _PKG_ROOT = Path(__file__).resolve().parents[3] + if str(_PKG_ROOT) not in sys.path: + sys.path.insert(0, str(_PKG_ROOT)) + + _SPEC = spec_from_file_location("samples_agents_util", _AGENTS_UTIL_PATH) + if _SPEC is None or _SPEC.loader is None: + raise ImportError(f"Unable to load agent samples util from {_AGENTS_UTIL_PATH}") + + _MODULE = module_from_spec(_SPEC) + _SPEC.loader.exec_module(_MODULE) + + create_version_with_endpoint = _MODULE.create_version_with_endpoint + create_version_with_endpoint_async = _MODULE.create_version_with_endpoint_async diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/__init__.py b/sdk/ai/azure-ai-projects/samples/agents/tools/__init__.py new file mode 100644 index 000000000000..91cacbdf2f80 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/__init__.py @@ -0,0 +1 @@ +# Package marker for sample type-checking. diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_ai_search.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_ai_search.py index e5d6d816ea6e..6eb6cbc49694 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_ai_search.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_ai_search.py @@ -21,14 +21,16 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) AI_SEARCH_PROJECT_CONNECTION_ID - The AI Search project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) AI_SEARCH_PROJECT_CONNECTION_ID - The AI Search project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. - 4) AI_SEARCH_INDEX_NAME - The name of the AI Search index to use for searching. - 5) AI_SEARCH_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. + 5) AI_SEARCH_INDEX_NAME - The name of the AI Search index to use for searching. + 6) AI_SEARCH_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -42,27 +44,27 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = AzureAISearchTool( - azure_ai_search=AzureAISearchToolResource( - indexes=[ - AISearchIndexResource( - project_connection_id=os.environ["AI_SEARCH_PROJECT_CONNECTION_ID"], - index_name=os.environ["AI_SEARCH_INDEX_NAME"], - query_type=AzureAISearchQueryType.SIMPLE, - ), - ] - ) +tool = AzureAISearchTool( + azure_ai_search=AzureAISearchToolResource( + indexes=[ + AISearchIndexResource( + project_connection_id=os.environ["AI_SEARCH_PROJECT_CONNECTION_ID"], + index_name=os.environ["AI_SEARCH_INDEX_NAME"], + query_type=AzureAISearchQueryType.SIMPLE, + ), + ] ) +) - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="""You are a helpful assistant. You must always provide citations for @@ -70,9 +72,9 @@ tools=[tool], ), description="You are a helpful agent.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Get user input from environment variable or prompt user_input = os.environ.get("AI_SEARCH_USER_INPUT") if not user_input: @@ -82,7 +84,6 @@ stream=True, tool_choice="required", input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -107,7 +108,3 @@ elif event.type == "response.completed": print("\nFollow-up completed!") print(f"Agent response: {event.response.output_text}") - - print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_azure_function.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_azure_function.py index 09c98f891a00..5a7729dbf78f 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_azure_function.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_azure_function.py @@ -22,13 +22,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) STORAGE_INPUT_QUEUE_NAME - The name of the Azure Storage Queue to use for input and output in the Azure Function tool. - 4) STORAGE_OUTPUT_QUEUE_NAME - The name of the Azure Storage Queue to use for output in the Azure Function tool. - 5) STORAGE_QUEUE_SERVICE_ENDPOINT - The endpoint of the Azure Storage Queue service. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) STORAGE_INPUT_QUEUE_NAME - The name of the Azure Storage Queue to use for input and output in the Azure Function tool. + 5) STORAGE_OUTPUT_QUEUE_NAME - The name of the Azure Storage Queue to use for output in the Azure Function tool. + 6) STORAGE_QUEUE_SERVICE_ENDPOINT - The endpoint of the Azure Storage Queue service. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -45,58 +47,53 @@ agent = None endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = AzureFunctionTool( - azure_function=AzureFunctionDefinition( - input_binding=AzureFunctionBinding( - storage_queue=AzureFunctionStorageQueue( - queue_name=os.environ["STORAGE_INPUT_QUEUE_NAME"], - queue_service_endpoint=os.environ["STORAGE_QUEUE_SERVICE_ENDPOINT"], - ) - ), - output_binding=AzureFunctionBinding( - storage_queue=AzureFunctionStorageQueue( - queue_name=os.environ["STORAGE_OUTPUT_QUEUE_NAME"], - queue_service_endpoint=os.environ["STORAGE_QUEUE_SERVICE_ENDPOINT"], - ) - ), - function=AzureFunctionDefinitionFunction( - name="queue_trigger", - description="Get weather for a given location", - parameters={ - "type": "object", - "properties": {"location": {"type": "string", "description": "location to determine weather for"}}, - }, - ), - ) +tool = AzureFunctionTool( + azure_function=AzureFunctionDefinition( + input_binding=AzureFunctionBinding( + storage_queue=AzureFunctionStorageQueue( + queue_name=os.environ["STORAGE_INPUT_QUEUE_NAME"], + queue_service_endpoint=os.environ["STORAGE_QUEUE_SERVICE_ENDPOINT"], + ) + ), + output_binding=AzureFunctionBinding( + storage_queue=AzureFunctionStorageQueue( + queue_name=os.environ["STORAGE_OUTPUT_QUEUE_NAME"], + queue_service_endpoint=os.environ["STORAGE_QUEUE_SERVICE_ENDPOINT"], + ) + ), + function=AzureFunctionDefinitionFunction( + name="queue_trigger", + description="Get weather for a given location", + parameters={ + "type": "object", + "properties": {"location": {"type": "string", "description": "location to determine weather for"}}, + }, + ), ) +) - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): user_input = "What is the weather in Seattle?" response = openai_client.responses.create( tool_choice="required", input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") - - print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_custom_search.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_custom_search.py index 0f52fbfa8e47..1ba8ddba0f8f 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_custom_search.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_custom_search.py @@ -31,14 +31,16 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID - The Bing Custom Search project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID - The Bing Custom Search project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. - 4) BING_CUSTOM_SEARCH_INSTANCE_NAME - The Bing Custom Search instance name - 5) BING_CUSTOM_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. + 5) BING_CUSTOM_SEARCH_INSTANCE_NAME - The Bing Custom Search instance name + 6) BING_CUSTOM_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -51,42 +53,41 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = BingCustomSearchPreviewTool( - bing_custom_search_preview=BingCustomSearchToolParameters( - search_configurations=[ - BingCustomSearchConfiguration( - project_connection_id=os.environ["BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID"], - instance_name=os.environ["BING_CUSTOM_SEARCH_INSTANCE_NAME"], - ) - ] - ) +tool = BingCustomSearchPreviewTool( + bing_custom_search_preview=BingCustomSearchToolParameters( + search_configurations=[ + BingCustomSearchConfiguration( + project_connection_id=os.environ["BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID"], + instance_name=os.environ["BING_CUSTOM_SEARCH_INSTANCE_NAME"], + ) + ] ) +) - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], 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=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): user_input = os.environ.get("BING_CUSTOM_USER_INPUT") or input("Enter your question: \n") # Send initial request that will trigger the Bing Custom Search tool stream_response = openai_client.responses.create( stream=True, input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -111,7 +112,3 @@ elif event.type == "response.completed": print("\nFollow-up completed!") print(f"Full response: {event.response.output_text}") - - print("Cleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_grounding.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_grounding.py index 735462eb82b0..8fbf96112bfc 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_grounding.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_bing_grounding.py @@ -39,11 +39,13 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) BING_PROJECT_CONNECTION_ID - The Bing project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) BING_PROJECT_CONNECTION_ID - The Bing project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -56,37 +58,36 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = BingGroundingTool( - bing_grounding=BingGroundingSearchToolParameters( - search_configurations=[ - BingGroundingSearchConfiguration(project_connection_id=os.environ["BING_PROJECT_CONNECTION_ID"]) - ] - ) +tool = BingGroundingTool( + bing_grounding=BingGroundingSearchToolParameters( + search_configurations=[ + BingGroundingSearchConfiguration(project_connection_id=os.environ["BING_PROJECT_CONNECTION_ID"]) + ] ) +) - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[tool], ), description="You are a helpful agent.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): stream_response = openai_client.responses.create( stream=True, tool_choice="required", input="What is today's date and whether in Seattle?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -107,7 +108,3 @@ elif event.type == "response.completed": print("\nFollow-up completed!") print(f"Full response: {event.response.output_text}") - - print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_browser_automation.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_browser_automation.py index 54471e71aff4..57645de43e4e 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_browser_automation.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_browser_automation.py @@ -21,13 +21,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) BROWSER_AUTOMATION_PROJECT_CONNECTION_ID - The browser automation project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) BROWSER_AUTOMATION_PROJECT_CONNECTION_ID - The browser automation project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. """ import os import json from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -40,44 +42,43 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = BrowserAutomationPreviewTool( - browser_automation_preview=BrowserAutomationToolParameters( - connection=BrowserAutomationToolConnectionParameters( - project_connection_id=os.environ["BROWSER_AUTOMATION_PROJECT_CONNECTION_ID"], - ) +tool = BrowserAutomationPreviewTool( + browser_automation_preview=BrowserAutomationToolParameters( + connection=BrowserAutomationToolConnectionParameters( + project_connection_id=os.environ["BROWSER_AUTOMATION_PROJECT_CONNECTION_ID"], ) ) +) - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], 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.""", + You can answer questions, provide information, and assist with various tasks + related to web browsing using the Browser Automation tool available to you.""", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): stream_response = openai_client.responses.create( stream=True, tool_choice="required", input=""" - 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.""", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, + 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.""", ) for event in stream_response: @@ -101,7 +102,3 @@ elif event.type == "response.completed": print("\nFollow-up completed!") print(f"Full response: {event.response.output_text}") - - print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter.py index d1da6fcd4181..bc25886352e3 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter.py @@ -21,10 +21,12 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, CodeInterpreterTool @@ -32,27 +34,23 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - tool = CodeInterpreterTool() - - # Create agent with code interpreter tool - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", - tools=[tool], + tools=[CodeInterpreterTool()], ), description="Code interpreter agent for data analysis and visualization.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Create a conversation for the agent interaction conversation = openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -61,7 +59,6 @@ response = openai_client.responses.create( conversation=conversation.id, input="Could you please generate a multiplication chart showing the products for 1-10 multiplied by 1-10 (a 10x10 times table)?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, tool_choice="required", ) print(f"Response completed (id: {response.id})") @@ -75,5 +72,3 @@ print(f"Agent response: {response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_async.py index 5371a781e75a..0c54d31371fd 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_async.py @@ -21,11 +21,13 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import asyncio import os from dotenv import load_dotenv +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, CodeInterpreterTool @@ -33,27 +35,25 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main() -> None: async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - - # Create agent with code interpreter tool - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[CodeInterpreterTool()], ), description="Code interpreter agent for data analysis and visualization.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): # Create a conversation for the agent interaction conversation = await openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -62,7 +62,6 @@ async def main() -> None: response = await openai_client.responses.create( conversation=conversation.id, input="Could you please generate a multiplication chart showing the products for 1-10 multiplied by 1-10 (a 10x10 times table)?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, tool_choice="required", ) print(f"Response completed (id: {response.id})") @@ -75,10 +74,6 @@ async def main() -> None: # Print final assistant text output. print(f"Agent response: {response.output_text}") - print("\nCleaning up...") - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_structured_inputs.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_structured_inputs.py index 15921ab7fd2c..f631ca4ed14b 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_structured_inputs.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_structured_inputs.py @@ -27,6 +27,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -74,7 +75,7 @@ # Create agent with code interpreter tool agent = project_client.agents.create_version( - agent_name="MyAgent", + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=agent_definition, description="Code interpreter agent for data analysis and visualization.", ) diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files.py index 3421bd5715d9..c4891fc02731 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files.py @@ -21,6 +21,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -55,7 +56,7 @@ # Create agent with code interpreter tool agent = project_client.agents.create_version( - agent_name="MyAgent", + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files_async.py index 88b59c545e49..49a7f1112856 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_code_interpreter_with_files_async.py @@ -21,6 +21,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -57,7 +58,7 @@ async def main() -> None: # Create agent with code interpreter tool agent = await project_client.agents.create_version( - agent_name="MyAgent", + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use.py index 59e5af777531..2c6cab4d70ab 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use.py @@ -27,10 +27,12 @@ page of your Microsoft Foundry portal. 2) (Optional) COMPUTER_USE_MODEL_DEPLOYMENT_NAME - The deployment name of the computer-use-preview model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint # Import shared helper functions from computer_use_util import ( # pylint: disable=import-error @@ -46,40 +48,40 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - # Initialize state machine - current_state = SearchState.INITIAL +# Initialize state machine +current_state = SearchState.INITIAL - # Load screenshot assets - try: - screenshots = load_screenshot_assets() - print("Successfully loaded screenshot assets") - except FileNotFoundError: - print("Failed to load required screenshot assets. Please ensure the asset files exist in ../assets/") - exit(1) # pylint: disable=consider-using-sys-exit +# Load screenshot assets +try: + screenshots = load_screenshot_assets() + print("Successfully loaded screenshot assets") +except FileNotFoundError: + print("Failed to load required screenshot assets. Please ensure the asset files exist in ../assets/") + exit(1) # pylint: disable=consider-using-sys-exit - tool = ComputerUsePreviewTool(display_width=1026, display_height=769, environment="windows") +tool = ComputerUsePreviewTool(display_width=1026, display_height=769, environment="windows") - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ.get("COMPUTER_USE_MODEL_DEPLOYMENT_NAME", "computer-use-preview"), instructions=""" - You are a computer automation assistant. + You are a computer automation assistant. - Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see. - """, + Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see. + """, tools=[tool], ), description="Computer automation agent with screen interaction capabilities.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Initial request with screenshot - start with Bing search page print("Starting computer automation session (initial screenshot: cua_browser_search.png)...") response = openai_client.responses.create( @@ -95,11 +97,10 @@ "type": "input_image", "image_url": screenshots["browser_search"]["url"], "detail": "high", - }, # Start with Bing search page + }, ], } ], - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, truncation="auto", ) @@ -149,12 +150,9 @@ }, } ], - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, truncation="auto", ) print(f"Follow-up response received (ID: {response.id})") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use_async.py index 5fd68ef7eda6..3ac457361d7a 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_computer_use_async.py @@ -27,12 +27,14 @@ page of your Microsoft Foundry portal. 2) (Optional) COMPUTER_USE_MODEL_DEPLOYMENT_NAME - The deployment name of the computer-use-preview model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ # pylint: disable=pointless-string-statement import asyncio import os from dotenv import load_dotenv +from util import create_version_with_endpoint_async from computer_use_util import ( # pylint: disable=import-error SearchState, load_screenshot_assets, @@ -46,44 +48,45 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main(): + """Main async function to demonstrate Computer Use Agent functionality.""" + # Initialize state machine + current_state = SearchState.INITIAL + + # Load screenshot assets + try: + screenshots = load_screenshot_assets() + print("Successfully loaded screenshot assets") + except FileNotFoundError: + print("Failed to load required screenshot assets. Please ensure the asset files exist in ../assets/") + return + + computer_use_tool = ComputerUsePreviewTool(display_width=1026, display_height=769, environment="windows") async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - - """Main async function to demonstrate Computer Use Agent functionality.""" - # Initialize state machine - current_state = SearchState.INITIAL - - # Load screenshot assets - try: - screenshots = load_screenshot_assets() - print("Successfully loaded screenshot assets") - except FileNotFoundError: - print("Failed to load required screenshot assets. Please ensure the asset files exist in ../assets/") - return - - computer_use_tool = ComputerUsePreviewTool(display_width=1026, display_height=769, environment="windows") - - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ.get("COMPUTER_USE_MODEL_DEPLOYMENT_NAME", "computer-use-preview"), instructions=""" - You are a computer automation assistant. + You are a computer automation assistant. - Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see. - """, + Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see. + """, tools=[computer_use_tool], ), description="Computer automation agent with screen interaction capabilities.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Initial request with screenshot - start with Bing search page print("Starting computer automation session (initial screenshot: cua_browser_search.png)...") @@ -100,11 +103,10 @@ async def main(): "type": "input_image", "image_url": screenshots["browser_search"]["url"], "detail": "high", - }, # Start with Bing search page + }, ], } ], - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, truncation="auto", ) @@ -156,15 +158,12 @@ async def main(): }, } ], - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, truncation="auto", ) print(f"Follow-up response received (ID: {response.id})") print("\nCleaning up...") - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") if __name__ == "__main__": diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric.py index 587394c4e1aa..620609ccc664 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric.py @@ -21,13 +21,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) FABRIC_PROJECT_CONNECTION_ID - The Fabric project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) FABRIC_PROJECT_CONNECTION_ID - The Fabric project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. - 4) FABRIC_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. + 5) FABRIC_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -40,37 +42,34 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +tool = MicrosoftFabricPreviewTool( + fabric_dataagent_preview=FabricDataAgentToolParameters( + project_connections=[ToolProjectConnection(project_connection_id=os.environ["FABRIC_PROJECT_CONNECTION_ID"])] + ) +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = MicrosoftFabricPreviewTool( - fabric_dataagent_preview=FabricDataAgentToolParameters( - project_connections=[ - ToolProjectConnection(project_connection_id=os.environ["FABRIC_PROJECT_CONNECTION_ID"]) - ] - ) - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): user_input = os.environ.get("FABRIC_USER_INPUT") or input("Enter your question: \n") stream_response = openai_client.responses.create( tool_choice="required", stream=True, input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -97,5 +96,3 @@ print(f"Full response: {event.response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq.py index f43fba64a401..98eb521f9968 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq.py @@ -21,12 +21,14 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) FABRIC_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the Fabric IQ project connection. - 4) FABRIC_IQ_USER_INPUT - The natural-language question to send to the agent. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) FABRIC_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the Fabric IQ project connection. + 5) FABRIC_IQ_USER_INPUT - The natural-language question to send to the agent. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, FabricIQPreviewTool @@ -34,36 +36,33 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +tool_payload = FabricIQPreviewTool( + project_connection_id=os.environ["FABRIC_IQ_PROJECT_CONNECTION_ID"], + require_approval="never", +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool_payload = FabricIQPreviewTool( - project_connection_id=os.environ["FABRIC_IQ_PROJECT_CONNECTION_ID"], - require_approval="never", - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Use the available Fabric IQ tools to answer questions and perform tasks.", tools=[tool_payload], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): user_input = os.environ.get("FABRIC_IQ_USER_INPUT") or input("Enter your question:\n") response = openai_client.responses.create( input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - # Clean up the agent version so unused versions don't accumulate in the project. - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") + # The helper restores the endpoint and deletes the temporary version automatically. diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq_async.py index bdd5881cba07..a0c85a5246c1 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_fabric_iq_async.py @@ -21,13 +21,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) FABRIC_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the Fabric IQ project connection. - 4) FABRIC_IQ_USER_INPUT - The natural-language question to send to the agent. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) FABRIC_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the Fabric IQ project connection. + 5) FABRIC_IQ_USER_INPUT - The natural-language question to send to the agent. """ import os import asyncio from dotenv import load_dotenv +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, FabricIQPreviewTool @@ -35,42 +37,40 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main(): + tool_payload = FabricIQPreviewTool( + project_connection_id=os.environ["FABRIC_IQ_PROJECT_CONNECTION_ID"], + require_approval="never", + ) + async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - tool_payload = FabricIQPreviewTool( - project_connection_id=os.environ["FABRIC_IQ_PROJECT_CONNECTION_ID"], - require_approval="never", - ) - - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Use the available Fabric IQ tools to answer questions and perform tasks.", tools=[tool_payload], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") user_input = os.environ.get("FABRIC_IQ_USER_INPUT") or input("Enter your question:\n") response = await openai_client.responses.create( input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - # Clean up the agent version so unused versions don't accumulate in the project. - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search.py index e6f64c060be0..fc6e7da22dd8 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search.py @@ -20,6 +20,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -55,7 +56,7 @@ # Create agent with file search tool agent = project_client.agents.create_version( - agent_name="MyAgent", + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that can search through product information.", diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search_structured_inputs.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search_structured_inputs.py index f9af76a1c920..c2e04b85efa5 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search_structured_inputs.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_file_search_structured_inputs.py @@ -22,10 +22,11 @@ Set these environment variables with your own values: 1) FOUNDRY_PROJECT_ENDPOINT (preferred) or AZURE_AI_PROJECT_ENDPOINT - The Azure AI Project endpoint. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". NOTES: This sample is intentionally kept very close to `sample_agent_file_search.py`. - It does not include fallback logic. + It demonstrates the same `FOUNDRY_AGENT_NAME` fallback behavior with structured inputs. """ import os @@ -83,7 +84,7 @@ # Create agent with file search tool agent = project_client.agents.create_version( - agent_name="MyAgent", + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=agent_definition, description="File search agent for product information queries.", ) diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool.py index 991406256f1a..09a096784dfc 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool.py @@ -21,6 +21,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ # pylint: disable=docstring-missing-param,docstring-missing-return,docstring-missing-rtype @@ -28,12 +29,15 @@ import json from dotenv import load_dotenv from openai.types.responses.response_input_param import FunctionCallOutput, ResponseInputParam +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, FunctionTool load_dotenv() +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + def get_horoscope(sign: str) -> str: """Generate a horoscope for the given astrological sign.""" @@ -42,42 +46,41 @@ def get_horoscope(sign: str) -> str: endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = FunctionTool( - name="get_horoscope", - parameters={ - "type": "object", - "properties": { - "sign": { - "type": "string", - "description": "An astrological sign like Taurus or Aquarius", - }, +tool = FunctionTool( + name="get_horoscope", + parameters={ + "type": "object", + "properties": { + "sign": { + "type": "string", + "description": "An astrological sign like Taurus or Aquarius", }, - "required": ["sign"], - "additionalProperties": False, }, - description="Get today's horoscope for an astrological sign.", - strict=True, - ) + "required": ["sign"], + "additionalProperties": False, + }, + description="Get today's horoscope for an astrological sign.", + strict=True, +) - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that can use function tools.", tools=[tool], ), - ) - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Prompt the model with tools defined response = openai_client.responses.create( input="What is my horoscope? I am an Aquarius.", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") @@ -104,11 +107,8 @@ def get_horoscope(sign: str) -> str: response = openai_client.responses.create( input=input_list, previous_response_id=response.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool_async.py index 249f9a936419..55d1d574cc09 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_function_tool_async.py @@ -22,6 +22,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ # pylint: disable=docstring-missing-param,docstring-missing-return,docstring-missing-rtype @@ -30,6 +31,7 @@ import asyncio from dotenv import load_dotenv from openai.types.responses.response_input_param import FunctionCallOutput, ResponseInputParam +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, FunctionTool @@ -37,6 +39,7 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def get_horoscope(sign: str) -> str: @@ -45,42 +48,44 @@ async def get_horoscope(sign: str) -> str: async def main(): - async with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - # Define a function tool for the model to use - func_tool = FunctionTool( - name="get_horoscope", - parameters={ - "type": "object", - "properties": { - "sign": { - "type": "string", - "description": "An astrological sign like Taurus or Aquarius", - }, + # Define a function tool for the model to use + func_tool = FunctionTool( + name="get_horoscope", + parameters={ + "type": "object", + "properties": { + "sign": { + "type": "string", + "description": "An astrological sign like Taurus or Aquarius", }, - "required": ["sign"], - "additionalProperties": False, }, - description="Get today's horoscope for an astrological sign.", - strict=True, - ) + "required": ["sign"], + "additionalProperties": False, + }, + description="Get today's horoscope for an astrological sign.", + strict=True, + ) - agent = await project_client.agents.create_version( - agent_name="MyAgent", + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that can use function tools.", tools=[func_tool], ), - ) + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Prompt the model with tools defined response = await openai_client.responses.create( input="What is my horoscope? I am an Aquarius.", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") @@ -107,7 +112,6 @@ async def main(): response = await openai_client.responses.create( input=input_list, previous_response_id=response.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation.py index b1a4e20fda11..82c3e75d6839 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation.py @@ -32,7 +32,8 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the chat model (e.g., gpt-4o, gpt-4o-mini, gpt-5o, gpt-5o-mini) used by the Agent for understanding and responding to prompts. This is NOT the image generation model. - 3) IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME - The deployment name of the image generation model (e.g. gpt-image-1) + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME - The deployment name of the image generation model (e.g. gpt-image-1) used by the ImageGenTool. NOTE: @@ -45,7 +46,9 @@ import base64 import os import tempfile +from pathlib import Path from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient @@ -54,51 +57,44 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +image_generation_model = os.environ["IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME"] + +tool = ImageGenTool( + model=image_generation_model, # Model such as "gpt-image-1" + quality="low", + size="1024x1024", +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - image_generation_model = os.environ["IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME"] - - tool = ImageGenTool( - model=image_generation_model, # Model such as "gpt-image-1" - quality="low", - size="1024x1024", - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Generate images based on user prompts", tools=[tool], ), description="Agent for image generation.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): response = openai_client.responses.create( input="Generate an image of Microsoft logo.", extra_headers={ "x-ms-oai-image-generation-deployment": image_generation_model }, # this is required at the moment for image generation - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response created: {response.id}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") image_data = [output.result for output in response.output if output.type == "image_generation_call"] if image_data and image_data[0]: print("Downloading generated image...") filename = "microsoft.png" - file_path = os.path.join(tempfile.gettempdir(), filename) - - with open(file_path, "wb") as f: - f.write(base64.b64decode(image_data[0])) - + file_path = Path(tempfile.gettempdir()) / filename + file_path.write_bytes(base64.b64decode(image_data[0])) print(f"Image saved to: {file_path}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation_async.py index 37fa57e82a16..cd6444fdcdf3 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_image_generation_async.py @@ -32,7 +32,8 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the chat model (e.g., gpt-4o, gpt-4o-mini, gpt-5o, gpt-5o-mini) used by the Agent for understanding and responding to prompts. This is NOT the image generation model. - 3) IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME - The deployment name of the image generation model (e.g. gpt-image-1) + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME - The deployment name of the image generation model (e.g. gpt-image-1) used by the ImageGenTool. NOTE: @@ -46,7 +47,9 @@ import base64 import os import tempfile +from pathlib import Path from dotenv import load_dotenv +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient @@ -54,51 +57,46 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +image_generation_model = os.environ["IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME"] async def main(): async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - - image_generation_model = os.environ["IMAGE_GENERATION_MODEL_DEPLOYMENT_NAME"] - - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Generate images based on user prompts", tools=[ImageGenTool(model=image_generation_model, quality="low", size="1024x1024")], ), description="Agent for image generation.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") response = await openai_client.responses.create( input="Generate an image of Microsoft logo.", extra_headers={ "x-ms-oai-image-generation-deployment": image_generation_model }, # this is required at the moment for image generation - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response created: {response.id}") print("\nCleaning up...") - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") # Save the image to a file image_data = [output.result for output in response.output if output.type == "image_generation_call"] if image_data and image_data[0]: print("Downloading generated image...") filename = "microsoft.png" - file_path = os.path.join(tempfile.gettempdir(), filename) - - with open(file_path, "wb") as f: - f.write(base64.b64decode(image_data[0])) - + file_path = Path(tempfile.gettempdir()) / filename + file_path.write_bytes(base64.b64decode(image_data[0])) print(f"Image saved to: {file_path}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp.py index 934a83781e92..03ba643cf794 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp.py @@ -21,11 +21,13 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv from openai.types.responses.response_input_param import McpApprovalResponse, ResponseInputParam +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, MCPTool @@ -33,28 +35,28 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +mcp_tool = MCPTool( + server_label="api-specs", + server_url="https://gitmcp.io/Azure/azure-rest-api-specs", + require_approval="always", +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - mcp_tool = MCPTool( - server_label="api-specs", - server_url="https://gitmcp.io/Azure/azure-rest-api-specs", - require_approval="always", - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.", tools=[mcp_tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Create a conversation thread to maintain context across multiple interactions conversation = openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -63,7 +65,6 @@ response = openai_client.responses.create( conversation=conversation.id, input="Please summarize the Azure REST API specifications Readme", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) # Process any MCP approval requests that were generated @@ -89,12 +90,6 @@ response = openai_client.responses.create( input=input_list, previous_response_id=response.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - - # Clean up resources by deleting the agent version - # This prevents accumulation of unused agent versions in your project - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_async.py index 55c32cd0602c..83eb878eb648 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_async.py @@ -21,12 +21,14 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os import asyncio from dotenv import load_dotenv from openai.types.responses.response_input_param import McpApprovalResponse, ResponseInputParam +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, MCPTool, Tool @@ -34,33 +36,35 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main(): + mcp_tool = MCPTool( + server_label="api-specs", + server_url="https://gitmcp.io/Azure/azure-rest-api-specs", + require_approval="always", + ) + + # Create tools list with proper typing for the agent definition + tools: list[Tool] = [mcp_tool] + async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - mcp_tool = MCPTool( - server_label="api-specs", - server_url="https://gitmcp.io/Azure/azure-rest-api-specs", - require_approval="always", - ) - - # Create tools list with proper typing for the agent definition - tools: list[Tool] = [mcp_tool] - - # Create a prompt agent with MCP tool capabilities - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.", tools=tools, ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Create a conversation thread to maintain context across multiple interactions conversation = await openai_client.conversations.create() @@ -70,7 +74,6 @@ async def main(): response = await openai_client.responses.create( conversation=conversation.id, input="Please summarize the Azure REST API specifications Readme", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) # Process any MCP approval requests that were generated @@ -96,16 +99,10 @@ async def main(): response = await openai_client.responses.create( input=input_list, previous_response_id=response.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - # Clean up resources by deleting the agent version - # This prevents accumulation of unused agent versions in your project - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection.py index 3042ac9458db..69816267de85 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection.py @@ -20,7 +20,8 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys with key equals to "Authorization" and value to be "Bearer ". Token can be created in https://github.com/settings/personal-access-tokens/new """ @@ -28,6 +29,7 @@ import os from dotenv import load_dotenv from openai.types.responses.response_input_param import McpApprovalResponse, ResponseInputParam +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, MCPTool @@ -35,31 +37,30 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + + +tool = MCPTool( + server_label="api-specs", + server_url="https://api.githubcopilot.com/mcp", + require_approval="always", + project_connection_id=os.environ["MCP_PROJECT_CONNECTION_ID"], +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - tool = MCPTool( - server_label="api-specs", - server_url="https://api.githubcopilot.com/mcp", - require_approval="always", - project_connection_id=os.environ["MCP_PROJECT_CONNECTION_ID"], - ) - - # Create a prompt agent with MCP tool capabilities - agent = project_client.agents.create_version( - agent_name="MyAgent7", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Use MCP tools as needed", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Create a conversation thread to maintain context across multiple interactions conversation = openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -68,7 +69,6 @@ response = openai_client.responses.create( conversation=conversation.id, input="What is my username in Github profile?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) # Process any MCP approval requests that were generated @@ -94,12 +94,6 @@ response = openai_client.responses.create( input=input_list, previous_response_id=response.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response: {response.output_text}") - - # Clean up resources by deleting the agent version - # This prevents accumulation of unused agent versions in your project - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection_async.py index 8de0155f94ec..d9dbcd020214 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_mcp_with_project_connection_async.py @@ -20,7 +20,8 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys with key equals to "Authorization" and value to be "Bearer ". Token can be created in https://github.com/settings/personal-access-tokens/new """ @@ -29,6 +30,7 @@ import asyncio from dotenv import load_dotenv from openai.types.responses.response_input_param import McpApprovalResponse, ResponseInputParam +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, MCPTool, Tool @@ -36,34 +38,36 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main(): + mcp_tool = MCPTool( + server_label="api-specs", + server_url="https://api.githubcopilot.com/mcp", + require_approval="always", + project_connection_id=os.environ["MCP_PROJECT_CONNECTION_ID"], + ) + + # Create tools list with proper typing for the agent definition + tools: list[Tool] = [mcp_tool] + async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - mcp_tool = MCPTool( - server_label="api-specs", - server_url="https://api.githubcopilot.com/mcp", - require_approval="always", - project_connection_id=os.environ["MCP_PROJECT_CONNECTION_ID"], - ) - - # Create tools list with proper typing for the agent definition - tools: list[Tool] = [mcp_tool] - - # Create a prompt agent with MCP tool capabilities - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Use MCP tools as needed", tools=tools, ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Create a conversation thread to maintain context across multiple interactions conversation = await openai_client.conversations.create() @@ -73,7 +77,6 @@ async def main(): response = await openai_client.responses.create( conversation=conversation.id, input="What is my username in GitHub profile?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) # Process any MCP approval requests that were generated @@ -98,16 +101,10 @@ async def main(): response = await openai_client.responses.create( input=input_list, previous_response_id=response.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response: {response.output_text}") - # Clean up resources by deleting the agent version - # This prevents accumulation of unused agent versions in your project - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - if __name__ == "__main__": # Run the async main function diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search.py index 433b315b2920..da339d10d3bd 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search.py @@ -27,15 +27,17 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the Agent's AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME - The deployment name of the chat model for memory, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME - The deployment name of the chat model for memory, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 4) MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME - The deployment name of the embedding model for memory, + 5) MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME - The deployment name of the embedding model for memory, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. """ import os import time from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.core.exceptions import ResourceNotFoundError from azure.ai.projects import AIProjectClient @@ -48,54 +50,58 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +AGENT_NAME = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +credential = DefaultAzureCredential() +project_client = AIProjectClient(endpoint=endpoint, credential=credential) + +# Delete memory store, if it already exists +memory_store_name = "my_memory_store" +try: + project_client.beta.memory_stores.delete(memory_store_name) + print(f"Memory store `{memory_store_name}` deleted") +except ResourceNotFoundError: + pass + +# Create a memory store +definition = MemoryStoreDefaultDefinition( + chat_model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"], + embedding_model=os.environ["MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME"], +) +memory_store = project_client.beta.memory_stores.create( + name=memory_store_name, + description="Example memory store for conversations", + definition=definition, +) +print(f"Created memory store: {memory_store.name} ({memory_store.id}): {memory_store.description}") -with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - # Delete memory store, if it already exists - memory_store_name = "my_memory_store" - try: - project_client.beta.memory_stores.delete(memory_store_name) - print(f"Memory store `{memory_store_name}` deleted") - except ResourceNotFoundError: - pass - - # Create a memory store - definition = MemoryStoreDefaultDefinition( - chat_model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"], - embedding_model=os.environ["MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME"], - ) - memory_store = project_client.beta.memory_stores.create( - name=memory_store_name, - description="Example memory store for conversations", - definition=definition, - ) - print(f"Created memory store: {memory_store.name} ({memory_store.id}): {memory_store.description}") - - # Set scope to associate the memories with - # You can also use "{{$userId}}" to take the oid of the request authentication header - scope = "user_123" +# Set scope to associate the memories with +# You can also use "{{$userId}}" to take the oid of the request authentication header +scope = "user_123" - tool = MemorySearchPreviewTool( - memory_store_name=memory_store.name, - scope=scope, - update_delay=1, # Wait 1 second of inactivity before updating memories - # In a real application, set this to a higher value like 300 (5 minutes, default) - ) +tool = MemorySearchPreviewTool( + memory_store_name=memory_store.name, + scope=scope, + update_delay=1, # Wait 1 second of inactivity before updating memories + # In a real application, set this to a higher value like 300 (5 minutes, default) +) - # Create a prompt agent with memory search tool - agent = project_client.agents.create_version( - agent_name="MyAgent", +with ( + credential, + project_client, + create_version_with_endpoint( + project_client=project_client, + agent_name=AGENT_NAME, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=AGENT_NAME) as openai_client, +): + agent = project_client.agents.get(agent_name=AGENT_NAME) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Create a conversation with the agent with memory tool enabled conversation = openai_client.conversations.create() @@ -105,7 +111,6 @@ response = openai_client.responses.create( input="I prefer dark roast coffee", conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") @@ -121,7 +126,6 @@ new_response = openai_client.responses.create( input="Please order my usual coffee", conversation=new_conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {new_response.output_text}") @@ -130,8 +134,5 @@ openai_client.conversations.delete(new_conversation.id) print("Conversations deleted") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - - project_client.beta.memory_stores.delete(memory_store.name) - print("Memory store deleted") +project_client.beta.memory_stores.delete(memory_store.name) +print("Memory store deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search_async.py index d69d5dea0751..7f151e983e4c 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_memory_search_async.py @@ -27,15 +27,17 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the Agent's AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME - The deployment name of the chat model for memory, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME - The deployment name of the chat model for memory, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 4) MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME - The deployment name of the embedding model for memory, + 5) MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME - The deployment name of the embedding model for memory, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. """ import asyncio import os from dotenv import load_dotenv +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.core.exceptions import ResourceNotFoundError from azure.ai.projects.aio import AIProjectClient @@ -47,44 +49,46 @@ load_dotenv() +AGENT_NAME = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + async def main() -> None: endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] - async with ( - DefaultAzureCredential() as credential, - AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - - # Delete memory store, if it already exists - memory_store_name = "my_memory_store" - try: - await project_client.beta.memory_stores.delete(memory_store_name) - print(f"Memory store `{memory_store_name}` deleted") - except ResourceNotFoundError: - pass - - # Create a memory store - definition = MemoryStoreDefaultDefinition( - chat_model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"], - embedding_model=os.environ["MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME"], - ) - memory_store = await project_client.beta.memory_stores.create( - name=memory_store_name, - description="Example memory store for conversations", - definition=definition, - ) - print(f"Created memory store: {memory_store.name} ({memory_store.id}): {memory_store.description}") + credential = DefaultAzureCredential() + project_client = AIProjectClient(endpoint=endpoint, credential=credential) + + # Delete memory store, if it already exists + memory_store_name = "my_memory_store" + try: + await project_client.beta.memory_stores.delete(memory_store_name) + print(f"Memory store `{memory_store_name}` deleted") + except ResourceNotFoundError: + pass + + # Create a memory store + definition = MemoryStoreDefaultDefinition( + chat_model=os.environ["MEMORY_STORE_CHAT_MODEL_DEPLOYMENT_NAME"], + embedding_model=os.environ["MEMORY_STORE_EMBEDDING_MODEL_DEPLOYMENT_NAME"], + ) + memory_store = await project_client.beta.memory_stores.create( + name=memory_store_name, + description="Example memory store for conversations", + definition=definition, + ) + print(f"Created memory store: {memory_store.name} ({memory_store.id}): {memory_store.description}") + + # Set scope to associate the memories with + # You can also use "{{$userId}}" to take the oid of the request authentication header + scope = "user_123" - # Set scope to associate the memories with - # You can also use "{{$userId}}" to take the oid of the request authentication header - scope = "user_123" - - # Create a prompt agent with memory search tool - agent = await project_client.agents.create_version( - agent_name="MyAgent", + async with ( + credential, + project_client, + create_version_with_endpoint_async( + project_client=project_client, + agent_name=AGENT_NAME, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", @@ -97,8 +101,11 @@ async def main() -> None: ) ], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=AGENT_NAME) as openai_client, + ): + agent = await project_client.agents.get(agent_name=AGENT_NAME) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") # Create a conversation with the agent with memory tool enabled conversation = await openai_client.conversations.create() @@ -108,7 +115,6 @@ async def main() -> None: response = await openai_client.responses.create( input="I prefer dark roast coffee", conversation=conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {response.output_text}") @@ -124,7 +130,6 @@ async def main() -> None: new_response = await openai_client.responses.create( input="Please order my usual coffee", conversation=new_conversation.id, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Response output: {new_response.output_text}") @@ -133,11 +138,8 @@ async def main() -> None: await openai_client.conversations.delete(new_conversation.id) print("Conversations deleted") - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - - await project_client.beta.memory_stores.delete(memory_store.name) - print("Memory store deleted") + await project_client.beta.memory_stores.delete(memory_store.name) + print("Memory store deleted") if __name__ == "__main__": diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi.py index 729971029a6d..068205c2c0e9 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi.py @@ -21,12 +21,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from typing import Any, cast +from pathlib import Path import jsonref from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -39,43 +42,34 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +weather_asset_file_path = Path(__file__).resolve().parent / "../assets/weather_openapi.json" +openapi_weather = cast(dict[str, Any], jsonref.loads(weather_asset_file_path.read_text(encoding="utf-8"))) + +tool = OpenApiTool( + openapi=OpenApiFunctionDefinition( + name="get_weather", + spec=openapi_weather, + description="Retrieve weather information for a location.", + auth=OpenApiAnonymousAuthDetails(), + ) +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - weather_asset_file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../assets/weather_openapi.json")) - - with open(weather_asset_file_path, "r", encoding="utf-8") as f: - openapi_weather = cast(dict[str, Any], jsonref.loads(f.read())) - - tool = OpenApiTool( - openapi=OpenApiFunctionDefinition( - name="get_weather", - spec=openapi_weather, - description="Retrieve weather information for a location.", - auth=OpenApiAnonymousAuthDetails(), - ) - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): response = openai_client.responses.create( input="Use the OpenAPI tool to print out, what is the weather in Seattle today.", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - - print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi_with_project_connection.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi_with_project_connection.py index 890b7388608a..03e3cb47836e 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi_with_project_connection.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_openapi_with_project_connection.py @@ -22,14 +22,17 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) OPENAPI_PROJECT_CONNECTION_ID - The OpenAPI project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) OPENAPI_PROJECT_CONNECTION_ID - The OpenAPI project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. """ import os from typing import Any, cast +from pathlib import Path import jsonref from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -43,50 +46,39 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +tripadvisor_asset_file_path = Path(__file__).resolve().parent / "../assets/tripadvisor_openapi.json" +openapi_tripadvisor = cast(dict[str, Any], jsonref.loads(tripadvisor_asset_file_path.read_text(encoding="utf-8"))) + +tool = OpenApiTool( + openapi=OpenApiFunctionDefinition( + name="tripadvisor", + spec=openapi_tripadvisor, + description="Trip Advisor API to get travel information", + auth=OpenApiProjectConnectionAuthDetails( + security_scheme=OpenApiProjectConnectionSecurityScheme( + project_connection_id=os.environ["OPENAPI_PROJECT_CONNECTION_ID"] + ) + ), + ) +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - tripadvisor_asset_file_path = os.path.abspath( - os.path.join(os.path.dirname(__file__), "../assets/tripadvisor_openapi.json") - ) - - with open(tripadvisor_asset_file_path, "r", encoding="utf-8") as f: - openapi_tripadvisor = cast(dict[str, Any], jsonref.loads(f.read())) - - tool = OpenApiTool( - openapi=OpenApiFunctionDefinition( - name="tripadvisor", - spec=openapi_tripadvisor, - description="Trip Advisor API to get travel information", - auth=OpenApiProjectConnectionAuthDetails( - security_scheme=OpenApiProjectConnectionSecurityScheme( - project_connection_id=os.environ["OPENAPI_PROJECT_CONNECTION_ID"] - ) - ), - ) - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): response = openai_client.responses.create( input="Recommend me 5 top hotels in the United States", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) # The response to the question may contain non ASCII letters. To avoid error, encode and re decode them. print(f"Response created: {response.output_text.encode().decode('ascii', errors='ignore')}") - - print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_sharepoint.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_sharepoint.py index d1c4db82eb1c..77027e023598 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_sharepoint.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_sharepoint.py @@ -21,13 +21,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) SHAREPOINT_PROJECT_CONNECTION_ID - The SharePoint project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) SHAREPOINT_PROJECT_CONNECTION_ID - The SharePoint project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. - 4) SHAREPOINT_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. + 5) SHAREPOINT_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -40,31 +42,31 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +tool = SharepointPreviewTool( + sharepoint_grounding_preview=SharepointGroundingToolParameters( + project_connections=[ + ToolProjectConnection(project_connection_id=os.environ["SHAREPOINT_PROJECT_CONNECTION_ID"]) + ] + ) +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = SharepointPreviewTool( - sharepoint_grounding_preview=SharepointGroundingToolParameters( - project_connections=[ - ToolProjectConnection(project_connection_id=os.environ["SHAREPOINT_PROJECT_CONNECTION_ID"]) - ] - ) - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], 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=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Get user input from environment variable or prompt user_input = os.environ.get("SHAREPOINT_USER_INPUT") if not user_input: @@ -74,7 +76,6 @@ stream_response = openai_client.responses.create( stream=True, input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -101,5 +102,3 @@ print(f"Agent response: {event.response.output_text}") print("Cleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_to_agent.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_to_agent.py index edb7a46fc760..b31d434ff910 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_to_agent.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_to_agent.py @@ -23,15 +23,17 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) A2A_PROJECT_CONNECTION_ID - The A2A project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) A2A_PROJECT_CONNECTION_ID - The A2A project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. - 4) A2A_ENDPOINT - (Optional) If the connection is missing target i.e. if it is of "Custom keys" type, we need to set the A2A + 5) A2A_ENDPOINT - (Optional) If the connection is missing target i.e. if it is of "Custom keys" type, we need to set the A2A endpoint on the tool. - 5) A2A_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. + 6) A2A_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -42,30 +44,29 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +tool = A2APreviewTool( + project_connection_id=os.environ["A2A_PROJECT_CONNECTION_ID"], +) +# If the connection is missing target, we need to set the A2A endpoint URL. +if os.environ.get("A2A_ENDPOINT"): + tool.base_url = os.environ["A2A_ENDPOINT"] with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - - tool = A2APreviewTool( - project_connection_id=os.environ["A2A_PROJECT_CONNECTION_ID"], - ) - # If the connection is missing target, we need to set the A2A endpoint URL. - if os.environ.get("A2A_ENDPOINT"): - tool.base_url = os.environ["A2A_ENDPOINT"] - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant.", tools=[tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): user_input = os.environ.get("A2A_USER_INPUT") or input( "Enter your question (e.g., 'What can the secondary agent do?'): \n" ) @@ -74,7 +75,6 @@ stream=True, tool_choice="required", input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -99,5 +99,3 @@ print(f"Full response: {event.response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_toolbox_skill.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_toolbox_skill.py index 847a9d206333..f4e0e7de9e38 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_toolbox_skill.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_toolbox_skill.py @@ -33,6 +33,7 @@ 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -51,6 +52,7 @@ ToolboxSearchPreviewToolboxTool, ToolboxSkillReference, ) +from util import create_version_with_endpoint load_dotenv() @@ -58,13 +60,13 @@ SKILL_NAME = "shipping-cost-skill" TOOLBOX_NAME = "toolbox_with_skill" -AGENT_NAME = "SkillToolboxAgent" +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, + project_client.get_openai_client(agent_name=agent_name) as openai_client, ): try: @@ -110,8 +112,9 @@ require_approval="never", ) - agent = project_client.agents.create_version( - agent_name=AGENT_NAME, + with create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions=( @@ -124,29 +127,27 @@ temperature=0, tools=[toolbox_mcp_tool], ), - ) - print(f"Agent created (id={agent.id}, name={agent.name}, version={agent.version})") - - user_input = "Compute the shipping cost for a 3 kg package shipped domestically." - print(f"User: {user_input}") - response = openai_client.responses.create( - input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - - for item in response.output: - if item.type == "mcp_list_tools": - print(f"mcp_list_tools server_label={item.server_label} tools={[t.name for t in (item.tools or [])]}") - elif item.type == "mcp_call": - print(f"mcp_call server_label={item.server_label} name={item.name} error={item.error}") - if getattr(item, "output", None): - print(f" output: {item.output}") - elif item.type == "mcp_approval_request": - print(f"mcp_approval_request server_label={item.server_label} name={item.name}") - else: - print(f"output item type={item.type}") - - print(f"Response: {response.output_text}") + ) as agent: + + user_input = "Compute the shipping cost for a 3 kg package shipped domestically." + print(f"User: {user_input}") + response = openai_client.responses.create( + input=user_input, + ) + + for item in response.output: + if item.type == "mcp_list_tools": + print(f"mcp_list_tools server_label={item.server_label} tools={[t.name for t in (item.tools or [])]}") + elif item.type == "mcp_call": + print(f"mcp_call server_label={item.server_label} name={item.name} error={item.error}") + if getattr(item, "output", None): + print(f" output: {item.output}") + elif item.type == "mcp_approval_request": + print(f"mcp_approval_request server_label={item.server_label} name={item.name}") + else: + print(f"output item type={item.type}") + + print(f"Response: {response.output_text}") project_client.toolboxes.delete(TOOLBOX_NAME) print("Toolbox deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search.py index a08477e27096..c3075924be2b 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search.py @@ -30,10 +30,12 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient @@ -47,25 +49,24 @@ endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +tool = WebSearchTool(user_location=WebSearchApproximateLocation(country="GB", city="London", region="London")) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = WebSearchTool(user_location=WebSearchApproximateLocation(country="GB", city="London", region="London")) - # Create Agent with web search tool - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that can search the web", tools=[tool], ), description="Agent for web search.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Create a conversation for the agent interaction conversation = openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -76,7 +77,6 @@ stream=True, input=user_input, tool_choice="required", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -102,5 +102,3 @@ print("\nFollow-up completed!") print(f"Full response: {event.response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_preview.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_preview.py index cdef1789b143..b7b67ff7cf9b 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_preview.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_preview.py @@ -30,10 +30,12 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient @@ -43,25 +45,24 @@ endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +tool = WebSearchPreviewTool(user_location=ApproximateLocation(country="GB", city="London", region="London")) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = WebSearchPreviewTool(user_location=ApproximateLocation(country="GB", city="London", region="London")) - # Create Agent with web search tool - agent = project_client.agents.create_version( - agent_name="MyAgent105", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that can search the web", tools=[tool], ), description="Agent for web search.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Create a conversation for the agent interaction conversation = openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -72,7 +73,6 @@ stream=True, input=user_input, tool_choice="required", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -99,5 +99,3 @@ print(f"Full response: {event.response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_with_custom_search.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_with_custom_search.py index b66e18e00241..ee49edc5d545 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_with_custom_search.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_web_search_with_custom_search.py @@ -31,14 +31,16 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID - The Bing Custom Search project connection ID, + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID - The Bing Custom Search project connection ID, as found in the "Connections" tab in your Microsoft Foundry project. - 4) BING_CUSTOM_SEARCH_INSTANCE_NAME - The Bing Custom Search instance name - 5) BING_CUSTOM_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. + 5) BING_CUSTOM_SEARCH_INSTANCE_NAME - The Bing Custom Search instance name + 6) BING_CUSTOM_USER_INPUT - (Optional) The question to ask. If not set, you will be prompted. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient @@ -52,30 +54,29 @@ endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") +tool = WebSearchTool( + custom_search_configuration=WebSearchConfiguration( + project_connection_id=os.environ["BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID"], + instance_name=os.environ["BING_CUSTOM_SEARCH_INSTANCE_NAME"], + ) +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool = WebSearchTool( - custom_search_configuration=WebSearchConfiguration( - project_connection_id=os.environ["BING_CUSTOM_SEARCH_PROJECT_CONNECTION_ID"], - instance_name=os.environ["BING_CUSTOM_SEARCH_INSTANCE_NAME"], - ) - ) - # Create Agent with web search tool - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that can search the web and bing", tools=[tool], ), description="Agent for web search.", - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): # Create a conversation for the agent interaction conversation = openai_client.conversations.create() print(f"Created conversation (id: {conversation.id})") @@ -88,7 +89,6 @@ stream=True, input=user_input, tool_choice="required", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) for event in stream_response: @@ -115,5 +115,3 @@ print(f"Full response: {event.response.output_text}") print("\nCleaning up...") - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq.py index 6ec54359df61..c5b48b80932f 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq.py @@ -21,12 +21,14 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) WORK_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the WorkIQ project connection. - 4) WORK_IQ_USER_INPUT - The natural-language question to send to the agent. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) WORK_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the WorkIQ project connection. + 5) WORK_IQ_USER_INPUT - The natural-language question to send to the agent. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, WorkIQPreviewTool @@ -34,35 +36,32 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") + +tool_payload = WorkIQPreviewTool( + project_connection_id=os.environ["WORK_IQ_PROJECT_CONNECTION_ID"], +) with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, -): - tool_payload = WorkIQPreviewTool( - project_connection_id=os.environ["WORK_IQ_PROJECT_CONNECTION_ID"], - ) - - agent = project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Use the available WorkIQ tools to answer questions and perform tasks.", tools=[tool_payload], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") - + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, +): user_input = os.environ.get("WORK_IQ_USER_INPUT") or input("Enter your question:\n") response = openai_client.responses.create( input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - # Clean up the agent version so unused versions don't accumulate in the project. - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") + # The helper restores the endpoint and deletes the temporary version automatically. diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq_async.py index 7f101778079f..ee64be8153ea 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_agent_work_iq_async.py @@ -21,13 +21,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) WORK_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the WorkIQ project connection. - 4) WORK_IQ_USER_INPUT - The natural-language question to send to the agent. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) WORK_IQ_PROJECT_CONNECTION_ID - The fully-qualified resource id of the WorkIQ project connection. + 5) WORK_IQ_USER_INPUT - The natural-language question to send to the agent. """ import os import asyncio from dotenv import load_dotenv +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import PromptAgentDefinition, WorkIQPreviewTool @@ -35,41 +37,39 @@ load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main(): + tool_payload = WorkIQPreviewTool( + project_connection_id=os.environ["WORK_IQ_PROJECT_CONNECTION_ID"], + ) + async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, - ): - tool_payload = WorkIQPreviewTool( - project_connection_id=os.environ["WORK_IQ_PROJECT_CONNECTION_ID"], - ) - - agent = await project_client.agents.create_version( - agent_name="MyAgent", + create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="Use the available WorkIQ tools to answer questions and perform tasks.", tools=[tool_payload], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})") + ), + project_client.get_openai_client(agent_name=agent_name) as openai_client, + ): + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.versions.latest.version})") user_input = os.environ.get("WORK_IQ_USER_INPUT") or input("Enter your question:\n") response = await openai_client.responses.create( input=user_input, - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, ) print(f"Agent response: {response.output_text}") - # Clean up the agent version so unused versions don't accumulate in the project. - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print("Agent deleted") - if __name__ == "__main__": asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview.py index ff4e7faa33f6..44b4a41296d2 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview.py @@ -31,12 +31,14 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys used by + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys used by the inner MCP server inside the toolbox. """ import os from dotenv import load_dotenv +from util import create_version_with_endpoint from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( @@ -54,12 +56,13 @@ INNER_MCP_LABEL = "github" INNER_MCP_URL = "https://api.githubcopilot.com/mcp" TOOLBOX_MCP_LABEL = "search-tool" +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, + project_client.get_openai_client(agent_name=agent_name) as openai_client, ): inner_mcp_tool = MCPToolboxTool( @@ -86,8 +89,9 @@ require_approval="never", ) - agent = project_client.agents.create_version( - agent_name="MyAgent", + with create_version_with_endpoint( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions=( @@ -97,25 +101,20 @@ ), tools=[toolbox_mcp_tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version}).") - - response = openai_client.responses.create( - input="What is my username in Github profile?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - - for item in response.output: - if item.type == "mcp_approval_request": - print(f"server_label={item.server_label}, name={item.name}") - elif item.type == "mcp_list_tools": - print(f"server_label={item.server_label}, tools={[t.name for t in (item.tools or [])]}") - elif item.type == "mcp_call": - print(f"server_label={item.server_label}, name={item.name}, error={item.error}") - else: - print() - - print(f"Response: {response.output_text}") - - project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print(f"Agent version {agent.version} deleted.") + ) as agent: + + response = openai_client.responses.create( + input="What is my username in Github profile?", + ) + + for item in response.output: + if item.type == "mcp_approval_request": + print(f"server_label={item.server_label}, name={item.name}") + elif item.type == "mcp_list_tools": + print(f"server_label={item.server_label}, tools={[t.name for t in (item.tools or [])]}") + elif item.type == "mcp_call": + print(f"server_label={item.server_label}, name={item.name}, error={item.error}") + else: + print() + + print(f"Response: {response.output_text}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview_async.py b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview_async.py index 1a44ab930311..34dc5af711de 100644 --- a/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview_async.py +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/sample_toolboxes_with_search_preview_async.py @@ -31,13 +31,15 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. - 3) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys used by + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". + 4) MCP_PROJECT_CONNECTION_ID - The connection resource ID in Custom keys used by the inner MCP server inside the toolbox. """ import asyncio import os from dotenv import load_dotenv +from util import create_version_with_endpoint_async from azure.identity.aio import DefaultAzureCredential from azure.ai.projects.aio import AIProjectClient from azure.ai.projects.models import ( @@ -55,13 +57,14 @@ INNER_MCP_LABEL = "github" INNER_MCP_URL = "https://api.githubcopilot.com/mcp" TOOLBOX_MCP_LABEL = "search-tool" +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") async def main() -> None: async with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, - project_client.get_openai_client() as openai_client, + project_client.get_openai_client(agent_name=agent_name) as openai_client, ): inner_mcp_tool = MCPToolboxTool( @@ -88,8 +91,9 @@ async def main() -> None: require_approval="never", ) - agent = await project_client.agents.create_version( - agent_name="MyAgent", + async with create_version_with_endpoint_async( + project_client=project_client, + agent_name=agent_name, definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions=( @@ -99,28 +103,24 @@ async def main() -> None: ), tools=[toolbox_mcp_tool], ), - ) - print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version}).") - - response = await openai_client.responses.create( - input="What is my username in Github profile?", - extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}}, - ) - - for item in response.output: - if item.type == "mcp_approval_request": - print(f"server_label={item.server_label}, name={item.name}") - elif item.type == "mcp_list_tools": - print(f"server_label={item.server_label}, tools={[t.name for t in (item.tools or [])]}") - elif item.type == "mcp_call": - print(f"server_label={item.server_label}, name={item.name}, error={item.error}") - else: - print() - - print(f"Response: {response.output_text}") - - await project_client.agents.delete_version(agent_name=agent.name, agent_version=agent.version) - print(f"Agent version {agent.version} deleted.") + ) as agent: + print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version}).") + + response = await openai_client.responses.create( + input="What is my username in Github profile?", + ) + + for item in response.output: + if item.type == "mcp_approval_request": + print(f"server_label={item.server_label}, name={item.name}") + elif item.type == "mcp_list_tools": + print(f"server_label={item.server_label}, tools={[t.name for t in (item.tools or [])]}") + elif item.type == "mcp_call": + print(f"server_label={item.server_label}, name={item.name}, error={item.error}") + else: + print() + + print(f"Response: {response.output_text}") if __name__ == "__main__": diff --git a/sdk/ai/azure-ai-projects/samples/agents/tools/util.py b/sdk/ai/azure-ai-projects/samples/agents/tools/util.py new file mode 100644 index 000000000000..bc55b40b1291 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/tools/util.py @@ -0,0 +1,27 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +import sys +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from samples.agents.util import create_version_with_endpoint, create_version_with_endpoint_async +else: + _AGENTS_UTIL_PATH = Path(__file__).resolve().parents[1] / "util.py" + _PKG_ROOT = Path(__file__).resolve().parents[3] + if str(_PKG_ROOT) not in sys.path: + sys.path.insert(0, str(_PKG_ROOT)) + + _SPEC = spec_from_file_location("samples_agents_util", _AGENTS_UTIL_PATH) + if _SPEC is None or _SPEC.loader is None: + raise ImportError(f"Unable to load agent samples util from {_AGENTS_UTIL_PATH}") + + _MODULE = module_from_spec(_SPEC) + _SPEC.loader.exec_module(_MODULE) + + create_version_with_endpoint = _MODULE.create_version_with_endpoint + create_version_with_endpoint_async = _MODULE.create_version_with_endpoint_async diff --git a/sdk/ai/azure-ai-projects/samples/agents/util.py b/sdk/ai/azure-ai-projects/samples/agents/util.py new file mode 100644 index 000000000000..6dd3e9c176d7 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/util.py @@ -0,0 +1,27 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +import sys +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from samples.util import create_version_with_endpoint, create_version_with_endpoint_async +else: + _SAMPLES_UTIL_PATH = Path(__file__).resolve().parents[1] / "util.py" + _PKG_ROOT = Path(__file__).resolve().parents[2] + if str(_PKG_ROOT) not in sys.path: + sys.path.insert(0, str(_PKG_ROOT)) + + _SPEC = spec_from_file_location("samples_shared_util", _SAMPLES_UTIL_PATH) + if _SPEC is None or _SPEC.loader is None: + raise ImportError(f"Unable to load shared samples util from {_SAMPLES_UTIL_PATH}") + + _MODULE = module_from_spec(_SPEC) + _SPEC.loader.exec_module(_MODULE) + + create_version_with_endpoint = _MODULE.create_version_with_endpoint + create_version_with_endpoint_async = _MODULE.create_version_with_endpoint_async diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_evaluation.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_evaluation.py index 5a930105fb95..9c9f48b5f6a4 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_evaluation.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_evaluation.py @@ -21,9 +21,9 @@ Set these environment variables with your own values: 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview page of your Microsoft Foundry portal. - 2) FOUNDRY_AGENT_NAME - The name of the AI agent to use for evaluation. - 3) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -54,7 +54,7 @@ project_client.get_openai_client() as openai_client, ): agent = project_client.agents.create_version( - agent_name=os.environ["FOUNDRY_AGENT_NAME"], + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=model_deployment_name, instructions="You are a helpful assistant that answers general questions", diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation.py index 2e60f43b3430..6074d6f3e644 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation.py @@ -21,9 +21,9 @@ Set these environment variables with your own values: 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview page of your Microsoft Foundry portal. - 2) FOUNDRY_AGENT_NAME - The name of the AI agent to use for evaluation. - 3) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -55,7 +55,7 @@ ): agent = project_client.agents.create_version( - agent_name=os.environ["FOUNDRY_AGENT_NAME"], + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation_with_function_tool.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation_with_function_tool.py index 03d33aa6dd40..6ae7d9c8048f 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation_with_function_tool.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_agent_response_evaluation_with_function_tool.py @@ -23,6 +23,7 @@ page of your Microsoft Foundry portal. 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ # pylint: disable=docstring-missing-param,docstring-missing-return,docstring-missing-rtype @@ -85,7 +86,7 @@ def get_horoscope(sign: str) -> str: project_client.get_openai_client() as openai_client, ): agent = project_client.agents.create_version( - agent_name="MyAgent", + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=model_deployment_name, instructions="You are a helpful assistant that can use function tools.", diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_continuous_evaluation_rule.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_continuous_evaluation_rule.py index ea1591a95a41..89b0f2741a64 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_continuous_evaluation_rule.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_continuous_evaluation_rule.py @@ -30,9 +30,9 @@ Set these environment variables with your own values: 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview page of your Microsoft Foundry portal. - 2) FOUNDRY_AGENT_NAME - The name of the AI agent to use for evaluation. - 3) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model, as found under the "Name" column in the "Models + endpoints" tab in your Microsoft Foundry project. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -63,7 +63,7 @@ # Create agent agent = project_client.agents.create_version( - agent_name=os.environ["FOUNDRY_AGENT_NAME"], + agent_name=os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent"), definition=PromptAgentDefinition( model=os.environ["FOUNDRY_MODEL_NAME"], instructions="You are a helpful assistant that answers general questions", diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_multiturn_conversation_simulation.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_multiturn_conversation_simulation.py index 6dd7db32cd9f..3c0892a97e7b 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_multiturn_conversation_simulation.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_multiturn_conversation_simulation.py @@ -35,7 +35,7 @@ 1) FOUNDRY_PROJECT_ENDPOINT - Required. The Azure AI Project endpoint. 2) FOUNDRY_MODEL_NAME - Required. The model deployment name for the simulator and AI-assisted evaluators. - 3) FOUNDRY_AGENT_NAME - Required. The name of the Foundry agent to simulate against. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -51,7 +51,7 @@ endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] model_deployment_name = os.environ["FOUNDRY_MODEL_NAME"] -agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "") +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") # Path to the simulation scenarios data file script_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_redteam_evaluations.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_redteam_evaluations.py index a88d71125b12..546ec8ade411 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_redteam_evaluations.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_redteam_evaluations.py @@ -19,7 +19,7 @@ Set these environment variables with your own values: 1) FOUNDRY_PROJECT_ENDPOINT - Required. The Azure AI Project endpoint, as found in the overview page of your Microsoft Foundry project. It has the form: https://.services.ai.azure.com/api/projects/. - 2) FOUNDRY_AGENT_NAME - Required. The name of the Agent to perform red teaming evaluation on. + 2) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -48,7 +48,7 @@ def main() -> None: # pylint: disable=too-many-statements load_dotenv() # endpoint = os.environ.get("FOUNDRY_PROJECT_ENDPOINT", "") - agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "") + agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_scheduled_evaluations.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_scheduled_evaluations.py index 8762ed0a9541..cbb22294f3d3 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_scheduled_evaluations.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_scheduled_evaluations.py @@ -24,7 +24,7 @@ 4) DATASET_NAME - Optional. The name of the Dataset to create and use in this sample. 5) DATASET_VERSION - Optional. The version of the Dataset to create and use in this sample. 6) DATA_FOLDER - Optional. The folder path where the data files for upload are located. - 7) FOUNDRY_AGENT_NAME - Required. The name of the Agent to perform red teaming evaluation on. + 7) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ from datetime import datetime @@ -328,7 +328,7 @@ def schedule_redteam_evaluation() -> None: # pylint: disable=too-many-locals load_dotenv() # endpoint = os.environ.get("FOUNDRY_PROJECT_ENDPOINT", "") - agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "") + agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") # Construct the paths to the data folder and data file used in this sample script_dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_data_agent_evaluation.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_data_agent_evaluation.py index dada3b8e2418..8ce3ea90d7c9 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_data_agent_evaluation.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_data_agent_evaluation.py @@ -31,7 +31,7 @@ Microsoft Foundry project. It has the form: https://.services.ai.azure.com/api/projects/. 2) FOUNDRY_MODEL_NAME - Required. The name of the model deployment to use for generating synthetic data and for AI-assisted evaluators. - 3) FOUNDRY_AGENT_NAME - Required. The name of the Foundry agent to evaluate. + 3) FOUNDRY_AGENT_NAME - Optional. The name of the AI agent. If not set, defaults to "MyAgent". """ import os @@ -51,7 +51,7 @@ endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] model_deployment_name = os.environ["FOUNDRY_MODEL_NAME"] -agent_name = os.environ["FOUNDRY_AGENT_NAME"] +agent_name = os.environ.get("FOUNDRY_AGENT_NAME", "MyAgent") with ( DefaultAzureCredential() as credential, diff --git a/sdk/ai/azure-ai-projects/samples/util.py b/sdk/ai/azure-ai-projects/samples/util.py index 818a62ccc853..94e9e1799a5d 100644 --- a/sdk/ai/azure-ai-projects/samples/util.py +++ b/sdk/ai/azure-ai-projects/samples/util.py @@ -5,10 +5,29 @@ import hashlib import os +import sys import tempfile import zipfile +from contextlib import asynccontextmanager, contextmanager from pathlib import Path -from typing import Optional, Tuple +from typing import Any, AsyncIterator, Iterator, Optional, Tuple + +_PKG_ROOT = Path(__file__).resolve().parents[1] +if str(_PKG_ROOT) not in sys.path: + sys.path.insert(0, str(_PKG_ROOT)) + +from azure.ai.projects import AIProjectClient +from azure.ai.projects.aio import AIProjectClient as AsyncAIProjectClient +from azure.ai.projects.models import ( + AgentBlueprintReference, + AgentDefinition, + AgentEndpointConfig, + AgentVersionDetails, + FixedRatioVersionSelectionRule, + ProtocolConfiguration, + ResponsesProtocolConfiguration, + VersionSelector, +) def _resolve_zip_file(zip_file: str) -> Path: @@ -54,3 +73,103 @@ def zip_directory( zip_sha256 = hashlib.sha256(zip_bytes).hexdigest() print(f"Built zip from {source_dir}: {len(zip_bytes)} bytes, sha256={zip_sha256}, path={zip_path}") return zip_bytes, zip_sha256, zip_path + + +@contextmanager +def create_version_with_endpoint( + project_client: AIProjectClient, + agent_name: str, + *, + definition: AgentDefinition, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, + blueprint_reference: Optional[AgentBlueprintReference] = None, + draft: Optional[bool] = None, + **kwargs: Any, +) -> Iterator[AgentVersionDetails]: + """Create a version, point the agent endpoint to it, then restore and delete on exit.""" + created_version = None + original_agent_endpoint = None + + try: + created_version = project_client.agents.create_version( + agent_name=agent_name, + definition=definition, + metadata=metadata, + description=description, + blueprint_reference=blueprint_reference, + draft=draft, + **kwargs, + ) + + original_agent_endpoint = project_client.agents.get(agent_name=agent_name).agent_endpoint + endpoint_config = AgentEndpointConfig( + version_selector=VersionSelector( + version_selection_rules=[ + FixedRatioVersionSelectionRule(agent_version=created_version.version, traffic_percentage=100), + ] + ), + protocol_configuration=ProtocolConfiguration(responses=ResponsesProtocolConfiguration()), + ) + project_client.agents.update_details(agent_name=agent_name, agent_endpoint=endpoint_config) + print(f"Agent endpoint configured for version {created_version.version}") + + yield created_version + finally: + if original_agent_endpoint is not None: + project_client.agents.update_details(agent_name=agent_name, agent_endpoint=original_agent_endpoint) + + if created_version is not None: + project_client.agents.delete_version( + agent_name=agent_name, agent_version=created_version.version, force=True + ) + + +@asynccontextmanager +async def create_version_with_endpoint_async( + project_client: AsyncAIProjectClient, + agent_name: str, + *, + definition: AgentDefinition, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, + blueprint_reference: Optional[AgentBlueprintReference] = None, + draft: Optional[bool] = None, + **kwargs: Any, +) -> AsyncIterator[AgentVersionDetails]: + """Async variant of :func:`create_version_with_endpoint`.""" + created_version = None + original_agent_endpoint = None + + try: + created_version = await project_client.agents.create_version( + agent_name=agent_name, + definition=definition, + metadata=metadata, + description=description, + blueprint_reference=blueprint_reference, + draft=draft, + **kwargs, + ) + + original_agent_endpoint = (await project_client.agents.get(agent_name=agent_name)).agent_endpoint + endpoint_config = AgentEndpointConfig( + version_selector=VersionSelector( + version_selection_rules=[ + FixedRatioVersionSelectionRule(agent_version=created_version.version, traffic_percentage=100), + ] + ), + protocol_configuration=ProtocolConfiguration(responses=ResponsesProtocolConfiguration()), + ) + await project_client.agents.update_details(agent_name=agent_name, agent_endpoint=endpoint_config) + print(f"Agent endpoint configured for version {created_version.version}") + + yield created_version + finally: + if original_agent_endpoint is not None: + await project_client.agents.update_details(agent_name=agent_name, agent_endpoint=original_agent_endpoint) + + if created_version is not None: + await project_client.agents.delete_version( + agent_name=agent_name, agent_version=created_version.version, force=True + ) diff --git a/sdk/ai/azure-ai-projects/tests/conftest.py b/sdk/ai/azure-ai-projects/tests/conftest.py index 4ea07947a42e..5d5722183e64 100644 --- a/sdk/ai/azure-ai-projects/tests/conftest.py +++ b/sdk/ai/azure-ai-projects/tests/conftest.py @@ -52,6 +52,7 @@ class SanitizedValues: ACCOUNT_NAME = "sanitized-account-name" PROJECT_NAME = "sanitized-project-name" COMPONENT_NAME = "sanitized-component-name" + AGENT_NAME = "sanitized-agent-name" AGENTS_API_VERSION = "sanitized-api-version" API_KEY = "sanitized-api-key" MODEL_DEPLOYMENT_NAME = "sanitized-model-deployment-name" @@ -65,6 +66,7 @@ def sanitized_values(): "project_name": f"{SanitizedValues.PROJECT_NAME}", "account_name": f"{SanitizedValues.ACCOUNT_NAME}", "component_name": f"{SanitizedValues.COMPONENT_NAME}", + "agent_name": f"{SanitizedValues.AGENT_NAME}", "agents_api_version": f"{SanitizedValues.AGENTS_API_VERSION}", "api_key": f"{SanitizedValues.API_KEY}", "model_deployment_name": f"{SanitizedValues.MODEL_DEPLOYMENT_NAME}", @@ -260,6 +262,24 @@ def sanitize_url_paths(): value=sanitized_values["model_deployment_name"], ) + agent_names = { + value + for value in ( + os.environ.get("FOUNDRY_AGENT_NAME"), + os.environ.get("foundry_agent_name"), + ) + if value and value != sanitized_values["agent_name"] + } + for agent_name in agent_names: + add_general_regex_sanitizer( + regex=re.escape(agent_name), + value=sanitized_values["agent_name"], + ) + add_body_string_sanitizer( + target=agent_name, + value=sanitized_values["agent_name"], + ) + # Deterministic fallback sanitization for model deployment names returned by # OpenAI-compatible endpoints. These can appear in response bodies and headers # even when the live value was not supplied through a known environment variable. diff --git a/sdk/ai/azure-ai-projects/tests/test_base.py b/sdk/ai/azure-ai-projects/tests/test_base.py index ed71677fe225..4069479fdcb3 100644 --- a/sdk/ai/azure-ai-projects/tests/test_base.py +++ b/sdk/ai/azure-ai-projects/tests/test_base.py @@ -41,6 +41,7 @@ "", foundry_project_endpoint="https://sanitized-account-name.services.ai.azure.com/api/projects/sanitized-project-name", foundry_project_api_key="sanitized-api-key", + foundry_agent_name="sanitized-agent-name", foundry_model_name="sanitized-model-deployment-name", llm_validation_project_endpoint="https://sanitized-account-name.services.ai.azure.com/api/projects/sanitized-project-name", image_generation_model_deployment_name="sanitized-gpt-image",