ag2 0.9.9__py3-none-any.whl → 0.9.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ag2 might be problematic. Click here for more details.
- {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/METADATA +232 -210
- {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/RECORD +88 -80
- autogen/_website/generate_mkdocs.py +3 -3
- autogen/_website/notebook_processor.py +1 -1
- autogen/_website/utils.py +1 -1
- autogen/agentchat/assistant_agent.py +15 -15
- autogen/agentchat/chat.py +52 -40
- autogen/agentchat/contrib/agent_eval/criterion.py +1 -1
- autogen/agentchat/contrib/capabilities/text_compressors.py +5 -5
- autogen/agentchat/contrib/capabilities/tools_capability.py +1 -1
- autogen/agentchat/contrib/capabilities/transforms.py +1 -1
- autogen/agentchat/contrib/captainagent/agent_builder.py +1 -1
- autogen/agentchat/contrib/captainagent/captainagent.py +20 -19
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +2 -5
- autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +5 -5
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +18 -17
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +2 -2
- autogen/agentchat/contrib/rag/query_engine.py +11 -11
- autogen/agentchat/contrib/retrieve_assistant_agent.py +3 -0
- autogen/agentchat/contrib/swarm_agent.py +3 -2
- autogen/agentchat/contrib/vectordb/couchbase.py +1 -1
- autogen/agentchat/contrib/vectordb/mongodb.py +1 -1
- autogen/agentchat/contrib/web_surfer.py +1 -1
- autogen/agentchat/conversable_agent.py +184 -80
- autogen/agentchat/group/context_expression.py +21 -21
- autogen/agentchat/group/handoffs.py +11 -11
- autogen/agentchat/group/multi_agent_chat.py +3 -2
- autogen/agentchat/group/on_condition.py +11 -11
- autogen/agentchat/group/safeguards/__init__.py +21 -0
- autogen/agentchat/group/safeguards/api.py +224 -0
- autogen/agentchat/group/safeguards/enforcer.py +1064 -0
- autogen/agentchat/group/safeguards/events.py +119 -0
- autogen/agentchat/group/safeguards/validator.py +435 -0
- autogen/agentchat/groupchat.py +58 -17
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +2 -2
- autogen/agentchat/realtime/experimental/function_observer.py +2 -3
- autogen/agentchat/realtime/experimental/realtime_agent.py +2 -3
- autogen/agentchat/realtime/experimental/realtime_swarm.py +21 -10
- autogen/agentchat/user_proxy_agent.py +55 -53
- autogen/agents/experimental/document_agent/document_agent.py +1 -10
- autogen/agents/experimental/document_agent/parser_utils.py +5 -1
- autogen/browser_utils.py +4 -4
- autogen/cache/abstract_cache_base.py +2 -6
- autogen/cache/disk_cache.py +1 -6
- autogen/cache/in_memory_cache.py +2 -6
- autogen/cache/redis_cache.py +1 -5
- autogen/coding/__init__.py +10 -2
- autogen/coding/base.py +2 -1
- autogen/coding/docker_commandline_code_executor.py +1 -6
- autogen/coding/factory.py +9 -0
- autogen/coding/jupyter/docker_jupyter_server.py +1 -7
- autogen/coding/jupyter/jupyter_client.py +2 -9
- autogen/coding/jupyter/jupyter_code_executor.py +2 -7
- autogen/coding/jupyter/local_jupyter_server.py +2 -6
- autogen/coding/local_commandline_code_executor.py +0 -65
- autogen/coding/yepcode_code_executor.py +197 -0
- autogen/environments/docker_python_environment.py +3 -3
- autogen/environments/system_python_environment.py +5 -5
- autogen/environments/venv_python_environment.py +5 -5
- autogen/events/agent_events.py +1 -1
- autogen/events/client_events.py +1 -1
- autogen/fast_depends/utils.py +10 -0
- autogen/graph_utils.py +5 -7
- autogen/import_utils.py +3 -1
- autogen/interop/pydantic_ai/pydantic_ai.py +8 -5
- autogen/io/processors/console_event_processor.py +8 -3
- autogen/llm_config/config.py +168 -91
- autogen/llm_config/entry.py +38 -26
- autogen/llm_config/types.py +35 -0
- autogen/llm_config/utils.py +223 -0
- autogen/mcp/mcp_proxy/operation_grouping.py +48 -39
- autogen/messages/agent_messages.py +1 -1
- autogen/messages/client_messages.py +1 -1
- autogen/oai/__init__.py +8 -1
- autogen/oai/client.py +10 -3
- autogen/oai/client_utils.py +1 -1
- autogen/oai/cohere.py +4 -4
- autogen/oai/gemini.py +4 -6
- autogen/oai/gemini_types.py +1 -0
- autogen/oai/openai_utils.py +44 -115
- autogen/tools/dependency_injection.py +4 -8
- autogen/tools/experimental/reliable/reliable.py +3 -2
- autogen/tools/experimental/web_search_preview/web_search_preview.py +1 -1
- autogen/tools/function_utils.py +2 -1
- autogen/version.py +1 -1
- {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/WHEEL +0 -0
- {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/licenses/LICENSE +0 -0
- {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
from ....llm_config import LLMConfig
|
|
10
|
+
|
|
11
|
+
# Import types that are safe to import at runtime
|
|
12
|
+
from ...agent import Agent
|
|
13
|
+
from ...conversable_agent import ConversableAgent
|
|
14
|
+
from ...groupchat import GroupChatManager
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .enforcer import SafeguardEnforcer
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def reset_safeguard_policy(
|
|
21
|
+
*,
|
|
22
|
+
agents: list[ConversableAgent] | None = None,
|
|
23
|
+
groupchat_manager: GroupChatManager | None = None,
|
|
24
|
+
) -> None:
|
|
25
|
+
"""Reset/remove all safeguards from agents and groupchat managers.
|
|
26
|
+
|
|
27
|
+
This function removes all safeguard hooks and inter-agent guardrails that were
|
|
28
|
+
previously applied by apply_safeguard_policy. Events are sent to track the reset process.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
agents: List of agents to remove safeguards from (optional if groupchat_manager provided)
|
|
32
|
+
groupchat_manager: GroupChatManager to remove safeguards from (optional if agents provided)
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
```python
|
|
36
|
+
from autogen.agentchat.group.safeguards import reset_safeguard_policy
|
|
37
|
+
|
|
38
|
+
# Remove safeguards from agents
|
|
39
|
+
reset_safeguard_policy(agents=[agent1, agent2, agent3])
|
|
40
|
+
|
|
41
|
+
# Or remove from GroupChatManager
|
|
42
|
+
reset_safeguard_policy(groupchat_manager=manager)
|
|
43
|
+
```
|
|
44
|
+
"""
|
|
45
|
+
from ....events.print_event import PrintEvent
|
|
46
|
+
from ....io.base import IOStream
|
|
47
|
+
|
|
48
|
+
iostream = IOStream.get_default()
|
|
49
|
+
|
|
50
|
+
# Send initial reset event
|
|
51
|
+
iostream.send(PrintEvent("Resetting safeguards..."))
|
|
52
|
+
# Determine which agents to remove safeguards from
|
|
53
|
+
target_agents: list[ConversableAgent | Agent] = []
|
|
54
|
+
|
|
55
|
+
if groupchat_manager:
|
|
56
|
+
if not isinstance(groupchat_manager, GroupChatManager):
|
|
57
|
+
raise ValueError("groupchat_manager must be an instance of GroupChatManager")
|
|
58
|
+
|
|
59
|
+
target_agents.extend([agent for agent in groupchat_manager.groupchat.agents if hasattr(agent, "hook_lists")])
|
|
60
|
+
|
|
61
|
+
agent_names = [agent.name for agent in target_agents]
|
|
62
|
+
iostream.send(PrintEvent(f"📋 Found {len(target_agents)} agents in GroupChat: {', '.join(agent_names)}"))
|
|
63
|
+
|
|
64
|
+
# Clear inter-agent guardrails from the groupchat
|
|
65
|
+
if hasattr(groupchat_manager.groupchat, "_inter_agent_guardrails"):
|
|
66
|
+
guardrail_count = len(groupchat_manager.groupchat._inter_agent_guardrails)
|
|
67
|
+
if guardrail_count > 0:
|
|
68
|
+
iostream.send(PrintEvent(f"🔗 Clearing {guardrail_count} inter-agent guardrails from GroupChat"))
|
|
69
|
+
groupchat_manager.groupchat._inter_agent_guardrails.clear()
|
|
70
|
+
|
|
71
|
+
elif agents:
|
|
72
|
+
target_agents.extend(agents)
|
|
73
|
+
agent_names = [agent.name for agent in target_agents]
|
|
74
|
+
iostream.send(PrintEvent(f"📋 Resetting safeguards for {len(target_agents)} agents: {', '.join(agent_names)}"))
|
|
75
|
+
else:
|
|
76
|
+
raise ValueError("Either agents or groupchat_manager must be provided")
|
|
77
|
+
|
|
78
|
+
# Remove safeguard hooks from each agent
|
|
79
|
+
safeguard_hook_names = [
|
|
80
|
+
"safeguard_tool_inputs",
|
|
81
|
+
"safeguard_tool_outputs",
|
|
82
|
+
"safeguard_llm_inputs",
|
|
83
|
+
"safeguard_llm_outputs",
|
|
84
|
+
"safeguard_human_inputs",
|
|
85
|
+
"process_message_before_send", # Inter-agent communication hooks for direct agent communication
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
for agent in target_agents:
|
|
89
|
+
if hasattr(agent, "hook_lists"):
|
|
90
|
+
# Use the agent's reset_safeguards method for agent-to-environment safeguards
|
|
91
|
+
if hasattr(agent, "reset_safeguards"):
|
|
92
|
+
agent.reset_safeguards()
|
|
93
|
+
else:
|
|
94
|
+
# Fallback to manual clearing for older agent versions
|
|
95
|
+
for hook_name in safeguard_hook_names:
|
|
96
|
+
if hook_name in agent.hook_lists:
|
|
97
|
+
# Clear all hooks in safeguard-specific hook lists
|
|
98
|
+
agent.hook_lists[hook_name].clear()
|
|
99
|
+
|
|
100
|
+
# Manually clear inter-agent safeguards (process_message_before_send)
|
|
101
|
+
if "process_message_before_send" in agent.hook_lists:
|
|
102
|
+
agent.hook_lists["process_message_before_send"].clear()
|
|
103
|
+
else:
|
|
104
|
+
raise ValueError(
|
|
105
|
+
f"Agent {agent.name} does not support hooks. Please ensure it inherits from ConversableAgent."
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Send completion event
|
|
109
|
+
iostream.send(PrintEvent(f"✅ Safeguard reset completed for {len(target_agents)} agents"))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def apply_safeguard_policy(
|
|
113
|
+
*,
|
|
114
|
+
agents: list[ConversableAgent] | None = None,
|
|
115
|
+
groupchat_manager: GroupChatManager | None = None,
|
|
116
|
+
policy: dict[str, Any] | str,
|
|
117
|
+
safeguard_llm_config: LLMConfig | None = None,
|
|
118
|
+
mask_llm_config: LLMConfig | None = None,
|
|
119
|
+
) -> SafeguardEnforcer:
|
|
120
|
+
"""Apply safeguards to agents using a policy file.
|
|
121
|
+
|
|
122
|
+
This is the main function for applying safeguards. It supports the policy format
|
|
123
|
+
with 'inter_agent_safeguards' and 'agent_environment_safeguards' sections.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
agents: List of agents to apply safeguards to (optional if groupchat_manager provided)
|
|
127
|
+
groupchat_manager: GroupChatManager to apply safeguards to (optional if agents provided)
|
|
128
|
+
policy: Safeguard policy dict or path to JSON file
|
|
129
|
+
safeguard_llm_config: LLM configuration for safeguard checks
|
|
130
|
+
mask_llm_config: LLM configuration for masking
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
SafeguardEnforcer instance for further configuration
|
|
134
|
+
|
|
135
|
+
Example:
|
|
136
|
+
```python
|
|
137
|
+
from autogen.agentchat.group.safeguards import apply_safeguard_policy
|
|
138
|
+
|
|
139
|
+
# Apply safeguards to agents
|
|
140
|
+
safeguard_enforcer = apply_safeguard_policy(
|
|
141
|
+
agents=[agent1, agent2, agent3],
|
|
142
|
+
policy="path/to/policy.json",
|
|
143
|
+
safeguard_llm_config=safeguard_llm_config,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Or apply to GroupChatManager
|
|
147
|
+
safeguard_enforcer = apply_safeguard_policy(
|
|
148
|
+
groupchat_manager=manager,
|
|
149
|
+
policy="path/to/policy.json",
|
|
150
|
+
safeguard_llm_config=safeguard_llm_config,
|
|
151
|
+
mask_llm_config=mask_llm_config,
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
"""
|
|
155
|
+
from .enforcer import SafeguardEnforcer
|
|
156
|
+
|
|
157
|
+
enforcer = SafeguardEnforcer(
|
|
158
|
+
policy=policy,
|
|
159
|
+
safeguard_llm_config=safeguard_llm_config,
|
|
160
|
+
mask_llm_config=mask_llm_config,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Determine which agents to apply safeguards to
|
|
164
|
+
target_agents: list[ConversableAgent | Agent] = []
|
|
165
|
+
all_agent_names = []
|
|
166
|
+
|
|
167
|
+
if groupchat_manager:
|
|
168
|
+
if not isinstance(groupchat_manager, GroupChatManager):
|
|
169
|
+
raise ValueError("groupchat_manager must be an instance of GroupChatManager")
|
|
170
|
+
|
|
171
|
+
target_agents.extend([agent for agent in groupchat_manager.groupchat.agents if hasattr(agent, "hook_lists")])
|
|
172
|
+
all_agent_names = [agent.name for agent in groupchat_manager.groupchat.agents]
|
|
173
|
+
all_agent_names.append(groupchat_manager.name)
|
|
174
|
+
|
|
175
|
+
# Register inter-agent guardrails with the groupchat
|
|
176
|
+
# Ensure the list exists and append our enforcer
|
|
177
|
+
if not hasattr(groupchat_manager.groupchat, "_inter_agent_guardrails"):
|
|
178
|
+
groupchat_manager.groupchat._inter_agent_guardrails = []
|
|
179
|
+
groupchat_manager.groupchat._inter_agent_guardrails.clear() # Clear any existing
|
|
180
|
+
groupchat_manager.groupchat._inter_agent_guardrails.append(enforcer)
|
|
181
|
+
elif agents:
|
|
182
|
+
target_agents.extend(agents)
|
|
183
|
+
all_agent_names = [agent.name for agent in agents]
|
|
184
|
+
else:
|
|
185
|
+
raise ValueError("Either agents or groupchat_manager must be provided")
|
|
186
|
+
|
|
187
|
+
# Build agent-to-tool mapping for validation
|
|
188
|
+
agent_tool_mapping = {}
|
|
189
|
+
for agent in target_agents:
|
|
190
|
+
agent_tools = []
|
|
191
|
+
|
|
192
|
+
# Get tools from the tools property (Tool objects)
|
|
193
|
+
if hasattr(agent, "tools"):
|
|
194
|
+
for tool in agent.tools:
|
|
195
|
+
agent_tools.append(tool.name)
|
|
196
|
+
|
|
197
|
+
# Get tools from function_map (functions registered with @register_for_execution)
|
|
198
|
+
if hasattr(agent, "function_map"):
|
|
199
|
+
agent_tools.extend(agent.function_map.keys())
|
|
200
|
+
|
|
201
|
+
agent_tool_mapping[agent.name] = agent_tools
|
|
202
|
+
|
|
203
|
+
# Validate policy including agent names and tool names
|
|
204
|
+
try:
|
|
205
|
+
from .validator import SafeguardValidator
|
|
206
|
+
|
|
207
|
+
validator = SafeguardValidator(enforcer.policy) # Use enforcer's loaded policy dict
|
|
208
|
+
validator.validate_policy_complete(agent_names=all_agent_names, agent_tool_mapping=agent_tool_mapping)
|
|
209
|
+
except ValueError as e:
|
|
210
|
+
raise ValueError(f"Policy validation failed: {e}")
|
|
211
|
+
|
|
212
|
+
# Apply hooks to each agent
|
|
213
|
+
for agent in target_agents:
|
|
214
|
+
if hasattr(agent, "hook_lists"):
|
|
215
|
+
hooks = enforcer.create_agent_hooks(agent.name)
|
|
216
|
+
for hook_name, hook_func in hooks.items():
|
|
217
|
+
if hook_name in agent.hook_lists:
|
|
218
|
+
agent.hook_lists[hook_name].append(hook_func)
|
|
219
|
+
else:
|
|
220
|
+
raise ValueError(
|
|
221
|
+
f"Agent {agent.name} does not support hooks. Please ensure it inherits from ConversableAgent."
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
return enforcer
|