Skip to content

Commit 4632bca

Browse files
committed
Refactor agent initialization to support persistent clients
Agent initialization now checks for existing database-backed AzureAIAgentClient instances and reuses them if available, improving persistence and resource management. The constructors for agent base classes were updated to accept and store model_deployment_name. FoundryAgentTemplate and ReasoningAgentTemplate now consistently use the database client if present, and only save new agents when necessary.
1 parent 654ffb2 commit 4632bca

File tree

3 files changed

+71
-68
lines changed

3 files changed

+71
-68
lines changed

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def __init__(
4949
agent_name: str | None = None,
5050
agent_description: str | None = None,
5151
agent_instructions: str | None = None,
52+
model_deployment_name: str | None = None,
5253
) -> None:
5354
self._stack: AsyncExitStack | None = None
5455
self.mcp_cfg: MCPConfig | None = mcp
@@ -63,6 +64,7 @@ def __init__(
6364
self.agent_name: str | None = agent_name
6465
self.agent_description: str | None = agent_description
6566
self.agent_instructions: str | None = agent_instructions
67+
self.model_deployment_name: str | None = model_deployment_name
6668
self.logger = logging.getLogger(__name__)
6769

6870
async def open(self) -> "MCPEnabledBase":
@@ -133,22 +135,27 @@ async def _after_open(self) -> None:
133135
"""Subclasses must build self._agent here."""
134136
raise NotImplementedError
135137

136-
async def get_database_team_agent(self) -> Optional[CurrentTeamAgent]:
138+
async def get_database_team_agent(self) -> Optional[AzureAIAgentClient]:
137139
"""Retrieve existing team agent from database, if any."""
138-
agent = None
140+
chat_client = None
139141
try:
140142
currentAgent = await self.memory_store.get_team_agent(
141143
team_id=self.team_config.team_id,
142144
agent_name=self.agent_name
143145
)
144146
if currentAgent and currentAgent.agent_foundry_id:
145-
agent = self.client.get_agent(
146-
agent_id=currentAgent.agent_foundry_id
147-
)
147+
agent = await self.client.get_agent(agent_id=currentAgent.agent_foundry_id)
148+
if agent:
149+
chat_client = AzureAIAgentClient(
150+
project_endpoint=self.project_endpoint,
151+
agent_id=currentAgent.agent_foundry_id,
152+
model_deployment_name=self.model_deployment_name,
153+
async_credential=self.creds,
154+
)
148155

149156
except Exception as ex: # Consider narrowing this to specific exceptions if possible
150157
self.logger.error("Failed to initialize ReasoningAgentTemplate: %s", ex)
151-
return agent
158+
return chat_client
152159

153160
async def save_database_team_agent(self) -> None:
154161
"""Save current team agent to database."""
@@ -213,13 +220,14 @@ def __init__(
213220
agent_name=agent_name,
214221
agent_description=agent_description,
215222
agent_instructions=agent_instructions,
223+
model_deployment_name=model_deployment_name,
216224
)
217225

218226
self._created_ephemeral: bool = (
219227
False # reserved if you add ephemeral agent cleanup
220228
)
221229

222-
self.model_deployment_name = model_deployment_name
230+
223231

224232
async def open(self) -> "AzureAgentBase":
225233
if self._stack is not None:

src/backend/v4/magentic_agents/foundry_agent.py

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ async def _collect_tools(self) -> List:
104104
# -------------------------
105105
# Azure Search helper
106106
# -------------------------
107-
async def _create_azure_search_enabled_client(self):
107+
async def _create_azure_search_enabled_client(self, chatClient=None) -> Optional[AzureAIAgentClient]:
108108
"""
109109
Create a server-side Azure AI agent with Azure AI Search raw tool.
110110
@@ -118,6 +118,9 @@ async def _create_azure_search_enabled_client(self):
118118
Returns:
119119
AzureAIAgentClient | None
120120
"""
121+
if chatClient:
122+
return chatClient
123+
121124
if not self.search:
122125
self.logger.error("Search configuration missing.")
123126
return None
@@ -217,55 +220,48 @@ async def _after_open(self) -> None:
217220
"""Initialize ChatAgent after connections are established."""
218221

219222
try:
220-
agent = await self.get_database_team_agent()
221-
if agent is None:
222-
if self._use_azure_search:
223-
# Azure Search mode (skip MCP + Code Interpreter due to incompatibility)
224-
self.logger.info(
225-
"Initializing agent in Azure AI Search mode (exclusive)."
226-
)
227-
chat_client = await self._create_azure_search_enabled_client()
228-
if not chat_client:
229-
raise RuntimeError(
230-
"Azure AI Search mode requested but setup failed."
231-
)
232-
233-
# In Azure Search raw tool path, tools/tool_choice are handled server-side.
234-
self._agent = ChatAgent(
235-
chat_client=chat_client,
236-
instructions=self.agent_instructions,
237-
name=self.agent_name,
238-
description=self.agent_description,
239-
tool_choice="required", # Force usage
240-
temperature=0.7,
241-
model_id=self.model_deployment_name,
242-
)
243-
else:
244-
# use MCP path
245-
self.logger.info("Initializing agent in MCP mode.")
246-
tools = await self._collect_tools()
247-
self._agent = ChatAgent(
248-
chat_client=AzureAIAgentClient(
249-
project_endpoint=self.project_endpoint,
250-
model_deployment_name=self.model_deployment_name,
251-
async_credential=self.creds,
252-
),
253-
instructions=self.agent_instructions,
254-
name=self.agent_name,
255-
description=self.agent_description,
256-
tools=tools if tools else None,
257-
tool_choice="auto" if tools else "none",
258-
temperature=0.7,
259-
model_id=self.model_deployment_name,
223+
chatClient= await self.get_database_team_agent()
224+
225+
if self._use_azure_search:
226+
# Azure Search mode (skip MCP + Code Interpreter due to incompatibility)
227+
self.logger.info(
228+
"Initializing agent in Azure AI Search mode (exclusive)."
229+
)
230+
chat_client = await self._create_azure_search_enabled_client(chatClient)
231+
if not chat_client:
232+
raise RuntimeError(
233+
"Azure AI Search mode requested but setup failed."
260234
)
261235

262-
self.logger.info("Initialized ChatAgent '%s'", self.agent_name)
236+
# In Azure Search raw tool path, tools/tool_choice are handled server-side.
237+
self._agent = ChatAgent(
238+
chat_client=chat_client,
239+
instructions=self.agent_instructions,
240+
name=self.agent_name,
241+
description=self.agent_description,
242+
tool_choice="required", # Force usage
243+
temperature=0.7,
244+
model_id=self.model_deployment_name,
245+
)
246+
else:
247+
# use MCP path
248+
self.logger.info("Initializing agent in MCP mode.")
249+
tools = await self._collect_tools()
250+
self._agent = ChatAgent(
251+
chat_client=chatClient or self.client,
252+
instructions=self.agent_instructions,
253+
name=self.agent_name,
254+
description=self.agent_description,
255+
tools=tools if tools else None,
256+
tool_choice="auto" if tools else "none",
257+
temperature=0.7,
258+
model_id=self.model_deployment_name,
259+
)
263260

261+
self.logger.info("Initialized ChatAgent '%s'", self.agent_name)
262+
if not chatClient: # Only save if we didn't load from DB
264263
await self.save_database_team_agent()
265264

266-
else:
267-
self.logger.info("Using existing ChatAgent '%s'", self.agent_name)
268-
self._agent = agent
269265
except Exception as ex:
270266
self.logger.error("Failed to initialize ChatAgent: %s", ex)
271267
raise

src/backend/v4/magentic_agents/reasoning_agent.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ def __init__(
7272
agent_name=agent_name,
7373
agent_description=agent_description,
7474
agent_instructions=agent_instructions,
75+
model_deployment_name=model_deployment_name,
7576
)
76-
self.model_deployment_name = model_deployment_name
77+
7778

7879
self.search_config = search_config
7980
self.max_search_docs = max_search_docs
@@ -106,22 +107,20 @@ async def _after_open(self) -> None:
106107
# Prepare tools for the agent
107108
tools = self._prepare_tools()
108109

109-
agent = await self.get_database_team_agent()
110-
if not agent:
111-
self._agent = ChatAgent(
112-
chat_client=self.client,
113-
instructions=self.base_instructions,
114-
name=self.agent_name,
115-
description=self.agent_description,
116-
tools=tools if tools else None,
117-
tool_choice="auto" if tools else "none",
118-
temperature=1.0, # Reasoning models use fixed temperature
119-
model_id=self.model_deployment_name,
120-
)
110+
chatClient = await self.get_database_team_agent()
111+
112+
self._agent = ChatAgent(
113+
chat_client = chatClient or self.client,
114+
instructions=self.agent_instructions,
115+
name=self.agent_name,
116+
description=self.agent_description,
117+
tools=tools if tools else None,
118+
tool_choice="auto" if tools else "none",
119+
temperature=1.0, # Reasoning models use fixed temperature
120+
model_id=self.model_deployment_name,
121+
)
122+
if not chatClient:
121123
await self.save_database_team_agent()
122-
123-
else:
124-
self._agent = agent
125124
self.logger.info("Using existing ReasoningAgent '%s'", self.agent_name)
126125
# Register agent globally
127126
try:

0 commit comments

Comments
 (0)