ag2 0.9.1.post0__py3-none-any.whl → 0.9.3__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 (37) hide show
  1. {ag2-0.9.1.post0.dist-info → ag2-0.9.3.dist-info}/METADATA +22 -12
  2. {ag2-0.9.1.post0.dist-info → ag2-0.9.3.dist-info}/RECORD +37 -23
  3. autogen/agentchat/contrib/capabilities/transforms.py +22 -9
  4. autogen/agentchat/conversable_agent.py +37 -34
  5. autogen/agentchat/group/group_utils.py +65 -20
  6. autogen/agentchat/group/handoffs.py +81 -5
  7. autogen/agentchat/group/on_context_condition.py +2 -2
  8. autogen/agentchat/group/patterns/pattern.py +7 -1
  9. autogen/agentchat/groupchat.py +2 -2
  10. autogen/agentchat/realtime/experimental/realtime_swarm.py +12 -4
  11. autogen/agents/experimental/document_agent/document_agent.py +232 -40
  12. autogen/events/agent_events.py +7 -4
  13. autogen/interop/litellm/litellm_config_factory.py +68 -2
  14. autogen/llm_config.py +4 -1
  15. autogen/mcp/__main__.py +78 -0
  16. autogen/mcp/mcp_proxy/__init__.py +19 -0
  17. autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +63 -0
  18. autogen/mcp/mcp_proxy/mcp_proxy.py +581 -0
  19. autogen/mcp/mcp_proxy/operation_grouping.py +158 -0
  20. autogen/mcp/mcp_proxy/operation_renaming.py +114 -0
  21. autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
  22. autogen/mcp/mcp_proxy/security.py +400 -0
  23. autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
  24. autogen/oai/client.py +11 -2
  25. autogen/oai/gemini.py +20 -3
  26. autogen/oai/gemini_types.py +27 -0
  27. autogen/oai/oai_models/chat_completion.py +1 -1
  28. autogen/tools/experimental/__init__.py +5 -0
  29. autogen/tools/experimental/reliable/__init__.py +10 -0
  30. autogen/tools/experimental/reliable/reliable.py +1316 -0
  31. autogen/version.py +1 -1
  32. templates/client_template/main.jinja2 +69 -0
  33. templates/config_template/config.jinja2 +7 -0
  34. templates/main.jinja2 +61 -0
  35. {ag2-0.9.1.post0.dist-info → ag2-0.9.3.dist-info}/WHEEL +0 -0
  36. {ag2-0.9.1.post0.dist-info → ag2-0.9.3.dist-info}/licenses/LICENSE +0 -0
  37. {ag2-0.9.1.post0.dist-info → ag2-0.9.3.dist-info}/licenses/NOTICE.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ag2
3
- Version: 0.9.1.post0
3
+ Version: 0.9.3
4
4
  Summary: A programming framework for agentic AI
5
5
  Project-URL: Homepage, https://ag2.ai/
6
6
  Project-URL: Documentation, https://docs.ag2.ai
@@ -72,7 +72,7 @@ Requires-Dist: azure-cosmos>=4.2.0; extra == 'cosmosdb'
72
72
  Provides-Extra: crawl4ai
73
73
  Requires-Dist: crawl4ai<0.5,>=0.4.247; extra == 'crawl4ai'
74
74
  Provides-Extra: deepseek
75
- Requires-Dist: openai>=1.66.2; extra == 'deepseek'
75
+ Requires-Dist: openai>=1.87.0; extra == 'deepseek'
76
76
  Provides-Extra: dev
77
77
  Requires-Dist: cairosvg; extra == 'dev'
78
78
  Requires-Dist: codespell==2.4.1; extra == 'dev'
@@ -96,7 +96,7 @@ Requires-Dist: mypy==1.15.0; extra == 'dev'
96
96
  Requires-Dist: nbclient==0.10.2; extra == 'dev'
97
97
  Requires-Dist: nbconvert==7.16.6; extra == 'dev'
98
98
  Requires-Dist: nbformat==5.10.4; extra == 'dev'
99
- Requires-Dist: openai>=1.66.2; extra == 'dev'
99
+ Requires-Dist: openai>=1.87.0; extra == 'dev'
100
100
  Requires-Dist: pandas==2.2.3; extra == 'dev'
101
101
  Requires-Dist: pdoc3==0.11.6; extra == 'dev'
102
102
  Requires-Dist: pillow; extra == 'dev'
@@ -130,6 +130,8 @@ Requires-Dist: pillow; extra == 'docs'
130
130
  Requires-Dist: pyyaml==6.0.2; extra == 'docs'
131
131
  Requires-Dist: termcolor==3.0.1; extra == 'docs'
132
132
  Requires-Dist: typer==0.15.2; extra == 'docs'
133
+ Provides-Extra: duckduckgo
134
+ Requires-Dist: duckduckgo-search>=8.0.2; extra == 'duckduckgo'
133
135
  Provides-Extra: flaml
134
136
  Requires-Dist: flaml; extra == 'flaml'
135
137
  Requires-Dist: numpy<2.0.0,>=1.24.0; (python_version < '3.13') and extra == 'flaml'
@@ -138,14 +140,14 @@ Provides-Extra: gemini
138
140
  Requires-Dist: google-api-core; extra == 'gemini'
139
141
  Requires-Dist: google-auth; extra == 'gemini'
140
142
  Requires-Dist: google-cloud-aiplatform; extra == 'gemini'
141
- Requires-Dist: google-genai>=1.2.0; extra == 'gemini'
143
+ Requires-Dist: google-genai>=1.20.0; extra == 'gemini'
142
144
  Requires-Dist: jsonschema; extra == 'gemini'
143
145
  Requires-Dist: pillow; extra == 'gemini'
144
146
  Provides-Extra: gemini-realtime
145
147
  Requires-Dist: google-api-core; extra == 'gemini-realtime'
146
148
  Requires-Dist: google-auth; extra == 'gemini-realtime'
147
149
  Requires-Dist: google-cloud-aiplatform; extra == 'gemini-realtime'
148
- Requires-Dist: google-genai>=1.2.0; extra == 'gemini-realtime'
150
+ Requires-Dist: google-genai>=1.20.0; extra == 'gemini-realtime'
149
151
  Requires-Dist: jsonschema; extra == 'gemini-realtime'
150
152
  Requires-Dist: pillow; extra == 'gemini-realtime'
151
153
  Requires-Dist: websockets<16,>=14.0; extra == 'gemini-realtime'
@@ -198,7 +200,13 @@ Provides-Extra: mathchat
198
200
  Requires-Dist: sympy; extra == 'mathchat'
199
201
  Requires-Dist: wolframalpha; extra == 'mathchat'
200
202
  Provides-Extra: mcp
201
- Requires-Dist: mcp<1.6,>=1.4.0; (python_version >= '3.10') and extra == 'mcp'
203
+ Requires-Dist: mcp>=1.9.4; (python_version >= '3.10') and extra == 'mcp'
204
+ Provides-Extra: mcp-proxy-gen
205
+ Requires-Dist: fastapi-code-generator>=0.5.4; extra == 'mcp-proxy-gen'
206
+ Requires-Dist: fastapi<1,>=0.112; extra == 'mcp-proxy-gen'
207
+ Requires-Dist: pyyaml; extra == 'mcp-proxy-gen'
208
+ Requires-Dist: requests; extra == 'mcp-proxy-gen'
209
+ Requires-Dist: typer; extra == 'mcp-proxy-gen'
202
210
  Provides-Extra: mistral
