ag2 0.9.8.post1__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.

Files changed (88) hide show
  1. {ag2-0.9.8.post1.dist-info → ag2-0.9.10.dist-info}/METADATA +232 -210
  2. {ag2-0.9.8.post1.dist-info → ag2-0.9.10.dist-info}/RECORD +88 -80
  3. autogen/_website/generate_mkdocs.py +3 -3
  4. autogen/_website/notebook_processor.py +1 -1
  5. autogen/_website/utils.py +1 -1
  6. autogen/agentchat/assistant_agent.py +15 -15
  7. autogen/agentchat/chat.py +52 -40
  8. autogen/agentchat/contrib/agent_eval/criterion.py +1 -1
  9. autogen/agentchat/contrib/capabilities/text_compressors.py +5 -5
  10. autogen/agentchat/contrib/capabilities/tools_capability.py +1 -1
  11. autogen/agentchat/contrib/capabilities/transforms.py +1 -1
  12. autogen/agentchat/contrib/captainagent/agent_builder.py +1 -1
  13. autogen/agentchat/contrib/captainagent/captainagent.py +20 -19
  14. autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +2 -5
  15. autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +5 -5
  16. autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +18 -17
  17. autogen/agentchat/contrib/rag/mongodb_query_engine.py +2 -2
  18. autogen/agentchat/contrib/rag/query_engine.py +11 -11
  19. autogen/agentchat/contrib/retrieve_assistant_agent.py +3 -0
  20. autogen/agentchat/contrib/swarm_agent.py +3 -2
  21. autogen/agentchat/contrib/vectordb/couchbase.py +1 -1
  22. autogen/agentchat/contrib/vectordb/mongodb.py +1 -1
  23. autogen/agentchat/contrib/web_surfer.py +1 -1
  24. autogen/agentchat/conversable_agent.py +184 -80
  25. autogen/agentchat/group/context_expression.py +21 -21
  26. autogen/agentchat/group/handoffs.py +11 -11
  27. autogen/agentchat/group/multi_agent_chat.py +3 -2
  28. autogen/agentchat/group/on_condition.py +11 -11
  29. autogen/agentchat/group/safeguards/__init__.py +21 -0
  30. autogen/agentchat/group/safeguards/api.py +224 -0
  31. autogen/agentchat/group/safeguards/enforcer.py +1064 -0
  32. autogen/agentchat/group/safeguards/events.py +119 -0
  33. autogen/agentchat/group/safeguards/validator.py +435 -0
  34. autogen/agentchat/groupchat.py +60 -19
  35. autogen/agentchat/realtime/experimental/clients/realtime_client.py +2 -2
  36. autogen/agentchat/realtime/experimental/function_observer.py +2 -3
  37. autogen/agentchat/realtime/experimental/realtime_agent.py +2 -3
  38. autogen/agentchat/realtime/experimental/realtime_swarm.py +21 -10
  39. autogen/agentchat/user_proxy_agent.py +55 -53
  40. autogen/agents/experimental/document_agent/document_agent.py +1 -10
  41. autogen/agents/experimental/document_agent/parser_utils.py +5 -1
  42. autogen/browser_utils.py +4 -4
  43. autogen/cache/abstract_cache_base.py +2 -6
  44. autogen/cache/disk_cache.py +1 -6
  45. autogen/cache/in_memory_cache.py +2 -6
  46. autogen/cache/redis_cache.py +1 -5
  47. autogen/coding/__init__.py +10 -2
  48. autogen/coding/base.py +2 -1
  49. autogen/coding/docker_commandline_code_executor.py +1 -6
  50. autogen/coding/factory.py +9 -0
  51. autogen/coding/jupyter/docker_jupyter_server.py +1 -7
  52. autogen/coding/jupyter/jupyter_client.py +2 -9
  53. autogen/coding/jupyter/jupyter_code_executor.py +2 -7
  54. autogen/coding/jupyter/local_jupyter_server.py +2 -6
  55. autogen/coding/local_commandline_code_executor.py +0 -65
  56. autogen/coding/yepcode_code_executor.py +197 -0
  57. autogen/environments/docker_python_environment.py +3 -3
  58. autogen/environments/system_python_environment.py +5 -5
  59. autogen/environments/venv_python_environment.py +5 -5
  60. autogen/events/agent_events.py +1 -1
  61. autogen/events/client_events.py +1 -1
  62. autogen/fast_depends/utils.py +10 -0
  63. autogen/graph_utils.py +5 -7
  64. autogen/import_utils.py +28 -15
  65. autogen/interop/pydantic_ai/pydantic_ai.py +8 -5
  66. autogen/io/processors/console_event_processor.py +8 -3
  67. autogen/llm_config/config.py +168 -91
  68. autogen/llm_config/entry.py +38 -26
  69. autogen/llm_config/types.py +35 -0
  70. autogen/llm_config/utils.py +223 -0
  71. autogen/mcp/mcp_proxy/operation_grouping.py +48 -39
  72. autogen/messages/agent_messages.py +1 -1
  73. autogen/messages/client_messages.py +1 -1
  74. autogen/oai/__init__.py +8 -1
  75. autogen/oai/client.py +10 -3
  76. autogen/oai/client_utils.py +1 -1
  77. autogen/oai/cohere.py +4 -4
  78. autogen/oai/gemini.py +4 -6
  79. autogen/oai/gemini_types.py +1 -0
  80. autogen/oai/openai_utils.py +44 -115
  81. autogen/tools/dependency_injection.py +4 -8
  82. autogen/tools/experimental/reliable/reliable.py +3 -2
  83. autogen/tools/experimental/web_search_preview/web_search_preview.py +1 -1
  84. autogen/tools/function_utils.py +2 -1
  85. autogen/version.py +1 -1
  86. {ag2-0.9.8.post1.dist-info → ag2-0.9.10.dist-info}/WHEEL +0 -0
  87. {ag2-0.9.8.post1.dist-info → ag2-0.9.10.dist-info}/licenses/LICENSE +0 -0
  88. {ag2-0.9.8.post1.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