33import logging
44from typing import List , Optional
55
6- from azure .ai .agents .models import Agent , AzureAISearchTool , CodeInterpreterToolDefinition
7- from agent_framework_azure_ai import AzureAIAgentClient
8- from agent_framework import ChatMessage , Role , ChatOptions , HostedMCPTool
9-
6+ from azure .ai .agents .models import (
7+ Agent ,
8+ AzureAISearchTool ,
9+ CodeInterpreterToolDefinition ,
10+ )
11+
12+ from agent_framework import (
13+ ChatMessage ,
14+ Role ,
15+ ChatOptions ,
16+ HostedMCPTool ,
17+ AggregateContextProvider ,
18+ ChatAgent ,
19+ ChatClientProtocol ,
20+ ChatMessageStoreProtocol ,
21+ ContextProvider ,
22+ Middleware ,
23+ ToolMode ,
24+ ToolProtocol ,
25+ )
1026from af .magentic_agents .common .lifecycle import AzureAgentBase
1127from af .magentic_agents .models .agent_models import MCPConfig , SearchConfig
1228from af .config .agent_registry import agent_registry
@@ -41,20 +57,33 @@ def __init__(
4157 self .logger = logging .getLogger (__name__ )
4258
4359 if self .model_deployment_name in {"o3" , "o4-mini" }:
44- raise ValueError ("Foundry agents do not support reasoning models in this implementation." )
60+ raise ValueError (
61+ "Foundry agents do not support reasoning models in this implementation."
62+ )
4563
4664 # -------------------------
4765 # Tool construction helpers
4866 # -------------------------
4967 async def _make_azure_search_tool (self ) -> Optional [AzureAISearchTool ]:
5068 """Create Azure AI Search tool (RAG capability)."""
51- if not (self .client and self .search and self .search .connection_name and self .search .index_name ):
52- self .logger .info ("Azure AI Search tool not enabled (missing config or client)." )
69+ if not (
70+ self .client
71+ and self .search
72+ and self .search .connection_name
73+ and self .search .index_name
74+ ):
75+ self .logger .info (
76+ "Azure AI Search tool not enabled (missing config or client)."
77+ )
5378 return None
5479
5580 try :
56- self ._search_connection = await self .client .connections .get (name = self .search .connection_name )
57- self .logger .info ("Found Azure AI Search connection: %s" , self ._search_connection .id )
81+ self ._search_connection = await self .client .connections .get (
82+ name = self .search .connection_name
83+ )
84+ self .logger .info (
85+ "Found Azure AI Search connection: %s" , self ._search_connection .id
86+ )
5887
5988 return AzureAISearchTool (
6089 index_connection_id = self ._search_connection .id ,
@@ -102,54 +131,39 @@ async def _collect_tools_and_resources(self) -> tuple[List, dict]:
102131 # Agent lifecycle override
103132 # -------------------------
104133 async def _after_open (self ) -> None :
105- """Create or reuse Azure AI agent definition and wrap with AzureAIAgentClient."""
106- definition = await self ._get_azure_ai_agent_definition (self .agent_name )
107-
108- if definition is not None :
109- if not await self ._check_connection_compatibility (definition ):
110- try :
111- await self .client .agents .delete_agent (definition .id )
112- self .logger .info (
113- "Deleted incompatible existing agent '%s'; will recreate with new connection settings." ,
114- self .agent_name ,
115- )
116- except Exception as ex :
117- self .logger .warning (
118- "Failed deleting incompatible agent '%s': %s (will still recreate)." ,
119- self .agent_name ,
120- ex ,
121- )
122- definition = None
123-
124- if definition is None :
134+ # Instantiate persistent AzureAIAgentClient bound to existing agent_id
135+ try :
136+ # AzureAIAgentClient(
137+ # project_client=self.client,
138+ # agent_id=str(definition.id),
139+ # agent_name=self.agent_name,
140+ # )
125141 tools , tool_resources = await self ._collect_tools_and_resources ()
126- definition = await self .client .agents .create_agent (
127- model = self .model_deployment_name ,
142+ self ._agent = ChatAgent (
143+ chat_client = self .client ,
144+ instructions = self .agent_description + " " + self .agent_instructions ,
128145 name = self .agent_name ,
129146 description = self .agent_description ,
130- instructions = self .agent_instructions ,
131- tools = tools ,
132- tool_resources = tool_resources ,
147+ tools = tools if tools else None ,
148+ tool_choice = "auto" if tools else "none" ,
149+ allow_multiple_tool_calls = True ,
150+ temperature = 0.7 ,
133151 )
134- self .logger .info ("Created new Azure AI agent definition '%s'" , self .agent_name )
135152
136- # Instantiate persistent AzureAIAgentClient bound to existing agent_id
137- try :
138- self ._agent = AzureAIAgentClient (
139- project_client = self .client ,
140- agent_id = str (definition .id ),
141- agent_name = self .agent_name ,
142- )
143153 except Exception as ex :
144154 self .logger .error ("Failed to initialize AzureAIAgentClient: %s" , ex )
145155 raise
146156
147157 # Register agent globally
148158 try :
149159 agent_registry .register_agent (self )
150- self .logger .info ("Registered agent '%s' in global registry." , self .agent_name )
160+ self .logger .info (
161+ "Registered agent '%s' in global registry." , self .agent_name
162+ )
151163 except Exception as reg_ex :
152- self .logger .warning ("Could not register agent '%s': %s" , self .agent_name , reg_ex )
164+ self .logger .warning (
165+ "Could not register agent '%s': %s" , self .agent_name , reg_ex
166+ )
153167
154168 # -------------------------
155169 # Definition compatibility
@@ -163,21 +177,29 @@ async def _check_connection_compatibility(self, existing_definition: Agent) -> b
163177
164178 tool_resources = getattr (existing_definition , "tool_resources" , None )
165179 if not tool_resources :
166- self .logger .info ("Existing agent has no tool resources; incompatible with search requirement." )
180+ self .logger .info (
181+ "Existing agent has no tool resources; incompatible with search requirement."
182+ )
167183 return False
168184
169185 azure_search = tool_resources .get ("azure_ai_search" , {})
170186 indexes = azure_search .get ("indexes" , [])
171187 if not indexes :
172- self .logger .info ("Existing agent has no Azure AI Search indexes; incompatible." )
188+ self .logger .info (
189+ "Existing agent has no Azure AI Search indexes; incompatible."
190+ )
173191 return False
174192
175193 existing_conn_id = indexes [0 ].get ("index_connection_id" )
176194 if not existing_conn_id :
177- self .logger .info ("Existing agent missing index_connection_id; incompatible." )
195+ self .logger .info (
196+ "Existing agent missing index_connection_id; incompatible."
197+ )
178198 return False
179199
180- current_connection = await self .client .connections .get (name = self .search .connection_name )
200+ current_connection = await self .client .connections .get (
201+ name = self .search .connection_name
202+ )
181203 same = existing_conn_id == current_connection .id
182204 if same :
183205 self .logger .info ("Search connection compatible: %s" , existing_conn_id )
@@ -197,7 +219,9 @@ async def _get_azure_ai_agent_definition(self, agent_name: str) -> Agent | None:
197219 try :
198220 async for agent in self .client .agents .list_agents ():
199221 if agent .name == agent_name :
200- self .logger .info ("Found existing agent '%s' (id=%s)." , agent_name , agent .id )
222+ self .logger .info (
223+ "Found existing agent '%s' (id=%s)." , agent_name , agent .id
224+ )
201225 return await self .client .agents .get_agent (agent .id )
202226 return None
203227 except Exception as e :
@@ -226,7 +250,12 @@ async def fetch_run_details(self, thread_id: str, run_id: str) -> None:
226250 getattr (run , "usage" , None ),
227251 )
228252 except Exception as ex :
229- self .logger .error ("Failed fetching run details (thread=%s run=%s): %s" , thread_id , run_id , ex )
253+ self .logger .error (
254+ "Failed fetching run details (thread=%s run=%s): %s" ,
255+ thread_id ,
256+ run_id ,
257+ ex ,
258+ )
230259
231260 # -------------------------
232261 # Invocation (streaming)
@@ -257,10 +286,10 @@ async def invoke(self, prompt: str):
257286 temperature = 0.7 ,
258287 )
259288
260- async for update in self ._agent .get_streaming_response (
289+ async for update in self ._agent .run_stream (
261290 messages = messages ,
262- chat_options = chat_options ,
263- instructions = self .agent_instructions ,
291+ # chat_options=chat_options,
292+ # instructions=self.agent_instructions,
264293 ):
265294 yield update
266295
@@ -287,4 +316,4 @@ async def create_foundry_agent(
287316 search_config = search_config ,
288317 )
289318 await agent .open ()
290- return agent
319+ return agent
0 commit comments