Skip to content

Commit cb056fb

Browse files
authored
Merge pull request #62 from Azure-Samples/update-azure-ai-projects-api
feat: update to azure-ai-projects 1.0.0b11 GA API
2 parents 303318d + cc08479 commit cb056fb

3 files changed

Lines changed: 165 additions & 186 deletions

File tree

src/agents/code_style.py

Lines changed: 81 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
# - Returns a comprehensive Markdown style guide based on code examples
88
import os
99
import logging
10-
from azure.ai.projects.aio import AIProjectClient
11-
from azure.ai.projects.models import AsyncFunctionTool
12-
from azure.identity.aio import DefaultAzureCredential
10+
from azure.ai.projects import AIProjectClient
11+
from azure.ai.agents.models import FunctionTool, ToolSet
12+
from azure.identity import DefaultAzureCredential
1313
from agents.tools import vector_search
1414

1515
# Configure logging for this module
@@ -85,99 +85,88 @@ async def generate_code_style(chat_history: str = "", user_query: str = "") -> s
8585

8686
# Create an Azure credential for authentication
8787
logger.info("Initializing Azure authentication")
88-
async with DefaultAzureCredential() as credential:
89-
# Connect to the Azure AI Project that hosts our agent
90-
logger.info("Connecting to Azure AI Project")
91-
async with AIProjectClient(
92-
credential=credential,
93-
endpoint=os.environ["PROJECT_ENDPOINT"]
94-
) as project_client:
95-
# Create the vector search tool that the agent will use
96-
logger.info("Setting up vector search tool")
97-
functions = AsyncFunctionTool(functions=[vector_search.vector_search])
98-
99-
# Create the agent with its personality and tools
100-
logger.info("Creating CodeStyleSynthesizer agent with model: %s", os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"])
101-
agent = await project_client.agents.create_agent(
102-
name="CodeStyleSynthesizer",
103-
description="An agent that produces code style guides",
104-
instructions=_CODE_STYLE_SYSTEM_PROMPT,
105-
tools=functions.definitions,
106-
model=os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"]
107-
)
108-
logger.info("Created agent: %s with tool: vector_search", agent.name)
109-
110-
# Create a conversation thread for the agent
111-
logger.info("Creating conversation thread")
112-
thread = await project_client.agents.create_thread()
113-
114-
# Add chat history if provided
115-
if chat_history:
116-
logger.info("Adding chat history to thread")
117-
await project_client.agents.create_message(
118-
thread_id=thread.id,
119-
role="user",
120-
content=chat_history
121-
)
122-
123-
# Add the user's query or default message
124-
final_query = user_query if user_query else "Generate a code style guide."
125-
logger.info("Adding user query to thread: %s", final_query)
126-
await project_client.agents.create_message(
88+
credential = DefaultAzureCredential()
89+
90+
# Connect to the Azure AI Project that hosts our agent
91+
logger.info("Connecting to Azure AI Project")
92+
project_client = AIProjectClient(
93+
endpoint=os.environ["PROJECT_ENDPOINT"],
94+
credential=credential
95+
)
96+
97+
with project_client:
98+
# Create the vector search tool that the agent will use
99+
logger.info("Setting up vector search tool")
100+
functions = FunctionTool({vector_search.vector_search})
101+
toolset = ToolSet()
102+
toolset.add(functions)
103+
104+
# Enable automatic function calls
105+
project_client.agents.enable_auto_function_calls(toolset)
106+
107+
# Create the agent with its personality and tools
108+
logger.info("Creating CodeStyleSynthesizer agent with model: %s", os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"])
109+
agent = project_client.agents.create_agent(
110+
name="CodeStyleSynthesizer",
111+
instructions=_CODE_STYLE_SYSTEM_PROMPT,
112+
toolset=toolset,
113+
model=os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"]
114+
)
115+
logger.info("Created agent: %s with tool: vector_search", agent.name)
116+
117+
# Create a conversation thread for the agent
118+
logger.info("Creating conversation thread")
119+
thread = project_client.agents.threads.create()
120+
121+
# Add chat history if provided
122+
if chat_history:
123+
logger.info("Adding chat history to thread")
124+
project_client.agents.messages.create(
127125
thread_id=thread.id,
128126
role="user",
129-
content=final_query
130-
)
131-
132-
# Start the agent's execution
133-
logger.info("Starting agent execution")
134-
run = await project_client.agents.create_run(
135-
thread_id=thread.id,
136-
agent_id=agent.id
127+
content=chat_history
137128
)
138-
139-
# Monitor the agent's progress and handle tool calls
140-
tool_call_count = 0
141-
while True:
142-
run = await project_client.agents.get_run(thread_id=thread.id, run_id=run.id)
143-
logger.info("Agent run status: %s", run.status)
144-
145-
if run.status == "completed":
146-
logger.info("Agent run completed successfully")
129+
130+
# Add the user's query or default message
131+
final_query = user_query if user_query else "Generate a code style guide."
132+
logger.info("Adding user query to thread: %s", final_query)
133+
project_client.agents.messages.create(
134+
thread_id=thread.id,
135+
role="user",
136+
content=final_query
137+
)
138+
139+
# Start the agent's execution and process it automatically
140+
logger.info("Starting agent execution")
141+
run = project_client.agents.runs.create_and_process(
142+
thread_id=thread.id,
143+
agent_id=agent.id
144+
)
145+
logger.info("Agent run completed with status: %s", run.status)
146+
147+
# Check for failure
148+
if run.status == "failed":
149+
logger.error("Agent run failed with error: %s", run.last_error)
150+
raise Exception(f"Agent run failed: {run.last_error}")
151+
152+
# Get the final response from the agent
153+
logger.info("Retrieving final response from agent")
154+
messages = project_client.agents.messages.list(thread_id=thread.id)
155+
156+
# Find the latest assistant message
157+
response = None
158+
for message in messages:
159+
if message.role == "assistant":
160+
# Get the text content from the message
161+
if message.content and len(message.content) > 0:
162+
response = str(message.content[0].text.value)
147163
break
148-
elif run.status == "failed":
149-
logger.error("Agent run failed with : %s", run)
150-
raise Exception("Agent run failed")
151-
elif run.status == "requires_action":
152-
# Handle tool calls from the agent
153-
tool_calls = run.required_action.submit_tool_outputs.tool_calls
154-
logger.info("Agent requires action with %d tool calls", len(tool_calls))
155-
tool_outputs = []
156-
for tool_call in tool_calls:
157-
logger.info("Agent %s calling tool: %s with arguments: %s",
158-
agent.name,
159-
tool_call.function.name,
160-
tool_call.function.arguments)
161-
output = await functions.execute(tool_call)
162-
logger.info("Tool call completed with output length: %d", len(str(output)))
163-
tool_outputs.append({
164-
"tool_call_id": tool_call.id,
165-
"output": output
166-
})
167-
tool_call_count += 1
168-
await project_client.agents.submit_tool_outputs_to_run(
169-
thread_id=thread.id,
170-
run_id=run.id,
171-
tool_outputs=tool_outputs
172-
)
173-
174-
# Get the final response from the agent
175-
logger.info("Retrieving final response from agent")
176-
messages = await project_client.agents.list_messages(thread_id=thread.id)
177-
response = str(messages.data[0].content[0].text.value)
178-
logger.info("Code style guide generated by %s (%d tool calls). Response length: %d",
179-
agent.name, tool_call_count, len(response))
180-
return response
164+
165+
if not response:
166+
raise Exception("No response generated by the agent")
167+
168+
logger.info("Code style guide generated by %s. Response length: %d", agent.name, len(response))
169+
return response
181170

182171
except Exception as e:
183172
logger.error("Code style generation failed with error: %s", str(e), exc_info=True)

src/agents/deep_wiki.py

Lines changed: 83 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import os
88
import logging
99
import time
10-
from azure.ai.projects.aio import AIProjectClient
11-
from azure.ai.projects.models import AsyncFunctionTool
12-
from azure.identity.aio import DefaultAzureCredential
10+
from azure.ai.projects import AIProjectClient
11+
from azure.ai.agents.models import FunctionTool, ToolSet
12+
from azure.identity import DefaultAzureCredential
1313
from agents.tools import vector_search
1414

1515
# Configure logging for this module
@@ -95,100 +95,90 @@ async def generate_deep_wiki(chat_history: str = "", user_query: str = "") -> st
9595

9696
# Create an Azure credential for authentication
9797
logger.info("Initializing Azure authentication")
98-
async with DefaultAzureCredential() as credential:
99-
# Connect to the Azure AI Project that hosts our agent
100-
logger.info("Connecting to Azure AI Project")
101-
async with AIProjectClient(
102-
credential=credential,
103-
endpoint=os.environ["PROJECT_ENDPOINT"]
104-
) as project_client:
105-
# Create the vector search tool that the agent will use
106-
logger.info("Setting up vector search tool")
107-
functions = AsyncFunctionTool(functions=[vector_search.vector_search])
108-
109-
# Create the agent with its personality and tools
110-
logger.info("Creating DeepWiki agent with model: %s", os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"])
111-
agent = await project_client.agents.create_agent(
112-
name="DeepWikiAgent",
113-
description="An agent that generates comprehensive wiki documentation",
114-
instructions=_DEEP_WIKI_SYSTEM_PROMPT,
115-
tools=functions.definitions,
116-
model=os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"]
117-
)
118-
logger.info("Created agent: %s with tool: vector_search", agent.name)
119-
120-
# Create a conversation thread for the agent
121-
logger.info("Creating conversation thread")
122-
thread = await project_client.agents.create_thread()
123-
124-
# Add chat history if provided
125-
if chat_history:
126-
logger.info("Adding chat history to thread")
127-
await project_client.agents.create_message(
128-
thread_id=thread.id,
129-
role="user",
130-
content=chat_history
131-
)
132-
133-
# Add the user's query or default message
134-
final_query = user_query if user_query else "Generate a comprehensive wiki documentation."
135-
logger.info("Adding user query to thread: %s", final_query)
136-
await project_client.agents.create_message(
98+
credential = DefaultAzureCredential()
99+
100+
# Connect to the Azure AI Project that hosts our agent
101+
logger.info("Connecting to Azure AI Project")
102+
project_client = AIProjectClient(
103+
endpoint=os.environ["PROJECT_ENDPOINT"],
104+
credential=credential
105+
)
106+
107+
with project_client:
108+
# Create the vector search tool that the agent will use
109+
logger.info("Setting up vector search tool")
110+
functions = FunctionTool({vector_search.vector_search})
111+
toolset = ToolSet()
112+
toolset.add(functions)
113+
114+
# Enable automatic function calls
115+
project_client.agents.enable_auto_function_calls(toolset)
116+
117+
# Create the agent with its personality and tools
118+
logger.info("Creating DeepWiki agent with model: %s", os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"])
119+
agent = project_client.agents.create_agent(
120+
name="DeepWikiAgent",
121+
instructions=_DEEP_WIKI_SYSTEM_PROMPT,
122+
toolset=toolset,
123+
model=os.environ["AGENTS_MODEL_DEPLOYMENT_NAME"]
124+
)
125+
logger.info("Created agent: %s with tool: vector_search", agent.name)
126+
127+
# Create a conversation thread for the agent
128+
logger.info("Creating conversation thread")
129+
thread = project_client.agents.threads.create()
130+
131+
# Add chat history if provided
132+
if chat_history:
133+
logger.info("Adding chat history to thread")
134+
project_client.agents.messages.create(
137135
thread_id=thread.id,
138136
role="user",
139-
content=final_query
140-
)
141-
142-
# Start the agent's execution
143-
logger.info("Starting agent execution")
144-
run = await project_client.agents.create_run(
145-
thread_id=thread.id,
146-
agent_id=agent.id
137+
content=chat_history
147138
)
148-
149-
# Monitor the agent's progress and handle tool calls
150-
tool_call_count = 0
151-
while True:
152-
run = await project_client.agents.get_run(thread_id=thread.id, run_id=run.id)
153-
logger.info("Agent run status: %s", run.status)
154-
155-
if run.status == "completed":
156-
logger.info("Agent run completed successfully")
139+
140+
# Add the user's query or default message
141+
final_query = user_query if user_query else "Generate a comprehensive wiki documentation."
142+
logger.info("Adding user query to thread: %s", final_query)
143+
project_client.agents.messages.create(
144+
thread_id=thread.id,
145+
role="user",
146+
content=final_query
147+
)
148+
149+
# Start the agent's execution and process it automatically
150+
logger.info("Starting agent execution")
151+
run = project_client.agents.runs.create_and_process(
152+
thread_id=thread.id,
153+
agent_id=agent.id
154+
)
155+
logger.info("Agent run completed with status: %s", run.status)
156+
157+
# Check for failure
158+
if run.status == "failed":
159+
logger.error("Agent run failed with error: %s", run.last_error)
160+
raise Exception(f"Agent run failed: {run.last_error}")
161+
162+
# Get the final response from the agent
163+
logger.info("Retrieving final response from agent")
164+
messages = project_client.agents.messages.list(thread_id=thread.id)
165+
166+
# Find the latest assistant message
167+
response = None
168+
for message in messages:
169+
if message.role == "assistant":
170+
# Get the text content from the message
171+
if message.content and len(message.content) > 0:
172+
response = str(message.content[0].text.value)
157173
break
158-
elif run.status == "failed":
159-
logger.error("Agent run failed with : %s", run)
160-
raise Exception("Agent run failed")
161-
elif run.status == "requires_action":
162-
# Handle tool calls from the agent
163-
tool_calls = run.required_action.submit_tool_outputs.tool_calls
164-
logger.info("Agent requires action with %d tool calls", len(tool_calls))
165-
tool_outputs = []
166-
for tool_call in tool_calls:
167-
logger.info("Agent %s calling tool: %s with arguments: %s",
168-
agent.name,
169-
tool_call.function.name,
170-
tool_call.function.arguments)
171-
output = await functions.execute(tool_call)
172-
logger.info("Tool call completed with output length: %d", len(str(output)))
173-
tool_outputs.append({
174-
"tool_call_id": tool_call.id,
175-
"output": output
176-
})
177-
tool_call_count += 1
178-
await project_client.agents.submit_tool_outputs_to_run(
179-
thread_id=thread.id,
180-
run_id=run.id,
181-
tool_outputs=tool_outputs
182-
)
183-
184-
# Get the final response from the agent
185-
logger.info("Retrieving final response from agent")
186-
messages = await project_client.agents.list_messages(thread_id=thread.id)
187-
response = str(messages.data[0].content[0].text.value)
188-
logger.info("Wiki documentation generated by %s (%d tool calls). Response length: %d",
189-
agent.name, tool_call_count, len(response))
190-
return response
174+
175+
if not response:
176+
raise Exception("No response generated by the agent")
177+
178+
logger.info("Wiki documentation generated by %s. Response length: %d", agent.name, len(response))
179+
return response
191180

192181
except Exception as e:
193182
logger.error("Wiki generation failed with error: %s", str(e), exc_info=True)
194-
raise
183+
raise
184+

src/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ azure-functions>=1.24.0
44
# Azure service SDKs
55
azure-storage-blob # For blob storage operations
66
azure-cosmos # For Cosmos DB operations
7-
azure-ai-projects==1.0.0b10 # For AI project management & getting inference client
7+
azure-ai-projects # For AI project management & agents (includes FunctionTool)
88
azure-identity # For Azure authentication (DefaultAzureCredential)
99
azure-ai-inference # For the EmbeddingsClient type hint and operations
1010

0 commit comments

Comments
 (0)