1- """Utility functions for agent_framework-based integration and agent management (converted from agent framework ) ."""
1+ """Utility functions for agent_framework-based integration and agent management."""
22
3+ from http import client
34import logging
5+ import secrets
6+ import string
7+ from typing import Optional # <-- Add this import
8+
9+ from tomlkit import (
10+ string as toml_string ,
11+ ) # <-- If you need tomlkit.string elsewhere, alias it
412
513from common .config .app_config import config
6- # Converted import path (agent_framework version of FoundryAgentTemplate)
14+
715from common .database .database_base import DatabaseBase
816from common .models .messages_af import TeamConfiguration
917from v4 .common .services .team_service import TeamService
1018from v4 .config .agent_registry import agent_registry
11- from v4 .magentic_agents .foundry_agent import \
12- FoundryAgentTemplate # formerly v4.magentic_agents.foundry_agent
19+ from v4 .magentic_agents .foundry_agent import (
20+ FoundryAgentTemplate ,
21+ ) # formerly v4.magentic_agents.foundry_agent
1322
1423logging .basicConfig (level = logging .INFO )
1524
25+
1626async def find_first_available_team (team_service : TeamService , user_id : str ) -> str :
1727 """
1828 Check teams in priority order (4 to 1) and return the first available team ID.
@@ -38,7 +48,10 @@ async def find_first_available_team(team_service: TeamService, user_id: str) ->
3848 print ("No teams found in priority order" )
3949 return None
4050
41- async def create_RAI_agent (team : TeamConfiguration , memory_store : DatabaseBase ) -> FoundryAgentTemplate :
51+
52+ async def create_RAI_agent (
53+ team : TeamConfiguration , memory_store : DatabaseBase
54+ ) -> FoundryAgentTemplate :
4255 """Create and initialize a FoundryAgentTemplate for Responsible AI (RAI) checks."""
4356 agent_name = "RAIAgent"
4457 agent_description = "A comprehensive research assistant for integration testing"
@@ -55,7 +68,7 @@ async def create_RAI_agent(team: TeamConfiguration, memory_store: DatabaseBase)
5568 "- Is completely meaningless, incoherent, or appears to be spam\n "
5669 "Respond with 'TRUE' if the input violates any rules and should be blocked, otherwise respond with 'FALSE'."
5770 )
58-
71+
5972 model_deployment_name = config .AZURE_OPENAI_DEPLOYMENT_NAME
6073 team .team_id = "rai_team" # Use a fixed team ID for RAI agent
6174 team .name = "RAI Team"
@@ -114,7 +127,9 @@ async def _get_agent_response(agent: FoundryAgentTemplate, query: str) -> str:
114127 return "TRUE" # Default to blocking on error
115128
116129
117- async def rai_success (description : str , team_config : TeamConfiguration , memory_store : DatabaseBase ) -> bool :
130+ async def rai_success (
131+ description : str , team_config : TeamConfiguration , memory_store : DatabaseBase
132+ ) -> bool :
118133 """
119134 Run a RAI compliance check on the provided description using the RAIAgent.
120135 Returns True if content is safe (should proceed), False if it should be blocked.
@@ -148,7 +163,9 @@ async def rai_success(description: str, team_config: TeamConfiguration, memory_
148163 pass
149164
150165
151- async def rai_validate_team_config (team_config_json : dict , team_config : TeamConfiguration , memory_store : DatabaseBase ) -> tuple [bool , str ]:
166+ async def rai_validate_team_config (
167+ team_config_json : dict , memory_store : DatabaseBase
168+ ) -> tuple [bool , str ]:
152169 """
153170 Validate a team configuration for RAI compliance.
154171
@@ -189,7 +206,7 @@ async def rai_validate_team_config(team_config_json: dict, team_config: TeamConf
189206 combined = " " .join (text_content ).strip ()
190207 if not combined :
191208 return False , "Team configuration contains no readable text content."
192-
209+ team_config = TeamConfiguration ( ** team_config_json )
193210 if not await rai_success (combined , team_config , memory_store ):
194211 return (
195212 False ,
@@ -200,3 +217,37 @@ async def rai_validate_team_config(team_config_json: dict, team_config: TeamConf
200217 except Exception as e :
201218 logging .error ("Error validating team configuration content: %s" , e )
202219 return False , "Unable to validate team configuration content. Please try again."
220+
221+
222+ def generate_assistant_id (prefix : str = "asst_" , length : int = 24 ) -> str :
223+ """
224+ Generate a unique ID like 'asst_jRgR5t2U7o8nUPkNGv5HWOgV'.
225+
226+ - prefix: leading string (defaults to 'asst_')
227+ - length: number of random characters after the prefix
228+ """
229+ # URL-safe characters similar to what OpenAI-style IDs use
230+ alphabet = string .ascii_letters + string .digits # a-zA-Z0-9
231+
232+ # cryptographically strong randomness
233+ random_part = "" .join (secrets .choice (alphabet ) for _ in range (length ))
234+ return f"{ prefix } { random_part } "
235+
236+
237+ async def get_database_team_agent_id (
238+ memory_store : DatabaseBase , team_config : TeamConfiguration , agent_name : str
239+ ) -> Optional [str ]:
240+ """Retrieve existing team agent from database, if any."""
241+ agent_id = None
242+ try :
243+ currentAgent = await memory_store .get_team_agent (
244+ team_id = team_config .team_id , agent_name = agent_name
245+ )
246+ if currentAgent and currentAgent .agent_foundry_id :
247+ agent_id = currentAgent .agent_foundry_id
248+
249+ except (
250+ Exception
251+ ) as ex : # Consider narrowing this to specific exceptions if possible
252+ logging .error ("Failed to initialize Get database team agent: %s" , ex )
253+ return agent_id
0 commit comments