203
211
  Requires-Dist: mistralai>=1.0.1; extra == 'mistral'
204
212
  Provides-Extra: neo4j
@@ -210,9 +218,9 @@ Provides-Extra: ollama
210
218
  Requires-Dist: fix-busted-json>=0.0.18; extra == 'ollama'
211
219
  Requires-Dist: ollama>=0.4.7; extra == 'ollama'
212
220
  Provides-Extra: openai
213
- Requires-Dist: openai>=1.66.2; extra == 'openai'
221
+ Requires-Dist: openai>=1.87.0; extra == 'openai'
214
222
  Provides-Extra: openai-realtime
215
- Requires-Dist: openai>=1.66.2; extra == 'openai-realtime'
223
+ Requires-Dist: openai>=1.87.0; extra == 'openai-realtime'
216
224
  Requires-Dist: openai[realtime]; extra == 'openai-realtime'
217
225
  Provides-Extra: rag
218
226
  Requires-Dist: chromadb<1,>=0.5; extra == 'rag'
@@ -276,6 +284,8 @@ Requires-Dist: protobuf==5.29.3; extra == 'retrievechat-qdrant'
276
284
  Requires-Dist: pypdf; extra == 'retrievechat-qdrant'
277
285
  Requires-Dist: qdrant-client; extra == 'retrievechat-qdrant'
278
286
  Requires-Dist: sentence-transformers<=4.1.0; extra == 'retrievechat-qdrant'
287
+ Provides-Extra: tavily
288
+ Requires-Dist: tavily-python>=0.7.4; extra == 'tavily'
279
289
  Provides-Extra: teachable
280
290
  Requires-Dist: chromadb; extra == 'teachable'
281
291
  Provides-Extra: test
@@ -303,7 +313,7 @@ Requires-Dist: mock==5.2.0; extra == 'types'
303
313
  Requires-Dist: mypy==1.15.0; extra == 'types'
304
314
  Requires-Dist: nbconvert==7.16.6; extra == 'types'
305
315
  Requires-Dist: nbformat==5.10.4; extra == 'types'
306
- Requires-Dist: openai>=1.66.2; extra == 'types'
316
+ Requires-Dist: openai>=1.87.0; extra == 'types'
307
317
  Requires-Dist: pandas==2.2.3; extra == 'types'
308
318
  Requires-Dist: pytest-asyncio==0.26.0; extra == 'types'
309
319
  Requires-Dist: pytest-cov==6.1.1; extra == 'types'
