Skip to content

Commit 009ce24

Browse files
authored
[AI] [Projects] Add Connected Agent Tool definition and sample (#40629)
* [AI] [Projects] add ConnectedAgentTool and sample * add connected agent sample * update sample to delete connected agent * fix typo
1 parent dcb5e57 commit 009ce24

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py

+45
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
BingGroundingToolDefinition,
5656
CodeInterpreterToolDefinition,
5757
CodeInterpreterToolResource,
58+
ConnectedAgentToolDefinition,
59+
ConnectedAgentDetails,
5860
FileSearchToolDefinition,
5961
FileSearchToolResource,
6062
FunctionDefinition,
@@ -1086,6 +1088,48 @@ def resources(self) -> ToolResources:
10861088
def execute(self, tool_call: Any) -> Any:
10871089
pass
10881090

1091+
class ConnectedAgentTool(Tool[ConnectedAgentToolDefinition]):
1092+
"""
1093+
A tool that connects to a sub-agent, with a description describing the conditions
1094+
or domain where the sub-agent would be called.
1095+
"""
1096+
def __init__(self, id: str, name: str, description: str):
1097+
"""
1098+
Initialize ConnectedAgentTool with an id, name, and description.
1099+
1100+
:param id: The ID of the connected agent.
1101+
:param name: The name of the connected agent.
1102+
:param description: The description of the connected agent, used by the calling agent
1103+
to determine when to call the connected agent.
1104+
"""
1105+
self.connected_agent = ConnectedAgentDetails(id=id, name=name, description=description)
1106+
1107+
@property
1108+
def definitions(self) -> List[ConnectedAgentToolDefinition]:
1109+
"""
1110+
Get the connected agent tool definitions.
1111+
1112+
:rtype: List[ToolDefinition]
1113+
"""
1114+
return [ConnectedAgentToolDefinition(connected_agent=self.connected_agent)]
1115+
1116+
@property
1117+
def resources(self) -> ToolResources:
1118+
"""
1119+
Get the tool resources for the agent.
1120+
1121+
:return: An empty ToolResources as ConnectedAgentTool doesn't have specific resources.
1122+
:rtype: ToolResources
1123+
"""
1124+
return ToolResources()
1125+
1126+
def execute(self, tool_call: Any) -> None:
1127+
"""
1128+
ConnectedAgentTool does not execute client-side.
1129+
1130+
:param Any tool_call: The tool call to execute.
1131+
:type tool_call: Any
1132+
"""
10891133

10901134
class FabricTool(ConnectionTool[MicrosoftFabricToolDefinition]):
10911135
"""
@@ -1917,6 +1961,7 @@ def get_last_text_message_by_role(self, role: MessageRole) -> Optional[MessageTe
19171961
"BaseAsyncAgentEventHandler",
19181962
"BaseAgentEventHandler",
19191963
"CodeInterpreterTool",
1964+
"ConnectedAgentTool",
19201965
"ConnectionProperties",
19211966
"AsyncAgentEventHandler",
19221967
"OpenAIPageableListOfThreadMessage",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# ------------------------------------
2+
# Copyright (c) Microsoft Corporation.
3+
# Licensed under the MIT License.
4+
# ------------------------------------
5+
6+
"""
7+
DESCRIPTION:
8+
This sample demonstrates how to use Agent operations with the Connected Agent tool from
9+
the Azure Agents service using a synchronous client.
10+
11+
USAGE:
12+
python sample_agents_connected_agent.py
13+
14+
Before running the sample:
15+
16+
pip install azure-ai-projects azure-identity
17+
18+
Set these environment variables with your own values:
19+
1) PROJECT_CONNECTION_STRING - The project connection string, as found in the overview page of your
20+
Azure AI Foundry project.
21+
2) MODEL_DEPLOYMENT_NAME - The deployment name of the AI model, as found under the "Name" column in
22+
the "Models + endpoints" tab in your Azure AI Foundry project.
23+
"""
24+
25+
import os
26+
from azure.ai.projects import AIProjectClient
27+
from azure.ai.projects.models import ConnectedAgentTool, MessageRole
28+
from azure.identity import DefaultAzureCredential
29+
30+
31+
project_client = AIProjectClient.from_connection_string(
32+
credential=DefaultAzureCredential(),
33+
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
34+
)
35+
36+
connected_agent_name = "stock_price_bot"
37+
38+
stock_price_agent = project_client.agents.create_agent(
39+
model=os.environ["MODEL_DEPLOYMENT_NAME"],
40+
name=connected_agent_name,
41+
instructions=(
42+
"Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price."
43+
),
44+
)
45+
46+
# [START create_agent_with_connected_agent_tool]
47+
# Initialize Connected Agent tool with the agent id, name, and description
48+
connected_agent = ConnectedAgentTool(id=stock_price_agent.id, name=connected_agent_name, description="Gets the stock price of a company")
49+
50+
# Create agent with the Connected Agent tool and process assistant run
51+
with project_client:
52+
agent = project_client.agents.create_agent(
53+
model=os.environ["MODEL_DEPLOYMENT_NAME"],
54+
name="my-assistant",
55+
instructions="You are a helpful assistant, and use the connected agent to get stock prices.",
56+
tools=connected_agent.definitions,
57+
)
58+
# [END create_agent_with_connected_agent_tool]
59+
60+
print(f"Created agent, ID: {agent.id}")
61+
62+
# Create thread for communication
63+
thread = project_client.agents.create_thread()
64+
print(f"Created thread, ID: {thread.id}")
65+
66+
# Create message to thread
67+
message = project_client.agents.create_message(
68+
thread_id=thread.id,
69+
role=MessageRole.USER,
70+
content="What is the stock price of Microsoft?",
71+
)
72+
print(f"Created message, ID: {message.id}")
73+
74+
# Create and process Agent run in thread with tools
75+
run = project_client.agents.create_and_process_run(thread_id=thread.id, agent_id=agent.id)
76+
print(f"Run finished with status: {run.status}")
77+
78+
if run.status == "failed":
79+
print(f"Run failed: {run.last_error}")
80+
81+
# Delete the Agent when done
82+
project_client.agents.delete_agent(agent.id)
83+
print("Deleted agent")
84+
85+
# Delete the connected Agent when done
86+
project_client.agents.delete_agent(stock_price_agent.id)
87+
print("Deleted connected agent")
88+
89+
# Print the Agent's response message with optional citation
90+
response_message = project_client.agents.list_messages(thread_id=thread.id).get_last_message_by_role(
91+
MessageRole.AGENT
92+
)
93+
if response_message:
94+
for text_message in response_message.text_messages:
95+
print(f"Agent response: {text_message.text.value}")
96+
for annotation in response_message.url_citation_annotations:
97+
print(f"URL Citation: [{annotation.url_citation.title}]({annotation.url_citation.url})")

0 commit comments

Comments
 (0)