Skip to content

Commit cf71746

Browse files
able to create the agnets
1 parent 8ece4e2 commit cf71746

4 files changed

Lines changed: 72 additions & 40 deletions

File tree

src/backend/common/config/app_config.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
from azure.ai.projects.aio import AIProjectClient
77
from azure.cosmos import CosmosClient
8-
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
8+
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential, AzureCliCredential
99
from azure.identity.aio import DefaultAzureCredential as AioDefaultAzureCredential
1010
from azure.identity.aio import ManagedIdentityCredential as AioManagedIdentityCredential
11+
from azure.identity.aio import AzureCliCredential as AioAzureCliCredential
1112
from dotenv import load_dotenv
1213

1314

@@ -115,17 +116,17 @@ def get_azure_credential(self, client_id=None):
115116
"""
116117
Returns an Azure credential based on the application environment.
117118
118-
If the environment is 'dev', it uses DefaultAzureCredential.
119+
If the environment is 'dev', it uses AzureCliCredential for proper token scoping.
119120
Otherwise, it uses ManagedIdentityCredential.
120121
121122
Args:
122123
client_id (str, optional): The client ID for the Managed Identity Credential.
123124
124125
Returns:
125-
Credential object: Either DefaultAzureCredential or ManagedIdentityCredential.
126+
Credential object: Either AzureCliCredential or ManagedIdentityCredential.
126127
"""
127128
if self.APP_ENV == "dev":
128-
return DefaultAzureCredential() # CodeQL [SM05139]: DefaultAzureCredential is safe here
129+
return AzureCliCredential() # Use AzureCliCredential for dev to properly scope tokens for https://ai.azure.com
129130
else:
130131
return ManagedIdentityCredential(client_id=client_id)
131132