@@ -613,7 +623,7 @@ teacher.initiate_chat(
613
623
 
614
624
  When executed, this code creates a collaborative system where the teacher initiates the conversation, and the lesson planner and reviewer agents work together to create and refine a lesson plan. The GroupChatManager orchestrates the conversation, selecting the next agent to respond based on the context of the discussion.
615
625
 
616
- For workflows requiring more structured processes, explore the Swarm pattern in the detailed [documentation](https://docs.ag2.ai/latest/docs/user-guide/advanced-concepts/conversation-patterns-deep-dive).
626
+ For workflows requiring more structured processes, explore the Group Chat pattern in the detailed [documentation](https://docs.ag2.ai/latest/docs/user-guide/advanced-concepts/orchestration/group-chat/introduction).
617
627
 
618
628
  ### Tools
619
629
 
@@ -672,9 +682,9 @@ AG2 supports more advanced concepts to help you build your AI agent workflows. Y
672
682
 
673
683
  - [Structured Output](https://docs.ag2.ai/latest/docs/user-guide/basic-concepts/structured-outputs)
674
684
  - [Ending a conversation](https://docs.ag2.ai/latest/docs/user-guide/advanced-concepts/orchestration/ending-a-chat/)
675
- - [Retrieval Augmented Generation (RAG)](https://docs.ag2.ai/docs/user-guide/advanced-concepts/rag)
685
+ - [Retrieval Augmented Generation (RAG)](https://docs.ag2.ai/latest/docs/user-guide/advanced-concepts/rag/)
676
686
  - [Code Execution](https://docs.ag2.ai/latest/docs/user-guide/advanced-concepts/code-execution)
677
- - [Tools with Secrets](https://docs.ag2.ai/latest/docs/user-guide/basic-concepts/introducing-tools/tools-with-secrets)
687
+ - [Tools with Secrets](https://docs.ag2.ai/latest/docs/user-guide/advanced-concepts/tools/tools-with-secrets/)
678
688
 
679
689
  ## Announcements
680
690
 
@@ -8,13 +8,13 @@ autogen/function_utils.py,sha256=YnzwNFA49Jbbe4riAY1sinYcKphg5lrHFCXx0POdYbw,481
8
8
  autogen/graph_utils.py,sha256=2dfGUHZCCF629vh0vMK9WMXIX-Zi-if9NbdC0KFcuw4,7904
9
9
  autogen/import_utils.py,sha256=byPlexRvu1bkGzEAtwwtJ2SQIm1IzModK9B5ONGkqJw,17634
10
10
  autogen/json_utils.py,sha256=_61k__3SS1-ffE2K5Mm9ZGHQJBRUbOL9kHGQGTAWRZk,1378
11
- autogen/llm_config.py,sha256=Vpm23hwFj_Xi6dzkPHpPv20P1Xeo4pUFPhhHTDsOncI,14107
11
+ autogen/llm_config.py,sha256=eFWSN9yR3w2R7d2CdDQ5ZpU2tUy8xBzEwGuq5K6QZLs,14172
12
12
  autogen/math_utils.py,sha256=Ew9-I5chny9eAOnphGxKf6XCeW6Pepz5S-5touWrbYU,9546
13
13
  autogen/retrieve_utils.py,sha256=R3Yp5d8dH4o9ayLZrGn4rCjIaY4glOHIiyQjwClmdi8,20087
14
14
  autogen/runtime_logging.py,sha256=yCmZODvwqYR91m8lX3Q4SoPcY-DK48NF4m56CP6Om3c,4692
15
15
  autogen/token_count_utils.py,sha256=n4wTFVNHwrfjZkrErFr8kNig2K-YCGgMLWsjDRS9D6g,10797
16
16
  autogen/types.py,sha256=qu-7eywhakW2AxQ5lYisLLeIg45UoOW-b3ErIuyRTuw,1000
17
- autogen/version.py,sha256=YukZ5zIFYpMhlQ_olcWkkgdY7RATOWxDna2VVuOd3NI,198
17
+ autogen/version.py,sha256=tN9tkN8TlaYs7tWFTkUc6inNMUFd2YXRCAXmqLFBOI4,193
18
18
  autogen/_website/__init__.py,sha256=c8B9TpO07x9neD0zsJWj6AaEdlcP-WvxrvVOGWLtamk,143
19
19
  autogen/_website/generate_api_references.py,sha256=yKqyeSP_NE27wwLYWsZbTYRceEoxzNxPXqn6vsIzEvk,14789
20
20
  autogen/_website/generate_mkdocs.py,sha256=TkmLnUDv1Ms5cGClXPmenA8nxmwg4kR0E-FHCVjw_og,43246
@@ -25,8 +25,8 @@ autogen/agentchat/__init__.py,sha256=d5jPpXeavynP9eh5uMIgJKbK3-3tywJBa6l3L9X4l34
25
25
  autogen/agentchat/agent.py,sha256=HePNJ5BXJTcZtaD2a8CoTeHAoLUUy3scM6Ihm-NsSWk,5828
26
26
  autogen/agentchat/assistant_agent.py,sha256=XTJvD66r4qYkdNAJJLr1CC-wTYFJWvhmD5_G0WbbX2I,5741
27
27
  autogen/agentchat/chat.py,sha256=6Gx2t1-Xa8kP6ZoUihHBNGOqNlrGhhqLPKrckL0n-RI,14003
28
- autogen/agentchat/conversable_agent.py,sha256=x2-UQzDJ_dhteicsS2eAKRTG8ozDrqdWh0ZawuFy6iI,191305
29
- autogen/agentchat/groupchat.py,sha256=eh_JNZWU-0gbxO7rIngokh71kpHLkA1Qunn6zXDdM0k,85361
28
+ autogen/agentchat/conversable_agent.py,sha256=F5OtTxBYb4Cqw5cp6V1gt8tL6EVVFuAKmbCR9SVosT8,191085
29
+ autogen/agentchat/groupchat.py,sha256=X54uAoAFYxMvxDVCMQJdlVnviOWvjqWp7bbt14PQUmk,85373
30
30
  autogen/agentchat/user_proxy_agent.py,sha256=-gbDblRvE09FGuVB6-y5ZT9Cpvv--rM3FMi8PnPIFBA,7445
31
31
  autogen/agentchat/utils.py,sha256=2ZweUqe4ynxji0jnvd0r9Uxg3n0elif4a-jZOyeeqcg,8238
32
32
  autogen/agentchat/contrib/__init__.py,sha256=tOTe4nwbKj7elHpftAy3zS_embMDzncrKL98XKhY6-c,168
@@ -58,7 +58,7 @@ autogen/agentchat/contrib/capabilities/teachability.py,sha256=tn3o7q-5vC7O-EFy7I
58
58
  autogen/agentchat/contrib/capabilities/text_compressors.py,sha256=tm5WDf0AC0VznFJ44Hy7zHh_Erar2c1OjExVt1MG8j8,2985
59
59
  autogen/agentchat/contrib/capabilities/tools_capability.py,sha256=iSECQqsHp-MBWu6Huo6OAH4ehSI04QYDGQBjUupFsPI,773
60
60
  autogen/agentchat/contrib/capabilities/transform_messages.py,sha256=bFUxDkq0jWLcgccE3Zp4_JD12zIVRE7AMVFwSJqssSY,3783
61
- autogen/agentchat/contrib/capabilities/transforms.py,sha256=Q_LSNQRRECKY1sd9r2KV6q4QukandWZSzVTgfgf1Rnk,25749
61
+ autogen/agentchat/contrib/capabilities/transforms.py,sha256=Ow3zPEPAnUfHoiH96vNxvjWGk5TVCqtttyqlkS3X2Dk,26292
62
62
  autogen/agentchat/contrib/capabilities/transforms_util.py,sha256=XjTkE_i-SArRPBuLmVaZYhJMY2RgNHjz2m_iF-lKUJM,4559
63
63
  autogen/agentchat/contrib/capabilities/vision_capability.py,sha256=kHUeIPvICOR-tLQ6g6AdNWtcbhrUKPIfg42ISqGzrA4,9872
64
64
  autogen/agentchat/contrib/captainagent/__init__.py,sha256=12X-ClPVPXBnN59wduSLhQ-PmUWXO45vvafHPQOUVV8,414
@@ -132,18 +132,18 @@ autogen/agentchat/group/context_expression.py,sha256=zFWPV3yfV-0ayYXfrhRq6iWQZnR
132
132
  autogen/agentchat/group/context_str.py,sha256=EHjpDr8MLMl5AMXktMi9Wp4BIL_1hbIeJPMEXlLkTjs,1270
133
133
  autogen/agentchat/group/context_variables.py,sha256=d2Q31aoV2o_5QSd3Oh1fYDIV0fDaaHOOsjNQ92TC_H0,5649
134
134
  autogen/agentchat/group/group_tool_executor.py,sha256=lCUg0Z_R8u0mRsWE350p6pGNj-6fJUMGqWqs3xmznCQ,9104
135
- autogen/agentchat/group/group_utils.py,sha256=XjVXvJ25Ka4l3kbPOVRgZbxM9PpaoS8ekQyeieJPF4U,25600
136
- autogen/agentchat/group/handoffs.py,sha256=ftGN8pUSQ0Y8Zu7M57kEazFuHG1kte4gqD8LD7gT54s,8463
135
+ autogen/agentchat/group/group_utils.py,sha256=W3zUghHffO0_seZefB68-U0jIufFDxAkd1NuutuaGmM,27240
136
+ autogen/agentchat/group/handoffs.py,sha256=ergiOsXC4z8N44LTUh-abIPrErjkXZWFRMXflinNq1Y,11743
137
137
  autogen/agentchat/group/llm_condition.py,sha256=wfuEET1VhyVVGedYxcyuhX_Vus6uZHxUl_SPpu4YIsc,2951
138
138
  autogen/agentchat/group/multi_agent_chat.py,sha256=oKAWiziaSZ0otwfGhSWaR26dYbfRQj_vau_P5Z1dvfY,7688
139
139
  autogen/agentchat/group/on_condition.py,sha256=ZxLiI4APceCGUcPFnLrsik7DEX9YgRW200k1QIhyaWg,2185
140
- autogen/agentchat/group/on_context_condition.py,sha256=rH4YlKnbUwUQ84lfEgACS9AQz6PCOYMZv2mQVjDSMUE,2008
140
+ autogen/agentchat/group/on_context_condition.py,sha256=GwB2qb2V7RbaOJPeXYXinuxDQ8ou0kvp7-9jZ85KFfk,2084
141
141
  autogen/agentchat/group/reply_result.py,sha256=KUJ2HWpRLEyc5SIVh60-GirsN7jFg-ceAeT4p7I0ZyQ,740
142
142
  autogen/agentchat/group/speaker_selection_result.py,sha256=2pvl-9zJ1al0AbAmLDqGRm9JgfmS-lyEOFiZoKIkUHY,1623
143
143
  autogen/agentchat/group/patterns/__init__.py,sha256=SUw-biSWow_uGHuHcMA3Pu2cq_CTTVeIqY2J8A5fq8A,446
144
144
  autogen/agentchat/group/patterns/auto.py,sha256=h0LjzGHv3yRqDCAnlOfjofkYNKiVzSKVc64T_o8e7wY,6075
145
145
  autogen/agentchat/group/patterns/manual.py,sha256=8ltqGFtt9xfyADl_OZFD0g-HydFQvDdrc35iwT612ok,6324
146
- autogen/agentchat/group/patterns/pattern.py,sha256=Uz7FgUQq5VGg4k_FqSuLoOcTsuLFNJ96lEvahjfrPVE,10721
146
+ autogen/agentchat/group/patterns/pattern.py,sha256=8DS9lMloLPemY10aIqTnttuRTd50YPN2-UFCj7wjhBk,10868
147
147
  autogen/agentchat/group/patterns/random.py,sha256=yrNCYwcodhdcquNEkdaWO_T32jJjiqaslLithAX1dSM,3367
148
148
  autogen/agentchat/group/patterns/round_robin.py,sha256=nS7nsQJKCq9lD0wyCx__gkWK3N9Z8bvlY2stUfE9JxA,3895
149
149
  autogen/agentchat/group/targets/__init__.py,sha256=AJNSbl9iMe2hiDmZojTp8h889o5OYN3V7f2_2nr8px4,145
@@ -158,7 +158,7 @@ autogen/agentchat/realtime/experimental/function_observer.py,sha256=M0cXXJNoBQ8s
158
158
  autogen/agentchat/realtime/experimental/realtime_agent.py,sha256=i8rxU-Tjk2Pz-WOZJ5PuRymaMvVLH66lqH2LJ85PxLM,5713
159
159
  autogen/agentchat/realtime/experimental/realtime_events.py,sha256=zmRr3pwPJpme5VZEADIz5vg9IZoT3Z1NAc3vt1RdWLk,1083
160
160
  autogen/agentchat/realtime/experimental/realtime_observer.py,sha256=nTouVj5-il0q2_P2LTpyb4pnHqyfwP5MJh_QmMJF3e8,3061
161
- autogen/agentchat/realtime/experimental/realtime_swarm.py,sha256=SRxG5jHGf52IGSXAUITPA9I_V2MqsBm-7ZlYVWbd6Ns,17501
161
+ autogen/agentchat/realtime/experimental/realtime_swarm.py,sha256=ENR7URgzaa4roTTLPAbUr44TT9FznG57kAU_0PIb34s,17809
162
162
  autogen/agentchat/realtime/experimental/websockets.py,sha256=bj9b5eq80L3KlGWPP6nn7uyfT_Z47kQqtIRbQkeE5SI,667
163
163
  autogen/agentchat/realtime/experimental/audio_adapters/__init__.py,sha256=rd0pEy91LYq0JMvIk8Fv7ZKIQLK7oZbVdgVAwNZDCmQ,315
164
164
  autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py,sha256=-O10rpqPKZKxZO58rQOxPnwECe-RQJoSUTU_K8i0A98,6110
@@ -185,7 +185,7 @@ autogen/agents/experimental/discord/discord.py,sha256=S5OkCgXJj2AnkEXZ3Z-pRG3_iD
185
185
  autogen/agents/experimental/document_agent/__init__.py,sha256=YNuO2YqxckrfAxcmRcI5JmiE7w52lkyVdLyvWxmbSUw,603
186
186
  autogen/agents/experimental/document_agent/chroma_query_engine.py,sha256=izKOopdDpmMfoAOCChR3evlLgJZkMh-x4XvsxiO9ol4,13864
187
187
  autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py,sha256=3QBqyZxtQCidxEdwwEHE0WRMgW1Q1nnFZnm9Z3ahwZI,5060
188
- autogen/agents/experimental/document_agent/document_agent.py,sha256=gxgbhTWfZSNHqY8SmJ7XdUxlRN_rT3Kgm7GADySCyaU,21797
188
+ autogen/agents/experimental/document_agent/document_agent.py,sha256=3QVW_Gt9IMFmXKtw9oWzUroa0N_lK9S3Ry4lnMzugkA,29628
189
189
  autogen/agents/experimental/document_agent/document_conditions.py,sha256=yahgDlnG6ORw9RQ6GLLrn_ZczHv9XrLcdouo6M9rSZQ,2051
190
190
  autogen/agents/experimental/document_agent/document_utils.py,sha256=g8PBcOFbVWtqP6rnRHJtY97ZJDXADcPzylkKZnhJfNA,14088
191
191
  autogen/agents/experimental/document_agent/inmemory_query_engine.py,sha256=UFv0u2V0QG3mne9BuQksWggEjGSmO4em4VGkU1Zm2to,8966
@@ -226,7 +226,7 @@ autogen/coding/jupyter/jupyter_client.py,sha256=ROXAWOKG_EJ_oFNuyqUd_3uOBPUTRoTh
226
226
  autogen/coding/jupyter/jupyter_code_executor.py,sha256=Z2vZvou6QzpMBg0IgOzVRoCADswd15mvfkktIjGhUMY,6374
227
227
  autogen/coding/jupyter/local_jupyter_server.py,sha256=7b8yi5qK8ms2e5-PRCrzmXKGp1iC5KgpMU8xiqQ9u8o,6589
228
228
  autogen/events/__init__.py,sha256=XwCA6Rsq9AyjgeecGuiwHcAvDQMmKXgGomw5iLDIU5Q,358
229
- autogen/events/agent_events.py,sha256=jY5WZa4uetm9bp42pMFjpggL_HWNpiJqAG5vAl27bUY,30651
229
+ autogen/events/agent_events.py,sha256=G4SO8DlXyeiBvUVW0z8BuOGpUpcUXjF6mzbDxW9Nn-w,30789
230
230
  autogen/events/base_event.py,sha256=5K1wzDBAio9wLxahErSvE0-UbFfMuSTxBp6EI8SbPGU,3475
231
231
  autogen/events/client_events.py,sha256=2skE5f9BxQmwJv22vNe-s1ReDXE-DsadeAmMWlrmltc,5466
232
232
  autogen/events/helpers.py,sha256=CMcetNzfCE-dWTTJ_9B09of2slRG43yYnHXvFfuGz2Q,1185
@@ -256,7 +256,7 @@ autogen/interop/langchain/__init__.py,sha256=8v-kdg4ImQ1Udzd8Y6r7DTvd760SgWkwNKz
256
256
  autogen/interop/langchain/langchain_chat_model_factory.py,sha256=Jv6Q-SFcaAk9e20fBu92ZZgEEShnUJDqbP5XTZravhE,5591
257
257
  autogen/interop/langchain/langchain_tool.py,sha256=2njJVv17ApNiei-ZJvpZhKFderwQIpmOAxNzx_jQmFM,3132
258
258
  autogen/interop/litellm/__init__.py,sha256=0K9NkQEBXKZI6UVNwD4daTumQL-uhMrAJE33wiSYmkI,237
259
- autogen/interop/litellm/litellm_config_factory.py,sha256=Zfc1UvPDQfccz1bxQGmUDLsS0sj-kCBFilrLjHFjSa0,3995
259
+ autogen/interop/litellm/litellm_config_factory.py,sha256=NiyU0fCCMu5uerirGLu2MR45x_xvAFIVFEJaG5bw4mY,6289
260
260
  autogen/interop/pydantic_ai/__init__.py,sha256=w9tqh96x43Ipq2loD_F-kqwws2RFRs7-98mPxWG-Mjc,238
261
261
  autogen/interop/pydantic_ai/pydantic_ai.py,sha256=ux0V3J37rrT80FCYwkEui3UjsMwUyLd1yfUOidVa4ks,6680
262
262
  autogen/io/__init__.py,sha256=c5iZkM24B9j3K0yPQ0HYJnvAdNMqhlRZVXqcfdnGFX4,600
@@ -275,7 +275,16 @@ autogen/logger/logger_factory.py,sha256=CeLbW3gN0J5zgvQSsRLCSnaiMYusrDWLWovo_Bk-
275
275
  autogen/logger/logger_utils.py,sha256=H9hcsRyEcUcfxTYWf5cRjtNghF4h3FT8sr4IIuqQumY,2053
276
276
  autogen/logger/sqlite_logger.py,sha256=sRwMx42zh85QWLz1BqKyVySI8OwEB_NjM3ObLOW-mcI,18685
277
277
  autogen/mcp/__init__.py,sha256=6BDDmw0sjLZRjyHnd-Gfh9BE-pTKTv5bkow9W6odHtQ,213
278
+ autogen/mcp/__main__.py,sha256=C7nXbWxG3yGsWKRgFnhSsbQOmshLnz6ZOcCxK2TWWio,2487
278
279
  autogen/mcp/mcp_client.py,sha256=7c_lHgBJEs77TFYjLcTlVrEu_0z4EafPPY3PgteY87c,7400
280
+ autogen/mcp/mcp_proxy/__init__.py,sha256=3HTU-TqHLk4XSXeBV1UFd9XkQ1B0yOuXXyGseXvDVec,518
281
+ autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py,sha256=dx-w2tGVMnh8pzY2NuXlMD7oIF7_5Gvc5oSbHIySEpc,2110
282
+ autogen/mcp/mcp_proxy/mcp_proxy.py,sha256=k2_FZyvCtF0h1CxL_VRL0rWMEuzmU42SpB6JCNbk9zc,22112
283
+ autogen/mcp/mcp_proxy/operation_grouping.py,sha256=1n4o5qhkQd2hVr7OaOMsRhInDveDGkCozLudsBVusC4,6349
284
+ autogen/mcp/mcp_proxy/operation_renaming.py,sha256=G5J4VdxUAwSvOo-DsqIUbCfV9TnH3riaHLI6IpctDF8,3956
285
+ autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py,sha256=vBr8P890nsFvK4iuFicrdNskooHlBQeTQ6jbb5kcPAk,3490
286
+ autogen/mcp/mcp_proxy/security.py,sha256=HUcdIE1CCmvuWBPUlvjoKOJV-05sve6pcKHalgm9Z8E,13611
287
+ autogen/mcp/mcp_proxy/security_schema_visitor.py,sha256=UafLMd5zcz0COcc5Vfvt6bP3LQ3jmaBwQIlWhovN9H4,1345
279
288
  autogen/messages/__init__.py,sha256=ZuLvvIQRkNE5fotPe6MSS_YzOUkmfIqGSfOZZOZQ3go,321
280
289
  autogen/messages/agent_messages.py,sha256=ZnRkdWcKS20lW2Njt740m2YNfKanHt8C3k84KKbzR8E,30414
281
290
  autogen/messages/base_message.py,sha256=MbYEXM0dWHl31y7o08PGeJNcpK67hpoQpUMgnZ8qTGE,3808
@@ -285,11 +294,11 @@ autogen/oai/__init__.py,sha256=BIwnV6wtHmKgIM4IUdymfPfpdNqos5P7BfRv-7_QL9A,1680
285
294
  autogen/oai/anthropic.py,sha256=AK_Bbcc5I-PqAvoiwB0LaO1ZLugh_wQNAOIFcj7eTtk,29174
286
295
  autogen/oai/bedrock.py,sha256=8AYWZVsDkJS2HmQ0ggoUqlKV_a4H_ON8rks4VW2Jrxk,25719
287
296
  autogen/oai/cerebras.py,sha256=8hiSBq88l2yTXUJPV7AvGXRCtwvW0Y9hIYUnYK2S2os,12462
288
- autogen/oai/client.py,sha256=oy90ySCTmsAO-4p2VF40IZfHAvZdoI6q5_SIq7aLz5g,64571
297
+ autogen/oai/client.py,sha256=BB_6Heny6_7lq8q7ZAPKohHAK63zs9UGzRoUknTxjYY,65051
289
298
  autogen/oai/client_utils.py,sha256=lVbHyff7OnpdM-tXskC23xLdFccj2AalTdWA4DxzxS4,7543
290
299
  autogen/oai/cohere.py,sha256=pRcQWjbzKbZ1RfC1vk9WGjgndwjHbIaOVoKEYdV2L6c,19421
291
- autogen/oai/gemini.py,sha256=-SgJaRvJ9cv79Ktpv88ZUTySa7M0n4bC_IcqtvXsmr8,41692
292
- autogen/oai/gemini_types.py,sha256=pEJFkDhHx91u5_TMFTV9b8nzho0DD5Pgyf3amBeEnCA,4735
300
+ autogen/oai/gemini.py,sha256=45-MiC-m43KgqLHSBsCw7qUymI3Zic3NUeefZ-HeQtI,42398
301
+ autogen/oai/gemini_types.py,sha256=lIrQGcret7213YR07uFfrw1CnFiZ9VwPyb55KyS0GPI,5864
293
302
  autogen/oai/groq.py,sha256=pQWtaAY_AjT30XKbZNHXDzWsawBys3yFWlfy6K4Nqr8,12431
294
303
  autogen/oai/mistral.py,sha256=SlOYPdnNLHuTEHBGCzsemG9sLEgphdUukRurERdMsvI,12677
295
304
  autogen/oai/ollama.py,sha256=t0fIgDCoIfsQZ3hhpseam5N-fbpI7-fw82bG55mA8nU,29103
@@ -297,7 +306,7 @@ autogen/oai/openai_utils.py,sha256=4kEu50WeTGGG2uh1fOeMxRIZkEoov-YkkTgx2n5DhkM,3
297
306
  autogen/oai/together.py,sha256=Sj4LOk9RrBG3Bb5IVsrjBYz-hDECCyCgofsCdtk6PSM,14867
298
307
  autogen/oai/oai_models/__init__.py,sha256=cILDaaCCvSC3aAX85iLwE1RCpNEokA9925Zse5hX2K4,549
299
308
  autogen/oai/oai_models/_models.py,sha256=jr5nlvk7Be4W7wDVnwyjDL6m2CSj0RY1nOL1W3Kq0xI,478
300
- autogen/oai/oai_models/chat_completion.py,sha256=-swXmkd7jNtOK8jGi84KG-kx1zeYL2roBq0Jco7wKWA,3179
309
+ autogen/oai/oai_models/chat_completion.py,sha256=xs6OH9bWDzN5YQjDRmbJSPr19zySRwJOmyPtJJiNC-M,3188
301
310
  autogen/oai/oai_models/chat_completion_audio.py,sha256=a55i5E1EnT8qWdiKxbwF2kmgt4fih6x6HaChjs0ZuZE,950
302
311
  autogen/oai/oai_models/chat_completion_message.py,sha256=6MbrdgmqoAz0dUuyZZtM4NQd80ljVm3zDpP9_-l5zyw,2808
303
312
  autogen/oai/oai_models/chat_completion_message_tool_call.py,sha256=CWuqlwrk8VMSevpOZAMMPyw9KzNVnxEOfYs9y5tN5zw,1206
@@ -311,7 +320,7 @@ autogen/tools/toolkit.py,sha256=1tOmTGJ96RhkJrrtAViKUyEcwacA6ztoIbYbnf8NgTU,2558
311
320
  autogen/tools/contrib/__init__.py,sha256=DWEjPK6xCR2ihAXXdquQZmiuqRLA3Pqb8QV8W1RtS3k,202
312
321
  autogen/tools/contrib/time/__init__.py,sha256=dplie5aBJZ8VoKy6EKcQMLTtSgcCkNDYzpdsC2I0YWk,195
313
322
  autogen/tools/contrib/time/time.py,sha256=tPi49vOUwfvujbYA-zS00CWcLW-y18CPyQ1gnJG6iRg,1271
314
- autogen/tools/experimental/__init__.py,sha256=3GcjpvEtTvBNPh0VLoWsSwtox2aDeOXABbyuD4PPln8,1249
323
+ autogen/tools/experimental/__init__.py,sha256=G399sJCbL3hV2HSU3eGnrrQ4i3a_P55LobmtcYYUrqU,1466
315
324
  autogen/tools/experimental/browser_use/__init__.py,sha256=kfxCajXcVMDH6CZq-lWh2p8PKxOwT9yjC_Za0jr4zUg,290
316
325
  autogen/tools/experimental/browser_use/browser_use.py,sha256=VEYJwUna_DM_HxeI5kgjhtTUzPBYlwrcGk5UOy85gDo,5426
317
326
  autogen/tools/experimental/crawl4ai/__init__.py,sha256=UjFJLSZ9P5xT6WCV0RDPtwt4MHuwPdK90TU7ByXhLWs,207
@@ -342,12 +351,17 @@ autogen/tools/experimental/messageplatform/telegram/__init__.py,sha256=gPhyMHRvu
342
351
  autogen/tools/experimental/messageplatform/telegram/telegram.py,sha256=i_rSZO8hgWcYrNKuRsgGVeIkIaw737IonPQtk7K5FjE,12332
343
352
  autogen/tools/experimental/perplexity/__init__.py,sha256=VxWG2HfcxwBhLUV4LnAlte9T2dH5dXIy-78gkPVfwSI,232
344
353
  autogen/tools/experimental/perplexity/perplexity_search.py,sha256=UZtyS9Pde3_VXufuZVuiBw87MiOiAWwVyXqstzE7Rlk,9976
354
+ autogen/tools/experimental/reliable/__init__.py,sha256=GLvfvsFLfBANFVcOptIa_Tm71YsHt5U7X5N9quqDZW0,479
355
+ autogen/tools/experimental/reliable/reliable.py,sha256=5s3aD5u-6JJrXqbSQBcW2qxNfyvx3MQ--IcZ6wMdsvE,64687
345
356
  autogen/tools/experimental/tavily/__init__.py,sha256=rvztagn7FpWiXZwJtZmKbIFBteBenaedwsiUViDyC4Y,220
346
357
  autogen/tools/experimental/tavily/tavily_search.py,sha256=S1Aj519kaEIwOAJXTc9Y__GHyY--vvc-P-5nh3ksCOQ,7810
347
358
  autogen/tools/experimental/web_search_preview/__init__.py,sha256=8vd1XWS14883MQ4U4dHvMP8aAKAtMILLnqRJNzgNh6A,233
348
359
  autogen/tools/experimental/web_search_preview/web_search_preview.py,sha256=bLKZSl0670uh82C3OCceRD0WaRfEPtQ4o06PTsQ3kKk,4818
349
360
  autogen/tools/experimental/wikipedia/__init__.py,sha256=jS_gUMyz-uCWr75yKv2esIiGz0ijNDNokt6wovQULLE,274
350
361
  autogen/tools/experimental/wikipedia/wikipedia.py,sha256=Cw7luG34J6if_5D40C_039BTA6l_LvOiEg6FY5UysC4,11545
362
+ templates/main.jinja2,sha256=UWDs5BU-h-L9daFPIy4OAkWFMu2-g5p1R759-yF6Oks,1729
363
+ templates/client_template/main.jinja2,sha256=HLXxq-DAqHyh_8PZ9uk6OVHB0RC6FZqKdIbnJQNJrLU,1978
364
+ templates/config_template/config.jinja2,sha256=A-p-YBsnEm1iftBIhuIBfIyCY-qw34KWcxalmM6KPWc,167
351
365
  autogen/agentchat/contrib/captainagent/tools/README.md,sha256=454O-irP4gjSdYnFgoE0i3BfueXO0qFONxe3GMxMpHg,1677
352
366
  autogen/agentchat/contrib/captainagent/tools/__init__.py,sha256=tOTe4nwbKj7elHpftAy3zS_embMDzncrKL98XKhY6-c,168
353
367
  autogen/agentchat/contrib/captainagent/tools/requirements.txt,sha256=z2uZXzuO-MT_d0EPrk9G3Ct2cQeS-KTj0p7HdgqiEYg,110
@@ -385,8 +399,8 @@ autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py,sha256=
385
399
  autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py,sha256=iqgpFJdyBHPPNCqkehSIbeuV8Rabr2eDMilT23Wx7PI,1687
386
400
  autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py,sha256=-6T5r6Er4mONPldRxv3F9tLoE7Og3qmeSeTC7Du_tTg,596
387
401
  autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py,sha256=Xig7K3A3DRnbv-UXfyo5bybGZUQYAQsltthfTYW5eV8,509
388
- ag2-0.9.1.post0.dist-info/METADATA,sha256=8X27ld0Dx4bVu445ftjyKFBba9qooBmme159PBE1L78,34793
389
- ag2-0.9.1.post0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
390
- ag2-0.9.1.post0.dist-info/licenses/LICENSE,sha256=GEFQVNayAR-S_rQD5l8hPdgvgyktVdy4Bx5-v90IfRI,11384
391
- ag2-0.9.1.post0.dist-info/licenses/NOTICE.md,sha256=07iCPQGbth4pQrgkSgZinJGT5nXddkZ6_MGYcBd2oiY,1134
392
- ag2-0.9.1.post0.dist-info/RECORD,,
402
+ ag2-0.9.3.dist-info/METADATA,sha256=tFxYI45V9ZmkhlvptG5JWYFlC61We-KYQXvQdgWrmiI,35268
403
+ ag2-0.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
404
+ ag2-0.9.3.dist-info/licenses/LICENSE,sha256=GEFQVNayAR-S_rQD5l8hPdgvgyktVdy4Bx5-v90IfRI,11384
405
+ ag2-0.9.3.dist-info/licenses/NOTICE.md,sha256=07iCPQGbth4pQrgkSgZinJGT5nXddkZ6_MGYcBd2oiY,1134
406
+ ag2-0.9.3.dist-info/RECORD,,
@@ -60,15 +60,23 @@ class MessageHistoryLimiter:
60
60
  It trims the conversation history by removing older messages, retaining only the most recent messages.
61
61
  """
62
62
 
63
- def __init__(self, max_messages: Optional[int] = None, keep_first_message: bool = False):
63
+ def __init__(
64
+ self,
65
+ max_messages: Optional[int] = None,
66
+ keep_first_message: bool = False,
67
+ exclude_names: Optional[list[str]] = None,
68
+ ):
64
69
  """Args:
65
70
  max_messages Optional[int]: Maximum number of messages to keep in the context. Must be greater than 0 if not None.
66
71
  keep_first_message bool: Whether to keep the original first message in the conversation history.
67
72
  Defaults to False.
73
+ exclude_names Optional[list[str]]: List of message sender names to exclude from the message history.
74
+ Messages from these senders will be filtered out before applying the message limit. Defaults to None.
68
75
  """
69
76
  self._validate_max_messages(max_messages)
70
77
  self._max_messages = max_messages
71
78
  self._keep_first_message = keep_first_message
79
+ self._exclude_names = exclude_names
72
80
 
73
81
  def apply_transform(self, messages: list[dict[str, Any]]) -> list[dict[str, Any]]:
74
82
  """Truncates the conversation history to the specified maximum number of messages.
@@ -83,25 +91,30 @@ class MessageHistoryLimiter:
83
91
  Returns:
84
92
  List[Dict]: A new list containing the most recent messages up to the specified maximum.
85
93
  """
86
- if self._max_messages is None or len(messages) <= self._max_messages:
87
- return messages
94
+
95
+ exclude_names = getattr(self, "_exclude_names", None)
96
+
97
+ filtered = [msg for msg in messages if msg.get("name") not in exclude_names] if exclude_names else messages
98
+
99
+ if self._max_messages is None or len(filtered) <= self._max_messages:
100
+ return filtered
88
101
 
89
102
  truncated_messages = []
90
103
  remaining_count = self._max_messages
91
104
 
92
105
  # Start with the first message if we need to keep it
93
- if self._keep_first_message:
94
- truncated_messages = [messages[0]]
106
+ if self._keep_first_message and filtered:
107
+ truncated_messages = [filtered[0]]
95
108
  remaining_count -= 1
96
109
 
97
110
  # Loop through messages in reverse
98
- for i in range(len(messages) - 1, 0, -1):
111
+ for i in range(len(filtered) - 1, 0, -1):
99
112
  if remaining_count > 1:
100
- truncated_messages.insert(1 if self._keep_first_message else 0, messages[i])
113
+ truncated_messages.insert(1 if self._keep_first_message else 0, filtered[i])
101
114
  if remaining_count == 1: # noqa: SIM102
102
115
  # If there's only 1 slot left and it's a 'tools' message, ignore it.
103
- if messages[i].get("role") != "tool":
104
- truncated_messages.insert(1, messages[i])
116
+ if filtered[i].get("role") != "tool":
117
+ truncated_messages.insert(1, filtered[i])
105
118
 
106
119
  remaining_count -= 1
107
120
  if remaining_count == 0:
@@ -2321,6 +2321,21 @@ class ConversableAgent(LLMAgent):
2321
2321
 
2322
2322
  return False, None
2323
2323
 
2324
+ def _run_async_in_thread(self, coro):
2325
+ """Run an async coroutine in a separate thread with its own event loop."""
2326
+ result = {}
2327
+
2328
+ def runner():
2329
+ loop = asyncio.new_event_loop()
2330
+ asyncio.set_event_loop(loop)
2331
+ result["value"] = loop.run_until_complete(coro)
2332
+ loop.close()
2333
+
2334
+ t = threading.Thread(target=runner)
2335
+ t.start()
2336
+ t.join()
2337
+ return result["value"]
2338
+
2324
2339
  def generate_function_call_reply(
2325
2340
  self,
2326
2341
  messages: Optional[list[dict[str, Any]]] = None,
@@ -2342,18 +2357,8 @@ class ConversableAgent(LLMAgent):
2342
2357
  func_call = message["function_call"]
2343
2358
  func = self._function_map.get(func_call.get("name", None), None)
2344
2359
  if inspect.iscoroutinefunction(func):
2345
- try:
2346
- # get the running loop if it was already created
2347
- loop = asyncio.get_running_loop()
2348
- close_loop = False
2349
- except RuntimeError:
2350
- # create a loop if there is no running loop
2351
- loop = asyncio.new_event_loop()
2352
- close_loop = True
2353
-
2354
- _, func_return = loop.run_until_complete(self.a_execute_function(func_call, call_id=call_id))
2355
- if close_loop:
2356
- loop.close()
2360
+ coro = self.a_execute_function(func_call, call_id=call_id)
2361
+ _, func_return = self._run_async_in_thread(coro)
2357
2362
  else:
2358
2363
  _, func_return = self.execute_function(message["function_call"], call_id=call_id)
2359
2364
  return True, func_return
@@ -2409,18 +2414,8 @@ class ConversableAgent(LLMAgent):
2409
2414
  tool_call_id = tool_call.get("id", None)
2410
2415
  func = self._function_map.get(function_call.get("name", None), None)
2411
2416
  if inspect.iscoroutinefunction(func):
2412
- try:
2413
- # get the running loop if it was already created
2414
- loop = asyncio.get_running_loop()
2415
- close_loop = False
2416
- except RuntimeError:
2417
- # create a loop if there is no running loop
2418
- loop = asyncio.new_event_loop()
2419
- close_loop = True
2420
-
2421
- _, func_return = loop.run_until_complete(self.a_execute_function(function_call, call_id=tool_call_id))
2422
- if close_loop:
2423
- loop.close()
2417
+ coro = self.a_execute_function(function_call, call_id=tool_call_id)
2418
+ _, func_return = self._run_async_in_thread(coro)
2424
2419
  else:
2425
2420
  _, func_return = self.execute_function(function_call, call_id=tool_call_id)
2426
2421
  content = func_return.get("content", "")
@@ -3130,12 +3125,16 @@ class ConversableAgent(LLMAgent):
3130
3125
  arguments = {}
3131
3126
  content = f"Error: Function {func_name} not found."
3132
3127
 
3133
- if verbose:
3134
- iostream.send(
3135
- ExecutedFunctionEvent(
3136
- func_name=func_name, call_id=call_id, arguments=arguments, content=content, recipient=self
3137
- )
3128
+ iostream.send(
3129
+ ExecutedFunctionEvent(
3130
+ func_name=func_name,
3131
+ call_id=call_id,
3132
+ arguments=arguments,
3133
+ content=content,
3134
+ recipient=self,
3135
+ is_exec_success=is_exec_success,
3138
3136
  )
3137
+ )
3139
3138
 
3140
3139
  return is_exec_success, {
3141
3140
  "name": func_name,
@@ -3198,12 +3197,16 @@ class ConversableAgent(LLMAgent):
3198
3197
  arguments = {}
3199
3198
  content = f"Error: Function {func_name} not found."
3200
3199
 
3201
- if verbose:
3202
- iostream.send(
3203
- ExecutedFunctionEvent(
3204
- func_name=func_name, call_id=call_id, arguments=arguments, content=content, recipient=self
3205
- )
3200
+ iostream.send(
3201
+ ExecutedFunctionEvent(
3202
+ func_name=func_name,
3203
+ call_id=call_id,
3204
+ arguments=arguments,
3205
+ content=content,
3206
+ recipient=self,
3207
+ is_exec_success=is_exec_success,
3206
3208
  )
3209
+ )
3207
3210
 
3208
3211
  return is_exec_success, {
3209
3212
  "name": func_name,
@@ -82,6 +82,46 @@ def link_agents_to_group_manager(agents: list[Agent], group_chat_manager: Agent)
82
82
  agent._group_manager = group_chat_manager # type: ignore[attr-defined]
83
83
 
84
84
 
85
+ def _evaluate_after_works_conditions(
86
+ agent: "ConversableAgent",
87
+ groupchat: GroupChat,
88
+ user_agent: Optional["ConversableAgent"],
89
+ ) -> Optional[Union[Agent, str]]:
90
+ """Evaluate after_works context conditions for an agent.
91
+
92
+ Args:
93
+ agent: The agent to evaluate after_works conditions for
94
+ groupchat: The current group chat
95
+ user_agent: Optional user proxy agent
96
+
97
+ Returns:
98
+ The resolved speaker selection result if a condition matches, None otherwise
99
+ """
100
+ if not hasattr(agent, "handoffs") or not agent.handoffs.after_works: # type: ignore[attr-defined]
101
+ return None
102
+
103
+ for after_work_condition in agent.handoffs.after_works: # type: ignore[attr-defined]
104
+ # Check if condition is available
105
+ is_available = (
106
+ after_work_condition.available.is_available(agent, groupchat.messages)
107
+ if after_work_condition.available
108
+ else True
109
+ )
110
+
111
+ # Evaluate the condition (None condition means always true)
112
+ if is_available and (
113
+ after_work_condition.condition is None or after_work_condition.condition.evaluate(agent.context_variables)
114
+ ):
115
+ # Condition matched, resolve and return
116
+ return after_work_condition.target.resolve(
117
+ groupchat,
118
+ agent,
119
+ user_agent,
120
+ ).get_speaker_selection_result(groupchat)
121
+
122
+ return None
123
+
124
+
85
125
  def _run_oncontextconditions(
86
126
  agent: "ConversableAgent",
87
127
  messages: Optional[list[dict[str, Any]]] = None,
@@ -94,7 +134,9 @@ def _run_oncontextconditions(
94
134
  on_condition.available.is_available(agent, messages if messages else []) if on_condition.available else True
95
135
  )
96
136
 
97
- if is_available and on_condition.condition.evaluate(agent.context_variables):
137
+ if is_available and (
138
+ on_condition.condition is None or on_condition.condition.evaluate(agent.context_variables)
139
+ ):
98
140
  # Condition has been met, we'll set the Tool Executor's next target
99
141
  # attribute and that will be picked up on the next iteration when
100
142
  # _determine_next_agent is called
@@ -161,12 +203,13 @@ def ensure_handoff_agents_in_group(agents: list["ConversableAgent"]) -> None:
161
203
  and context_conditions.target.agent_name not in agent_names
162
204
  ):
163
205
  raise ValueError("Agent in OnContextCondition Hand-offs must be in the agents list")
164
- if (
165
- agent.handoffs.after_work is not None
166
- and isinstance(agent.handoffs.after_work, (AgentTarget, AgentNameTarget))
167
- and agent.handoffs.after_work.agent_name not in agent_names
168
- ):
169
- raise ValueError("Agent in after work target Hand-offs must be in the agents list")
206
+ # Check after_works targets
207
+ for after_work_condition in agent.handoffs.after_works:
208
+ if (
209
+ isinstance(after_work_condition.target, (AgentTarget, AgentNameTarget))
210
+ and after_work_condition.target.agent_name not in agent_names
211
+ ):
212
+ raise ValueError("Agent in after work target Hand-offs must be in the agents list")
170
213
 
171
214
 
172
215
  def prepare_exclude_transit_messages(agents: list["ConversableAgent"]) -> None:
@@ -320,17 +363,19 @@ def setup_context_variables(
320
363
  tool_execution: "ConversableAgent",
321
364
  agents: list["ConversableAgent"],
322
365
  manager: GroupChatManager,
366
+ user_agent: Optional["ConversableAgent"],
323
367
  context_variables: ContextVariables,
324
368
  ) -> None:
325
- """Assign a common context_variables reference to all agents in the group, including the tool executor and group chat manager.
369
+ """Assign a common context_variables reference to all agents in the group, including the tool executor, group chat manager, and user proxy agent.
326
370
 
327
371
  Args:
328
372
  tool_execution: The tool execution agent.
329
373
  agents: List of all agents in the conversation.
330
374
  manager: GroupChatManager instance.
375
+ user_agent: Optional user proxy agent.
331
376
  context_variables: Context variables to assign to all agents.
332
377
  """
333
- for agent in agents + [tool_execution] + [manager]:
378
+ for agent in agents + [tool_execution] + [manager] + ([user_agent] if user_agent else []):
334
379
  agent.context_variables = context_variables
335
380
 
336
381
 
@@ -426,22 +471,25 @@ def determine_next_agent(
426
471
 
427
472
  # If the user last spoke, return to the agent prior to them (if they don't have an after work, otherwise it's treated like any other agent)
428
473
  if user_agent and last_speaker == user_agent:
429
- if user_agent.handoffs.after_work is None:
474
+ if not user_agent.handoffs.after_works:
430
475
  return last_agent_speaker
431
476
  else:
432
477
  last_agent_speaker = user_agent
433
478
 
434
479
  # AFTER WORK:
435
480
 
436
- # Get the appropriate After Work condition (from the agent if they have one, otherwise the group level one)
437
- after_work_condition = (
438
- last_agent_speaker.handoffs.after_work # type: ignore[attr-defined]
439
- if last_agent_speaker.handoffs.after_work is not None # type: ignore[attr-defined]
440
- else group_after_work
481
+ # First, try to evaluate after_works context conditions
482
+ after_works_result = _evaluate_after_works_conditions(
483
+ last_agent_speaker, # type: ignore[arg-type]
484
+ groupchat,
485
+ user_agent,
441
486
  )
487
+ if after_works_result is not None:
488
+ return after_works_result
442
489
 
490
+ # If no after_works conditions matched, use the group-level after_work
443
491
  # Resolve the next agent, termination, or speaker selection method
444
- resolved_speaker_selection_result = after_work_condition.resolve(
492
+ resolved_speaker_selection_result = group_after_work.resolve(
445
493
  groupchat,
446
494
  last_agent_speaker, # type: ignore[arg-type]
447
495
  user_agent,
@@ -525,10 +573,7 @@ def create_group_manager(
525
573
  if (
526
574
  len(agent.handoffs.get_context_conditions_by_target_type(GroupManagerTarget)) > 0
527
575
  or len(agent.handoffs.get_llm_conditions_by_target_type(GroupManagerTarget)) > 0
528
- or (
529
- agent.handoffs.after_work is not None
530
- and isinstance(agent.handoffs.after_work, GroupManagerTarget)
531
- )
576
+ or any(isinstance(aw.target, GroupManagerTarget) for aw in agent.handoffs.after_works)
532
577
  ):
533
578
  has_group_manager_target = True
534
579
  break