|
14 | 14 | import importlib.util |
15 | 15 | import os |
16 | 16 | import logging |
| 17 | +import re |
| 18 | +import keyword |
17 | 19 |
|
18 | 20 | # Framework-specific imports with availability checks |
19 | 21 | CREWAI_AVAILABLE = False |
@@ -82,6 +84,40 @@ class BaseTool: |
82 | 84 | def noop(*args, **kwargs): |
83 | 85 | pass |
84 | 86 |
|
| 87 | +def sanitize_agent_name_for_autogen_v4(name): |
| 88 | + """ |
| 89 | + Sanitize agent name to be a valid Python identifier for AutoGen v0.4. |
| 90 | + |
| 91 | + Args: |
| 92 | + name (str): The original agent name |
| 93 | + |
| 94 | + Returns: |
| 95 | + str: A valid Python identifier |
| 96 | + """ |
| 97 | + # Convert to string and replace invalid characters with underscores |
| 98 | + sanitized = re.sub(r'[^a-zA-Z0-9_]', '_', str(name)) |
| 99 | + |
| 100 | + # Collapse only very excessive underscores (5 or more) to reduce extreme cases |
| 101 | + sanitized = re.sub(r'_{5,}', '_', sanitized) |
| 102 | + |
| 103 | + # Remove trailing underscores only if not part of a dunder pattern and only if singular |
| 104 | + if sanitized.endswith('_') and not sanitized.endswith('__') and sanitized != '_': |
| 105 | + sanitized = sanitized.rstrip('_') |
| 106 | + |
| 107 | + # Ensure it starts with a letter or underscore (not a digit) |
| 108 | + if sanitized and sanitized[0].isdigit(): |
| 109 | + sanitized = 'agent_' + sanitized |
| 110 | + |
| 111 | + # Handle empty string or only invalid characters (including single underscore from all invalid chars) |
| 112 | + if not sanitized or sanitized == '_': |
| 113 | + sanitized = 'agent' |
| 114 | + |
| 115 | + # Check if it's a Python keyword and append underscore if so |
| 116 | + if keyword.iskeyword(sanitized): |
| 117 | + sanitized += '_' |
| 118 | + |
| 119 | + return sanitized |
| 120 | + |
85 | 121 | def disable_crewai_telemetry(): |
86 | 122 | if CREWAI_AVAILABLE: |
87 | 123 | for attr in dir(Telemetry): |
@@ -471,7 +507,9 @@ async def run_autogen_v4_async(): |
471 | 507 |
|
472 | 508 | # Create agents from config |
473 | 509 | for role, details in config['roles'].items(): |
| 510 | + # For AutoGen v0.4, ensure agent name is a valid Python identifier |
474 | 511 | agent_name = details['role'].format(topic=topic).replace("{topic}", topic) |
| 512 | + agent_name = sanitize_agent_name_for_autogen_v4(agent_name) |
475 | 513 | backstory = details['backstory'].format(topic=topic) |
476 | 514 |
|
477 | 515 | # Convert tools for v0.4 - simplified tool passing |
|
0 commit comments