@@ -136,10 +137,10 @@ async def get_azure_credential_async(self, client_id=None):
136137
client_id (str, optional): The client ID for the Managed Identity Credential.
137138
138139
Returns:
139-
Async credential object: Either AioDefaultAzureCredential or AioManagedIdentityCredential.
140+
Async credential object: Either AioAzureCliCredential or AioManagedIdentityCredential.
140141
"""
141142
if self.APP_ENV == "dev":
142-
return AioDefaultAzureCredential() # CodeQL [SM05139]: DefaultAzureCredential is safe here
143+
return AioAzureCliCredential() # Use AzureCliCredential for dev to properly scope tokens for https://ai.azure.com
143144
else:
144145
return AioManagedIdentityCredential(client_id=client_id)
145146

@@ -252,7 +253,7 @@ def get_ai_project_client(self):
252253

253254
endpoint = self.AZURE_AI_AGENT_ENDPOINT
254255
self._ai_project_client = AIProjectClient(
255-
endpoint=endpoint, credential=AioDefaultAzureCredential()
256+
endpoint=endpoint, credential=self.get_azure_credential(self.AZURE_CLIENT_ID)
256257
)
257258

258259
return self._ai_project_client

src/backend/v4/magentic_agents/common/lifecycle.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from agent_framework.azure import AzureAIClient
1515
from azure.ai.agents.aio import AgentsClient
16-
from azure.identity.aio import DefaultAzureCredential
16+
from azure.identity.aio import AzureCliCredential
1717
from common.database.database_base import DatabaseBase
1818
from common.models.messages_af import CurrentTeamAgent, TeamConfiguration
1919
from common.utils.utils_agents import (
@@ -68,14 +68,26 @@ async def open(self) -> "MCPEnabledBase":
6868
return self
6969
self._stack = AsyncExitStack()
7070

71-
# Acquire credential
72-
self.creds = DefaultAzureCredential()
71+
# Acquire async credential - using AzureCliCredential for dev environment
72+
# following Microsoft reference pattern from agent-framework samples
73+
self.creds = AzureCliCredential()
7374
if self._stack:
7475
await self._stack.enter_async_context(self.creds)
75-
# Create AgentsClient
76+
77+
# Create project_client with async credentials if not already set
78+
if not self.project_client:
79+
from azure.ai.projects.aio import AIProjectClient
80+
self.project_client = AIProjectClient(
81+
endpoint=config.AZURE_AI_AGENT_ENDPOINT,
82+
credential=self.creds
83+
)
84+
if self._stack:
85+
await self._stack.enter_async_context(self.project_client)
86+
87+
# Create AgentsClient with same async credential
7688
self.client = AzureAIClient(
7789
project_client=self.project_client,
78-
#async_credential=self.creds if hasattr(self, 'creds') and self.creds else None,
90+
async_credential=self.creds,
7991
agent_name=self.agent_name,
8092
use_latest_version=True,
8193
)
@@ -145,7 +157,7 @@ def get_chat_client(self, chat_client) -> AzureAIClient:
145157
if self.project_client and self.agent_name and self.creds:
146158
chat_client = AzureAIClient(
147159
project_client=self.project_client,
148-
#async_credential=self.creds,
160+
async_credential=self.creds,
149161
agent_name=self.agent_name,
150162
use_latest_version=True,
151163
)
@@ -253,7 +265,7 @@ async def get_database_team_agent(self) -> Optional[AzureAIClient]:
253265
if self.agent_name == "RAIAgent" and self.project_client and self.creds:
254266
chat_client = AzureAIClient(
255267
project_client=self.project_client,
256-
#async_credential=self.creds,
268+
async_credential=self.creds,
257269
agent_name=self.agent_name,
258270
use_latest_version=True,
259271
)
@@ -264,7 +276,7 @@ async def get_database_team_agent(self) -> Optional[AzureAIClient]:
264276
elif self.project_client and self.creds:
265277
chat_client = AzureAIClient(
266278
project_client=self.project_client,
267-
#async_credential=self.creds,
279+
async_credential=self.creds,
268280
agent_name=self.agent_name,
269281
use_latest_version=True,
270282
)

src/backend/v4/magentic_agents/foundry_agent.py

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def __init__(
4646
team_config: TeamConfiguration | None = None,
4747
memory_store: DatabaseBase | None = None,
4848
) -> None:
49-
# Get project_client before calling super().__init__
50-
project_client = config.get_ai_project_client()
49+
# Defer project_client creation until async open() to use async credentials
50+
project_client = None # Will be created in parent's open() method
5151

5252
super().__init__(
5353
mcp=mcp_config,
@@ -223,7 +223,7 @@ async def _create_azure_search_enabled_client(self, chatClient=None) -> Optional
223223
# The async_credential is needed for inference/streaming operations
224224
chat_client = AzureAIClient(
225225
project_client=self.project_client,
226-
#async_credential=self.creds if hasattr(self, 'creds') and self.creds else None,
226+
async_credential=self.creds if hasattr(self, 'creds') and self.creds else None,
227227
agent_name=self.agent_name,
228228
use_latest_version=True,
229229
)
@@ -281,35 +281,53 @@ async def _after_open(self) -> None:
281281
self.logger.info("Initializing agent in MCP mode.")
282282

283283
tools = await self._collect_tools()
284-
# NOTE: Following Microsoft reference pattern - ChatAgent used directly
285284
self._tools_for_invoke = tools if tools else None
286285
self._tool_choice = "auto" if tools else "none"
287286

288-
self._agent = AzureAIClient(
289-
project_client=self.project_client,
290-
use_latest_version=True).create_agent(
291-
name=self.agent_name,
287+
# Convert agent_framework tools to Foundry FunctionTool format
288+
foundry_tools = []
289+
for tool in (tools or []):
290+
if hasattr(tool, 'to_function_tool'):
291+
foundry_tools.append(tool.to_function_tool())
292+
elif hasattr(tool, 'function'):
293+
# For MCP tools or other function-based tools
294+
foundry_tools.append(FunctionTool(function=tool.function))
295+
296+
# Create Azure agent version with tools
297+
azure_agent = await self.project_client.agents.create_version(
298+
agent_name=self.agent_name,
299+
definition=PromptAgentDefinition(
300+
model=self.model_deployment_name,
292301
instructions=self.agent_instructions,
293-
tools=tools if tools else None
302+
tools=foundry_tools if foundry_tools else None
294303
)
295-
print("mcp based agent: ",self.agent_name)
296-
# Create ChatAgent following reference pattern
297-
# self._agent = ChatAgent(
298-
# chat_client=self.get_chat_client(chatClient),
299-
# instructions=self.agent_instructions,
300-
# name=self.agent_name,
301-
# description=self.agent_description,
302-
# tools=tools if tools else None,
303-
# tool_choice="auto" if tools else "none",
304-
# temperature=temp,
305-
# model_id=self.model_deployment_name,
306-
# )
304+
)
305+
306+
self.logger.info(
307+
"Created Azure agent version (agent_name=%s) with %d tools.",
308+
self.agent_name,
309+
len(foundry_tools)
310+
)
311+
312+
# Use AzureAIClient with the created agent
313+
chat_client = AzureAIClient(
314+
project_client=self.project_client,
315+
async_credential=self.creds if hasattr(self, 'creds') and self.creds else None,
316+
agent_name=self.agent_name,
317+
use_latest_version=True,
318+
)
319+
320+
# Create ChatAgent with the Azure-backed client
321+
self._agent = ChatAgent(
322+
chat_client=self.get_chat_client(chat_client),
323+
tools=self._tools_for_invoke,
324+
tool_choice=self._tool_choice,
325+
store=True,
326+
)
327+
307328
async for agent in self.project_client.agents.list():
308329
print(f" Agent: {agent.name}")
309330

310-
async for version in self.project_client.agents.list_versions(agent_name=self.agent_name):
311-
print(f" Version: {version}")
312-
313331
self.logger.info("Initialized ChatAgent '%s'", self.agent_name)
314332

315333
except Exception as ex:
@@ -338,7 +356,7 @@ async def invoke(self, prompt: str):
338356
messages = [ChatMessage(role=Role.USER, text=prompt)]
339357

340358
agent_saved = False
341-
print("invoke stream...", self._agent.name)
359+
print(f"invoke stream... agent_name={self.agent_name}")
342360
async for update in self._agent.run_stream(messages):
343361
# Save agent only once on first update (using agent name)
344362
if not agent_saved and self._agent.id:

src/backend/v4/orchestration/orchestration_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ async def init_orchestration(
8080

8181
chat_client = AzureAIClient(
8282
project_client=project_client,
83+
async_credential=credential,
8384
agent_name=agent_name,
8485
use_latest_version=True
8586
)

0 commit comments

Comments
 (0)