ag2 0.10.2__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.
Files changed (423) hide show
  1. ag2-0.10.2.dist-info/METADATA +819 -0
  2. ag2-0.10.2.dist-info/RECORD +423 -0
  3. ag2-0.10.2.dist-info/WHEEL +4 -0
  4. ag2-0.10.2.dist-info/licenses/LICENSE +201 -0
  5. ag2-0.10.2.dist-info/licenses/NOTICE.md +19 -0
  6. autogen/__init__.py +88 -0
  7. autogen/_website/__init__.py +3 -0
  8. autogen/_website/generate_api_references.py +426 -0
  9. autogen/_website/generate_mkdocs.py +1216 -0
  10. autogen/_website/notebook_processor.py +475 -0
  11. autogen/_website/process_notebooks.py +656 -0
  12. autogen/_website/utils.py +413 -0
  13. autogen/a2a/__init__.py +36 -0
  14. autogen/a2a/agent_executor.py +86 -0
  15. autogen/a2a/client.py +357 -0
  16. autogen/a2a/errors.py +18 -0
  17. autogen/a2a/httpx_client_factory.py +79 -0
  18. autogen/a2a/server.py +221 -0
  19. autogen/a2a/utils.py +207 -0
  20. autogen/agentchat/__init__.py +47 -0
  21. autogen/agentchat/agent.py +180 -0
  22. autogen/agentchat/assistant_agent.py +86 -0
  23. autogen/agentchat/chat.py +325 -0
  24. autogen/agentchat/contrib/__init__.py +5 -0
  25. autogen/agentchat/contrib/agent_eval/README.md +7 -0
  26. autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
  27. autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
  28. autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
  29. autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
  30. autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
  31. autogen/agentchat/contrib/agent_eval/task.py +42 -0
  32. autogen/agentchat/contrib/agent_optimizer.py +432 -0
  33. autogen/agentchat/contrib/capabilities/__init__.py +5 -0
  34. autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
  35. autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
  36. autogen/agentchat/contrib/capabilities/teachability.py +393 -0
  37. autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
  38. autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
  39. autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
  40. autogen/agentchat/contrib/capabilities/transforms.py +578 -0
  41. autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
  42. autogen/agentchat/contrib/capabilities/vision_capability.py +215 -0
  43. autogen/agentchat/contrib/captainagent/__init__.py +9 -0
  44. autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
  45. autogen/agentchat/contrib/captainagent/captainagent.py +514 -0
  46. autogen/agentchat/contrib/captainagent/tool_retriever.py +334 -0
  47. autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
  48. autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
  49. autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
  50. autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
  51. autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
  52. autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
  53. autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
  54. autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
  55. autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
  56. autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
  57. autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
  58. autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
  59. autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
  60. autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
  61. autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
  62. autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
  63. autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
  64. autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
  65. autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
  66. autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
  67. autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
  68. autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
  69. autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
  70. autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
  71. autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
  72. autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
  73. autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
  74. autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
  75. autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
  76. autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
  77. autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
  78. autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
  79. autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
  80. autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
  81. autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
  82. autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
  83. autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
  84. autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
  85. autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
  86. autogen/agentchat/contrib/graph_rag/document.py +29 -0
  87. autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +167 -0
  88. autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
  89. autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
  90. autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
  91. autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +263 -0
  92. autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
  93. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
  94. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
  95. autogen/agentchat/contrib/img_utils.py +397 -0
  96. autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
  97. autogen/agentchat/contrib/llava_agent.py +189 -0
  98. autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
  99. autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
  100. autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +325 -0
  101. autogen/agentchat/contrib/rag/__init__.py +10 -0
  102. autogen/agentchat/contrib/rag/chromadb_query_engine.py +268 -0
  103. autogen/agentchat/contrib/rag/llamaindex_query_engine.py +195 -0
  104. autogen/agentchat/contrib/rag/mongodb_query_engine.py +319 -0
  105. autogen/agentchat/contrib/rag/query_engine.py +76 -0
  106. autogen/agentchat/contrib/retrieve_assistant_agent.py +59 -0
  107. autogen/agentchat/contrib/retrieve_user_proxy_agent.py +704 -0
  108. autogen/agentchat/contrib/society_of_mind_agent.py +200 -0
  109. autogen/agentchat/contrib/swarm_agent.py +1404 -0
  110. autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
  111. autogen/agentchat/contrib/vectordb/__init__.py +5 -0
  112. autogen/agentchat/contrib/vectordb/base.py +224 -0
  113. autogen/agentchat/contrib/vectordb/chromadb.py +316 -0
  114. autogen/agentchat/contrib/vectordb/couchbase.py +405 -0
  115. autogen/agentchat/contrib/vectordb/mongodb.py +551 -0
  116. autogen/agentchat/contrib/vectordb/pgvectordb.py +927 -0
  117. autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
  118. autogen/agentchat/contrib/vectordb/utils.py +126 -0
  119. autogen/agentchat/contrib/web_surfer.py +304 -0
  120. autogen/agentchat/conversable_agent.py +4307 -0
  121. autogen/agentchat/group/__init__.py +67 -0
  122. autogen/agentchat/group/available_condition.py +91 -0
  123. autogen/agentchat/group/context_condition.py +77 -0
  124. autogen/agentchat/group/context_expression.py +238 -0
  125. autogen/agentchat/group/context_str.py +39 -0
  126. autogen/agentchat/group/context_variables.py +182 -0
  127. autogen/agentchat/group/events/transition_events.py +111 -0
  128. autogen/agentchat/group/group_tool_executor.py +324 -0
  129. autogen/agentchat/group/group_utils.py +659 -0
  130. autogen/agentchat/group/guardrails.py +179 -0
  131. autogen/agentchat/group/handoffs.py +303 -0
  132. autogen/agentchat/group/llm_condition.py +93 -0
  133. autogen/agentchat/group/multi_agent_chat.py +291 -0
  134. autogen/agentchat/group/on_condition.py +55 -0
  135. autogen/agentchat/group/on_context_condition.py +51 -0
  136. autogen/agentchat/group/patterns/__init__.py +18 -0
  137. autogen/agentchat/group/patterns/auto.py +160 -0
  138. autogen/agentchat/group/patterns/manual.py +177 -0
  139. autogen/agentchat/group/patterns/pattern.py +295 -0
  140. autogen/agentchat/group/patterns/random.py +106 -0
  141. autogen/agentchat/group/patterns/round_robin.py +117 -0
  142. autogen/agentchat/group/reply_result.py +24 -0
  143. autogen/agentchat/group/safeguards/__init__.py +21 -0
  144. autogen/agentchat/group/safeguards/api.py +241 -0
  145. autogen/agentchat/group/safeguards/enforcer.py +1158 -0
  146. autogen/agentchat/group/safeguards/events.py +140 -0
  147. autogen/agentchat/group/safeguards/validator.py +435 -0
  148. autogen/agentchat/group/speaker_selection_result.py +41 -0
  149. autogen/agentchat/group/targets/__init__.py +4 -0
  150. autogen/agentchat/group/targets/function_target.py +245 -0
  151. autogen/agentchat/group/targets/group_chat_target.py +133 -0
  152. autogen/agentchat/group/targets/group_manager_target.py +151 -0
  153. autogen/agentchat/group/targets/transition_target.py +424 -0
  154. autogen/agentchat/group/targets/transition_utils.py +6 -0
  155. autogen/agentchat/groupchat.py +1832 -0
  156. autogen/agentchat/realtime/__init__.py +3 -0
  157. autogen/agentchat/realtime/experimental/__init__.py +20 -0
  158. autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
  159. autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
  160. autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
  161. autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
  162. autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
  163. autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
  164. autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
  165. autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
  166. autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
  167. autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
  168. autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
  169. autogen/agentchat/realtime/experimental/clients/realtime_client.py +191 -0
  170. autogen/agentchat/realtime/experimental/function_observer.py +84 -0
  171. autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
  172. autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
  173. autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
  174. autogen/agentchat/realtime/experimental/realtime_swarm.py +533 -0
  175. autogen/agentchat/realtime/experimental/websockets.py +21 -0
  176. autogen/agentchat/realtime_agent/__init__.py +21 -0
  177. autogen/agentchat/user_proxy_agent.py +114 -0
  178. autogen/agentchat/utils.py +206 -0
  179. autogen/agents/__init__.py +3 -0
  180. autogen/agents/contrib/__init__.py +10 -0
  181. autogen/agents/contrib/time/__init__.py +8 -0
  182. autogen/agents/contrib/time/time_reply_agent.py +74 -0
  183. autogen/agents/contrib/time/time_tool_agent.py +52 -0
  184. autogen/agents/experimental/__init__.py +27 -0
  185. autogen/agents/experimental/deep_research/__init__.py +7 -0
  186. autogen/agents/experimental/deep_research/deep_research.py +52 -0
  187. autogen/agents/experimental/discord/__init__.py +7 -0
  188. autogen/agents/experimental/discord/discord.py +66 -0
  189. autogen/agents/experimental/document_agent/__init__.py +19 -0
  190. autogen/agents/experimental/document_agent/chroma_query_engine.py +301 -0
  191. autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +113 -0
  192. autogen/agents/experimental/document_agent/document_agent.py +643 -0
  193. autogen/agents/experimental/document_agent/document_conditions.py +50 -0
  194. autogen/agents/experimental/document_agent/document_utils.py +376 -0
  195. autogen/agents/experimental/document_agent/inmemory_query_engine.py +214 -0
  196. autogen/agents/experimental/document_agent/parser_utils.py +134 -0
  197. autogen/agents/experimental/document_agent/url_utils.py +417 -0
  198. autogen/agents/experimental/reasoning/__init__.py +7 -0
  199. autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
  200. autogen/agents/experimental/slack/__init__.py +7 -0
  201. autogen/agents/experimental/slack/slack.py +73 -0
  202. autogen/agents/experimental/telegram/__init__.py +7 -0
  203. autogen/agents/experimental/telegram/telegram.py +76 -0
  204. autogen/agents/experimental/websurfer/__init__.py +7 -0
  205. autogen/agents/experimental/websurfer/websurfer.py +70 -0
  206. autogen/agents/experimental/wikipedia/__init__.py +7 -0
  207. autogen/agents/experimental/wikipedia/wikipedia.py +88 -0
  208. autogen/browser_utils.py +309 -0
  209. autogen/cache/__init__.py +10 -0
  210. autogen/cache/abstract_cache_base.py +71 -0
  211. autogen/cache/cache.py +203 -0
  212. autogen/cache/cache_factory.py +88 -0
  213. autogen/cache/cosmos_db_cache.py +144 -0
  214. autogen/cache/disk_cache.py +97 -0
  215. autogen/cache/in_memory_cache.py +54 -0
  216. autogen/cache/redis_cache.py +119 -0
  217. autogen/code_utils.py +598 -0
  218. autogen/coding/__init__.py +30 -0
  219. autogen/coding/base.py +120 -0
  220. autogen/coding/docker_commandline_code_executor.py +283 -0
  221. autogen/coding/factory.py +56 -0
  222. autogen/coding/func_with_reqs.py +203 -0
  223. autogen/coding/jupyter/__init__.py +23 -0
  224. autogen/coding/jupyter/base.py +36 -0
  225. autogen/coding/jupyter/docker_jupyter_server.py +160 -0
  226. autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
  227. autogen/coding/jupyter/import_utils.py +82 -0
  228. autogen/coding/jupyter/jupyter_client.py +224 -0
  229. autogen/coding/jupyter/jupyter_code_executor.py +154 -0
  230. autogen/coding/jupyter/local_jupyter_server.py +164 -0
  231. autogen/coding/local_commandline_code_executor.py +341 -0
  232. autogen/coding/markdown_code_extractor.py +44 -0
  233. autogen/coding/utils.py +55 -0
  234. autogen/coding/yepcode_code_executor.py +197 -0
  235. autogen/doc_utils.py +35 -0
  236. autogen/environments/__init__.py +10 -0
  237. autogen/environments/docker_python_environment.py +365 -0
  238. autogen/environments/python_environment.py +125 -0
  239. autogen/environments/system_python_environment.py +85 -0
  240. autogen/environments/venv_python_environment.py +220 -0
  241. autogen/environments/working_directory.py +74 -0
  242. autogen/events/__init__.py +7 -0
  243. autogen/events/agent_events.py +1016 -0
  244. autogen/events/base_event.py +100 -0
  245. autogen/events/client_events.py +168 -0
  246. autogen/events/helpers.py +44 -0
  247. autogen/events/print_event.py +45 -0
  248. autogen/exception_utils.py +73 -0
  249. autogen/extensions/__init__.py +5 -0
  250. autogen/fast_depends/__init__.py +16 -0
  251. autogen/fast_depends/_compat.py +75 -0
  252. autogen/fast_depends/core/__init__.py +14 -0
  253. autogen/fast_depends/core/build.py +206 -0
  254. autogen/fast_depends/core/model.py +527 -0
  255. autogen/fast_depends/dependencies/__init__.py +15 -0
  256. autogen/fast_depends/dependencies/model.py +30 -0
  257. autogen/fast_depends/dependencies/provider.py +40 -0
  258. autogen/fast_depends/library/__init__.py +10 -0
  259. autogen/fast_depends/library/model.py +46 -0
  260. autogen/fast_depends/py.typed +6 -0
  261. autogen/fast_depends/schema.py +66 -0
  262. autogen/fast_depends/use.py +272 -0
  263. autogen/fast_depends/utils.py +177 -0
  264. autogen/formatting_utils.py +83 -0
  265. autogen/function_utils.py +13 -0
  266. autogen/graph_utils.py +173 -0
  267. autogen/import_utils.py +539 -0
  268. autogen/interop/__init__.py +22 -0
  269. autogen/interop/crewai/__init__.py +7 -0
  270. autogen/interop/crewai/crewai.py +88 -0
  271. autogen/interop/interoperability.py +71 -0
  272. autogen/interop/interoperable.py +46 -0
  273. autogen/interop/langchain/__init__.py +8 -0
  274. autogen/interop/langchain/langchain_chat_model_factory.py +156 -0
  275. autogen/interop/langchain/langchain_tool.py +78 -0
  276. autogen/interop/litellm/__init__.py +7 -0
  277. autogen/interop/litellm/litellm_config_factory.py +178 -0
  278. autogen/interop/pydantic_ai/__init__.py +7 -0
  279. autogen/interop/pydantic_ai/pydantic_ai.py +172 -0
  280. autogen/interop/registry.py +70 -0
  281. autogen/io/__init__.py +15 -0
  282. autogen/io/base.py +151 -0
  283. autogen/io/console.py +56 -0
  284. autogen/io/processors/__init__.py +12 -0
  285. autogen/io/processors/base.py +21 -0
  286. autogen/io/processors/console_event_processor.py +61 -0
  287. autogen/io/run_response.py +294 -0
  288. autogen/io/thread_io_stream.py +63 -0
  289. autogen/io/websockets.py +214 -0
  290. autogen/json_utils.py +42 -0
  291. autogen/llm_clients/MIGRATION_TO_V2.md +782 -0
  292. autogen/llm_clients/__init__.py +77 -0
  293. autogen/llm_clients/client_v2.py +122 -0
  294. autogen/llm_clients/models/__init__.py +55 -0
  295. autogen/llm_clients/models/content_blocks.py +389 -0
  296. autogen/llm_clients/models/unified_message.py +145 -0
  297. autogen/llm_clients/models/unified_response.py +83 -0
  298. autogen/llm_clients/openai_completions_client.py +444 -0
  299. autogen/llm_config/__init__.py +11 -0
  300. autogen/llm_config/client.py +59 -0
  301. autogen/llm_config/config.py +461 -0
  302. autogen/llm_config/entry.py +169 -0
  303. autogen/llm_config/types.py +37 -0
  304. autogen/llm_config/utils.py +223 -0
  305. autogen/logger/__init__.py +11 -0
  306. autogen/logger/base_logger.py +129 -0
  307. autogen/logger/file_logger.py +262 -0
  308. autogen/logger/logger_factory.py +42 -0
  309. autogen/logger/logger_utils.py +57 -0
  310. autogen/logger/sqlite_logger.py +524 -0
  311. autogen/math_utils.py +338 -0
  312. autogen/mcp/__init__.py +7 -0
  313. autogen/mcp/__main__.py +78 -0
  314. autogen/mcp/helpers.py +45 -0
  315. autogen/mcp/mcp_client.py +349 -0
  316. autogen/mcp/mcp_proxy/__init__.py +19 -0
  317. autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +62 -0
  318. autogen/mcp/mcp_proxy/mcp_proxy.py +577 -0
  319. autogen/mcp/mcp_proxy/operation_grouping.py +166 -0
  320. autogen/mcp/mcp_proxy/operation_renaming.py +110 -0
  321. autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
  322. autogen/mcp/mcp_proxy/security.py +399 -0
  323. autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
  324. autogen/messages/__init__.py +7 -0
  325. autogen/messages/agent_messages.py +946 -0
  326. autogen/messages/base_message.py +108 -0
  327. autogen/messages/client_messages.py +172 -0
  328. autogen/messages/print_message.py +48 -0
  329. autogen/oai/__init__.py +61 -0
  330. autogen/oai/anthropic.py +1516 -0
  331. autogen/oai/bedrock.py +800 -0
  332. autogen/oai/cerebras.py +302 -0
  333. autogen/oai/client.py +1658 -0
  334. autogen/oai/client_utils.py +196 -0
  335. autogen/oai/cohere.py +494 -0
  336. autogen/oai/gemini.py +1045 -0
  337. autogen/oai/gemini_types.py +156 -0
  338. autogen/oai/groq.py +319 -0
  339. autogen/oai/mistral.py +311 -0
  340. autogen/oai/oai_models/__init__.py +23 -0
  341. autogen/oai/oai_models/_models.py +16 -0
  342. autogen/oai/oai_models/chat_completion.py +86 -0
  343. autogen/oai/oai_models/chat_completion_audio.py +32 -0
  344. autogen/oai/oai_models/chat_completion_message.py +97 -0
  345. autogen/oai/oai_models/chat_completion_message_tool_call.py +60 -0
  346. autogen/oai/oai_models/chat_completion_token_logprob.py +62 -0
  347. autogen/oai/oai_models/completion_usage.py +59 -0
  348. autogen/oai/ollama.py +657 -0
  349. autogen/oai/openai_responses.py +451 -0
  350. autogen/oai/openai_utils.py +897 -0
  351. autogen/oai/together.py +387 -0
  352. autogen/remote/__init__.py +18 -0
  353. autogen/remote/agent.py +199 -0
  354. autogen/remote/agent_service.py +197 -0
  355. autogen/remote/errors.py +17 -0
  356. autogen/remote/httpx_client_factory.py +131 -0
  357. autogen/remote/protocol.py +37 -0
  358. autogen/remote/retry.py +102 -0
  359. autogen/remote/runtime.py +96 -0
  360. autogen/retrieve_utils.py +490 -0
  361. autogen/runtime_logging.py +161 -0
  362. autogen/testing/__init__.py +12 -0
  363. autogen/testing/messages.py +45 -0
  364. autogen/testing/test_agent.py +111 -0
  365. autogen/token_count_utils.py +280 -0
  366. autogen/tools/__init__.py +20 -0
  367. autogen/tools/contrib/__init__.py +9 -0
  368. autogen/tools/contrib/time/__init__.py +7 -0
  369. autogen/tools/contrib/time/time.py +40 -0
  370. autogen/tools/dependency_injection.py +249 -0
  371. autogen/tools/experimental/__init__.py +54 -0
  372. autogen/tools/experimental/browser_use/__init__.py +7 -0
  373. autogen/tools/experimental/browser_use/browser_use.py +154 -0
  374. autogen/tools/experimental/code_execution/__init__.py +7 -0
  375. autogen/tools/experimental/code_execution/python_code_execution.py +86 -0
  376. autogen/tools/experimental/crawl4ai/__init__.py +7 -0
  377. autogen/tools/experimental/crawl4ai/crawl4ai.py +150 -0
  378. autogen/tools/experimental/deep_research/__init__.py +7 -0
  379. autogen/tools/experimental/deep_research/deep_research.py +329 -0
  380. autogen/tools/experimental/duckduckgo/__init__.py +7 -0
  381. autogen/tools/experimental/duckduckgo/duckduckgo_search.py +103 -0
  382. autogen/tools/experimental/firecrawl/__init__.py +7 -0
  383. autogen/tools/experimental/firecrawl/firecrawl_tool.py +836 -0
  384. autogen/tools/experimental/google/__init__.py +14 -0
  385. autogen/tools/experimental/google/authentication/__init__.py +11 -0
  386. autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
  387. autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
  388. autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
  389. autogen/tools/experimental/google/drive/__init__.py +9 -0
  390. autogen/tools/experimental/google/drive/drive_functions.py +124 -0
  391. autogen/tools/experimental/google/drive/toolkit.py +88 -0
  392. autogen/tools/experimental/google/model.py +17 -0
  393. autogen/tools/experimental/google/toolkit_protocol.py +19 -0
  394. autogen/tools/experimental/google_search/__init__.py +8 -0
  395. autogen/tools/experimental/google_search/google_search.py +93 -0
  396. autogen/tools/experimental/google_search/youtube_search.py +181 -0
  397. autogen/tools/experimental/messageplatform/__init__.py +17 -0
  398. autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
  399. autogen/tools/experimental/messageplatform/discord/discord.py +284 -0
  400. autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
  401. autogen/tools/experimental/messageplatform/slack/slack.py +385 -0
  402. autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
  403. autogen/tools/experimental/messageplatform/telegram/telegram.py +271 -0
  404. autogen/tools/experimental/perplexity/__init__.py +7 -0
  405. autogen/tools/experimental/perplexity/perplexity_search.py +249 -0
  406. autogen/tools/experimental/reliable/__init__.py +10 -0
  407. autogen/tools/experimental/reliable/reliable.py +1311 -0
  408. autogen/tools/experimental/searxng/__init__.py +7 -0
  409. autogen/tools/experimental/searxng/searxng_search.py +142 -0
  410. autogen/tools/experimental/tavily/__init__.py +7 -0
  411. autogen/tools/experimental/tavily/tavily_search.py +176 -0
  412. autogen/tools/experimental/web_search_preview/__init__.py +7 -0
  413. autogen/tools/experimental/web_search_preview/web_search_preview.py +120 -0
  414. autogen/tools/experimental/wikipedia/__init__.py +7 -0
  415. autogen/tools/experimental/wikipedia/wikipedia.py +284 -0
  416. autogen/tools/function_utils.py +412 -0
  417. autogen/tools/tool.py +188 -0
  418. autogen/tools/toolkit.py +86 -0
  419. autogen/types.py +29 -0
  420. autogen/version.py +7 -0
  421. templates/client_template/main.jinja2 +72 -0
  422. templates/config_template/config.jinja2 +7 -0
  423. templates/main.jinja2 +61 -0
@@ -0,0 +1,533 @@
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
+ import logging
6
+ import uuid
7
+ import warnings
8
+ from collections import defaultdict
9
+ from collections.abc import Callable
10
+ from functools import partial
11
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar
12
+
13
+ import anyio
14
+ from anyio import create_task_group, from_thread
15
+
16
+ from autogen.agentchat.group.guardrails import Guardrail, GuardrailResult
17
+
18
+ from ....agentchat.contrib.swarm_agent import AfterWorkOption, initiate_swarm_chat
19
+ from ....cache import AbstractCache
20
+ from ....code_utils import content_str
21
+ from ....doc_utils import export_module
22
+ from ....fast_depends.utils import asyncify
23
+ from ... import Agent, ChatResult, ConversableAgent, LLMAgent
24
+ from ...utils import consolidate_chat_info, gather_usage_summary
25
+
26
+ if TYPE_CHECKING:
27
+ from .clients import Role
28
+ from .realtime_agent import RealtimeAgent
29
+
30
+ __all__ = ["register_swarm"]
31
+
32
+ SWARM_SYSTEM_MESSAGE = (
33
+ "You are a helpful voice assistant. Your task is to listen to user and to coordinate the tasks based on his/her inputs."
34
+ "You can and will communicate using audio output only."
35
+ )
36
+
37
+ QUESTION_ROLE: "Role" = "user"
38
+ QUESTION_MESSAGE = (
39
+ "I have a question/information for myself. DO NOT ANSWER YOURSELF, GET THE ANSWER FROM ME. "
40
+ "repeat the question to me **WITH AUDIO OUTPUT** and AFTER YOU GET THE ANSWER FROM ME call 'answer_task_question' with the answer in first person\n\n"
41
+ "IMPORTANT: repeat just the question, without any additional information or context\n\n"
42
+ "The question is: '{}'\n\n"
43
+ )
44
+ QUESTION_TIMEOUT_SECONDS = 20
45
+
46
+ logger = logging.getLogger(__name__)
47
+
48
+ F = TypeVar("F", bound=Callable[..., Any])
49
+
50
+
51
+ def message_to_dict(message: dict[str, Any] | str) -> dict[str, Any]:
52
+ if isinstance(message, str):
53
+ return {"content": message}
54
+ elif isinstance(message, dict):
55
+ return message
56
+ else:
57
+ return dict(message)
58
+
59
+
60
+ def parse_oai_message(message: dict[str, Any] | str, role: str, adressee: Agent) -> dict[str, Any]:
61
+ """Parse a message into an OpenAI-compatible message format.
62
+
63
+ Args:
64
+ message: The message to parse.
65
+ role: The role associated with the message.
66
+ adressee: The agent that will receive the message.
67
+
68
+ Returns:
69
+ The parsed message in OpenAI-compatible format.
70
+
71
+ Raises:
72
+ ValueError: If the message lacks required fields like 'content', 'function_call', or 'tool_calls'.
73
+ """
74
+ message = message_to_dict(message)
75
+
76
+ # Extract relevant fields while ensuring none are None
77
+ oai_message = {
78
+ key: message[key]
79
+ for key in ("content", "function_call", "tool_calls", "tool_responses", "tool_call_id", "name", "context")
80
+ if key in message and message[key] is not None
81
+ }
82
+
83
+ # Validate or set the content field
84
+ if "content" not in oai_message:
85
+ if "function_call" in oai_message or "tool_calls" in oai_message:
86
+ oai_message["content"] = None
87
+ else:
88
+ raise ValueError("Message must have either 'content', 'function_call', or 'tool_calls' field.")
89
+
90
+ # Determine and assign the role
91
+ if message.get("role") in ["function", "tool"]:
92
+ oai_message["role"] = message["role"]
93
+ # Ensure all tool responses have string content
94
+ for tool_response in oai_message.get("tool_responses", []):
95
+ tool_response["content"] = str(tool_response["content"])
96
+ elif "override_role" in message:
97
+ oai_message["role"] = message["override_role"]
98
+ else:
99
+ oai_message["role"] = role
100
+
101
+ # Enforce specific role requirements for assistant messages
102
+ if oai_message.get("function_call") or oai_message.get("tool_calls"):
103
+ oai_message["role"] = "assistant"
104
+
105
+ # Add a name field if missing
106
+ if "name" not in oai_message:
107
+ oai_message["name"] = adressee.name
108
+
109
+ return oai_message
110
+
111
+
112
+ class SwarmableAgent(Agent):
113
+ """A class for an agent that can participate in a swarm chat."""
114
+
115
+ def __init__(
116
+ self,
117
+ name: str,
118
+ system_message: str = "You are a helpful AI Assistant.",
119
+ is_termination_msg: Callable[..., bool] | None = None,
120
+ description: str | None = None,
121
+ silent: bool | None = None,
122
+ ):
123
+ self._oai_messages: dict[Agent, Any] = defaultdict(list)
124
+
125
+ self._system_message = system_message
126
+ self._description = description if description is not None else system_message
127
+ self._is_termination_msg = (
128
+ is_termination_msg
129
+ if is_termination_msg is not None
130
+ else (lambda x: content_str(x.get("content")) == "TERMINATE")
131
+ )
132
+ self.silent = silent
133
+
134
+ self._name = name
135
+
136
+ # Initialize standalone client cache object.
137
+ self.client_cache = None
138
+ self.previous_cache = None
139
+
140
+ self.reply_at_receive: dict[Agent, bool] = defaultdict(bool)
141
+ self.input_guardrails: list[Guardrail] = []
142
+ self.output_guardrails: list[Guardrail] = []
143
+
144
+ @property
145
+ def system_message(self) -> str:
146
+ return self._system_message
147
+
148
+ def update_system_message(self, system_message: str) -> None:
149
+ """Update this agent's system message.
150
+
151
+ Args:
152
+ system_message (str): system message for inference.
153
+ """
154
+ self._system_message = system_message
155
+
156
+ @property
157
+ def name(self) -> str:
158
+ return self._name
159
+
160
+ @property
161
+ def description(self) -> str:
162
+ return self._description
163
+
164
+ def register_input_guardrail(self, guardrail: Guardrail) -> None:
165
+ self.input_guardrails.append(guardrail)
166
+
167
+ def register_input_guardrails(self, guardrails: list[Guardrail]) -> None:
168
+ self.input_guardrails.extend(guardrails)
169
+
170
+ def register_output_guardrail(self, guardrail: Guardrail) -> None:
171
+ self.output_guardrails.append(guardrail)
172
+
173
+ def register_output_guardrails(self, guardrails: list[Guardrail]) -> None:
174
+ self.output_guardrails.extend(guardrails)
175
+
176
+ def run_input_guardrails(self, messages: list[dict[str, Any]] | None = None) -> GuardrailResult | None:
177
+ for guardrail in self.input_guardrails:
178
+ result = guardrail.check(context=messages)
179
+ if result.activated:
180
+ return result
181
+ return None
182
+
183
+ def run_output_guardrails(self, reply: str | dict[str, Any]) -> GuardrailResult | None:
184
+ for guardrail in self.output_guardrails:
185
+ result = guardrail.check(context=reply)
186
+ if result.activated:
187
+ return result
188
+ return None
189
+
190
+ def send(
191
+ self,
192
+ message: dict[str, Any] | str,
193
+ recipient: Agent,
194
+ request_reply: bool | None = None,
195
+ silent: bool | None = False,
196
+ ) -> None:
197
+ self._oai_messages[recipient].append(parse_oai_message(message, "assistant", recipient))
198
+ recipient.receive(message, self, request_reply)
199
+
200
+ def receive(
201
+ self,
202
+ message: dict[str, Any] | str,
203
+ sender: Agent,
204
+ request_reply: bool | None = None,
205
+ silent: bool | None = False,
206
+ ) -> None:
207
+ self._oai_messages[sender].append(parse_oai_message(message, "user", self))
208
+ if request_reply is False or (request_reply is None and self.reply_at_receive[sender] is False):
209
+ return
210
+ reply = self.generate_reply(messages=self.chat_messages[sender], sender=sender)
211
+ if reply is not None:
212
+ self.send(reply, sender, silent=silent)
213
+
214
+ def generate_reply(
215
+ self,
216
+ messages: list[dict[str, Any]] | None = None,
217
+ sender: Optional["Agent"] = None,
218
+ ) -> str | dict[str, Any] | None:
219
+ if messages is None:
220
+ if sender is None:
221
+ raise ValueError("Either messages or sender must be provided.")
222
+ messages = self._oai_messages[sender]
223
+
224
+ _, reply = self.check_termination_and_human_reply(messages=messages, sender=sender, config=None)
225
+
226
+ return reply
227
+
228
+ def check_termination_and_human_reply(
229
+ self,
230
+ messages: list[dict[str, Any]] | None = None,
231
+ sender: Agent | None = None,
232
+ config: Any | None = None,
233
+ ) -> tuple[bool, str | None]:
234
+ raise NotImplementedError
235
+
236
+ def initiate_chat(
237
+ self,
238
+ recipient: ConversableAgent,
239
+ message: dict[str, Any] | str,
240
+ clear_history: bool = True,
241
+ silent: bool | None = False,
242
+ cache: AbstractCache | None = None,
243
+ summary_args: dict[str, Any] | None = {},
244
+ **kwargs: dict[str, Any],
245
+ ) -> ChatResult:
246
+ chat_id = uuid.uuid4().int
247
+ _chat_info = locals().copy()
248
+ _chat_info["sender"] = self
249
+ consolidate_chat_info(_chat_info, uniform_sender=self)
250
+ recipient._raise_exception_on_async_reply_functions()
251
+ recipient.previous_cache = recipient.client_cache # type: ignore[attr-defined]
252
+ recipient.client_cache = cache # type: ignore[attr-defined, assignment]
253
+
254
+ self._prepare_chat(recipient, clear_history)
255
+ self.send(message, recipient, silent=silent)
256
+ summary = self._last_msg_as_summary(self, recipient, summary_args)
257
+
258
+ recipient.client_cache = recipient.previous_cache # type: ignore[attr-defined]
259
+ recipient.previous_cache = None # type: ignore[attr-defined]
260
+
261
+ chat_result = ChatResult(
262
+ chat_id=chat_id,
263
+ chat_history=self.chat_messages[recipient],
264
+ summary=summary,
265
+ cost=gather_usage_summary([self, recipient]), # type: ignore[arg-type]
266
+ human_input=[],
267
+ )
268
+ return chat_result
269
+
270
+ async def a_generate_reply(
271
+ self,
272
+ messages: list[dict[str, Any]] | None = None,
273
+ sender: Optional["Agent"] = None,
274
+ ) -> str | dict[str, Any] | None:
275
+ return self.generate_reply(messages=messages, sender=sender)
276
+
277
+ async def a_receive(
278
+ self,
279
+ message: dict[str, Any] | str,
280
+ sender: "Agent",
281
+ request_reply: bool | None = None,
282
+ ) -> None:
283
+ self.receive(message, sender, request_reply)
284
+
285
+ async def a_send(
286
+ self,
287
+ message: dict[str, Any] | str,
288
+ recipient: "Agent",
289
+ request_reply: bool | None = None,
290
+ ) -> None:
291
+ self.send(message, recipient, request_reply)
292
+
293
+ @property
294
+ def chat_messages(self) -> dict[Agent, list[dict[str, Any]]]:
295
+ """A dictionary of conversations from agent to list of messages."""
296
+ return self._oai_messages
297
+
298
+ def last_message(self, agent: Agent | None = None) -> dict[str, Any] | None:
299
+ if agent is None:
300
+ n_conversations = len(self._oai_messages)
301
+ if n_conversations == 0:
302
+ return None
303
+ if n_conversations == 1:
304
+ for conversation in self._oai_messages.values():
305
+ return conversation[-1] # type: ignore[no-any-return]
306
+ raise ValueError("More than one conversation is found. Please specify the sender to get the last message.")
307
+ if agent not in self._oai_messages():
308
+ raise KeyError(
309
+ f"The agent '{agent.name}' is not present in any conversation. No history available for this agent."
310
+ )
311
+ return self._oai_messages[agent][-1] # type: ignore[no-any-return]
312
+
313
+ def _prepare_chat(
314
+ self,
315
+ recipient: ConversableAgent,
316
+ clear_history: bool,
317
+ prepare_recipient: bool = True,
318
+ reply_at_receive: bool = True,
319
+ ) -> None:
320
+ self.reply_at_receive[recipient] = reply_at_receive
321
+ if clear_history:
322
+ self._oai_messages[recipient].clear()
323
+ if prepare_recipient:
324
+ recipient._prepare_chat(self, clear_history, False, reply_at_receive) # type: ignore[arg-type]
325
+
326
+ def _raise_exception_on_async_reply_functions(self) -> None:
327
+ pass
328
+
329
+ def set_ui_tools(self, tools: list | None = None) -> None:
330
+ """Set UI tools for the agent."""
331
+ pass
332
+
333
+ def unset_ui_tools(self) -> None:
334
+ """Unset UI tools for the agent."""
335
+ pass
336
+
337
+ @staticmethod
338
+ def _last_msg_as_summary(sender: Agent, recipient: Agent, summary_args: dict[str, Any] | None) -> str:
339
+ """Get a chat summary from the last message of the recipient."""
340
+ summary = ""
341
+ try:
342
+ content = recipient.last_message(sender)["content"] # type: ignore[attr-defined]
343
+ if isinstance(content, str):
344
+ summary = content.replace("TERMINATE", "")
345
+ elif isinstance(content, list):
346
+ summary = "\n".join(
347
+ x["text"].replace("TERMINATE", "") for x in content if isinstance(x, dict) and "text" in x
348
+ )
349
+ except (IndexError, AttributeError) as e:
350
+ warnings.warn(f"Cannot extract summary using last_msg: {e}. Using an empty str as summary.", UserWarning)
351
+ return summary
352
+
353
+
354
+ # check that the SwarmableAgent class is implementing LLMAgent protocol
355
+ if TYPE_CHECKING:
356
+
357
+ def _create_swarmable_agent(
358
+ name: str,
359
+ system_message: str,
360
+ is_termination_msg: Callable[..., bool] | None,
361
+ description: str | None,
362
+ silent: bool | None,
363
+ ) -> LLMAgent:
364
+ return SwarmableAgent(
365
+ name=name,
366
+ system_message=system_message,
367
+ is_termination_msg=is_termination_msg,
368
+ description=description,
369
+ silent=silent,
370
+ )
371
+
372
+
373
+ class SwarmableRealtimeAgent(SwarmableAgent):
374
+ def __init__(
375
+ self,
376
+ realtime_agent: "RealtimeAgent",
377
+ initial_agent: ConversableAgent,
378
+ agents: list[ConversableAgent],
379
+ question_message: str | None = None,
380
+ ) -> None:
381
+ self._initial_agent = initial_agent
382
+ self._agents = agents
383
+ self._realtime_agent = realtime_agent
384
+
385
+ self._answer_event = anyio.Event()
386
+ self._answer: str = ""
387
+ self.question_message = question_message or QUESTION_MESSAGE
388
+
389
+ super().__init__(
390
+ name=realtime_agent._name,
391
+ is_termination_msg=None,
392
+ description=None,
393
+ silent=None,
394
+ )
395
+ self.input_guardrails = []
396
+ self.output_guardrails = []
397
+
398
+ def reset_answer(self) -> None:
399
+ """Reset the answer event."""
400
+ self._answer_event = anyio.Event()
401
+
402
+ def set_answer(self, answer: str) -> str:
403
+ """Set the answer to the question."""
404
+ self._answer = answer
405
+ self._answer_event.set()
406
+ return "Answer set successfully."
407
+
408
+ async def get_answer(self) -> str:
409
+ """Get the answer to the question."""
410
+ await self._answer_event.wait()
411
+ return self._answer
412
+
413
+ async def ask_question(self, question: str, question_timeout: int) -> None:
414
+ """Send a question for the user to the agent and wait for the answer.
415
+ If the answer is not received within the timeout, the question is repeated.
416
+
417
+ Args:
418
+ question: The question to ask the user.
419
+ question_timeout: The time in seconds to wait for the answer.
420
+ """
421
+ self.reset_answer()
422
+ realtime_client = self._realtime_agent._realtime_client
423
+ await realtime_client.send_text(role=QUESTION_ROLE, text=question)
424
+
425
+ async def _check_event_set(timeout: int = question_timeout) -> bool:
426
+ for _ in range(timeout):
427
+ if self._answer_event.is_set():
428
+ return True
429
+ await anyio.sleep(1)
430
+ return False
431
+
432
+ while not await _check_event_set():
433
+ await realtime_client.send_text(role=QUESTION_ROLE, text=question)
434
+
435
+ def check_termination_and_human_reply(
436
+ self,
437
+ messages: list[dict[str, Any]] | None = None,
438
+ sender: Agent | None = None,
439
+ config: Any | None = None,
440
+ ) -> tuple[bool, str | None]:
441
+ """Check if the conversation should be terminated and if the agent should reply.
442
+
443
+ Called when its agents turn in the chat conversation.
444
+
445
+ Args:
446
+ messages (list[dict[str, Any]]): The messages in the conversation.
447
+ sender (Agent): The agent that sent the message.
448
+ config (Optional[Any]): The configuration for the agent.
449
+ """
450
+ if not messages:
451
+ return False, None
452
+
453
+ async def get_input() -> None:
454
+ async with create_task_group() as tg:
455
+ tg.start_soon(
456
+ self.ask_question,
457
+ self.question_message.format(messages[-1]["content"]),
458
+ question_timeout=QUESTION_TIMEOUT_SECONDS,
459
+ )
460
+
461
+ from_thread.run_sync(get_input)
462
+
463
+ return True, {"role": "user", "content": self._answer} # type: ignore[return-value]
464
+
465
+ def start_chat(self) -> None:
466
+ raise NotImplementedError
467
+
468
+ def configure_realtime_agent(self, system_message: str | None) -> None:
469
+ realtime_agent = self._realtime_agent
470
+
471
+ logger = realtime_agent.logger
472
+ if not system_message:
473
+ if realtime_agent.system_message != "You are a helpful AI Assistant.":
474
+ logger.warning(
475
+ "Overriding system message set up in `__init__`, please use `system_message` parameter of the `register_swarm` function instead."
476
+ )
477
+ system_message = SWARM_SYSTEM_MESSAGE
478
+
479
+ realtime_agent._system_message = system_message
480
+
481
+ realtime_agent.register_realtime_function(
482
+ name="answer_task_question", description="Answer question from the task"
483
+ )(self.set_answer)
484
+
485
+ registered_tool_names = set()
486
+ all_agents = [self._initial_agent] + self._agents
487
+
488
+ for agent in all_agents:
489
+ for tool in agent.tools:
490
+ if tool.name not in registered_tool_names:
491
+ realtime_agent.register_realtime_function(name=tool.name, description=tool.description)(tool.func)
492
+ registered_tool_names.add(tool.name)
493
+
494
+ async def on_observers_ready() -> None:
495
+ self._realtime_agent._tg.start_soon(
496
+ asyncify(
497
+ partial(
498
+ initiate_swarm_chat,
499
+ initial_agent=self._initial_agent,
500
+ agents=self._agents,
501
+ user_agent=self, # type: ignore[arg-type]
502
+ messages="Find out what the user wants.",
503
+ after_work=AfterWorkOption.REVERT_TO_USER,
504
+ )
505
+ )
506
+ )
507
+
508
+ self._realtime_agent.callbacks.on_observers_ready = on_observers_ready
509
+
510
+
511
+ @export_module("autogen.agentchat.realtime.experimental")
512
+ def register_swarm(
513
+ *,
514
+ realtime_agent: "RealtimeAgent",
515
+ initial_agent: ConversableAgent,
516
+ agents: list[ConversableAgent],
517
+ system_message: str | None = None,
518
+ question_message: str | None = None,
519
+ ) -> None:
520
+ """Create a SwarmableRealtimeAgent.
521
+
522
+ Args:
523
+ realtime_agent (RealtimeAgent): The RealtimeAgent to create the SwarmableRealtimeAgent from.
524
+ initial_agent (ConversableAgent): The initial agent.
525
+ agents (list[ConversableAgent]): The agents in the swarm.
526
+ system_message (Optional[str]): The system message to set for the agent. If None, the default system message is used.
527
+ question_message (Optional[str]): The question message to set for the agent. If None, the default QUESTION_MESSAGE is used.
528
+ """
529
+ swarmable_agent = SwarmableRealtimeAgent(
530
+ realtime_agent=realtime_agent, initial_agent=initial_agent, agents=agents, question_message=question_message
531
+ )
532
+
533
+ swarmable_agent.configure_realtime_agent(system_message=system_message)
@@ -0,0 +1,21 @@
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 collections.abc import AsyncIterator
6
+ from typing import Any, Protocol, runtime_checkable
7
+
8
+ __all__ = ["WebSocketProtocol"]
9
+
10
+
11
+ @runtime_checkable
12
+ class WebSocketProtocol(Protocol):
13
+ """WebSocket protocol for sending and receiving JSON data modelled after FastAPI's WebSocket."""
14
+
15
+ async def send_json(self, data: Any, mode: str = "text") -> None: ...
16
+
17
+ async def receive_json(self, mode: str = "text") -> Any: ...
18
+
19
+ async def receive_text(self) -> str: ...
20
+
21
+ def iter_text(self) -> AsyncIterator[str]: ...
@@ -0,0 +1,21 @@
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 ..realtime.experimental import (
6
+ FunctionObserver,
7
+ RealtimeAgent,
8
+ RealtimeObserver,
9
+ TwilioAudioAdapter,
10
+ WebSocketAudioAdapter,
11
+ register_swarm,
12
+ )
13
+
14
+ __all__ = [
15
+ "FunctionObserver",
16
+ "RealtimeAgent",
17
+ "RealtimeObserver",
18
+ "TwilioAudioAdapter",
19
+ "WebSocketAudioAdapter",
20
+ "register_swarm",
21
+ ]
@@ -0,0 +1,114 @@
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
+ # Portions derived from https://github.com/microsoft/autogen are under the MIT License.
6
+ # SPDX-License-Identifier: MIT
7
+ from collections.abc import Callable
8
+ from typing import Any, Literal
9
+
10
+ from ..doc_utils import export_module
11
+ from ..llm_config import LLMConfig
12
+ from ..runtime_logging import log_new_agent, logging_enabled
13
+ from .conversable_agent import ConversableAgent
14
+
15
+
16
+ @export_module("autogen")
17
+ class UserProxyAgent(ConversableAgent):
18
+ """(In preview) A proxy agent for the user, that can execute code and provide feedback to the other agents.\n
19
+ \n
20
+ UserProxyAgent is a subclass of ConversableAgent configured with `human_input_mode` to ALWAYS\n
21
+ and `llm_config` to False. By default, the agent will prompt for human input every time a message is received.\n
22
+ Code execution is enabled by default. LLM-based auto reply is disabled by default.\n
23
+ To modify auto reply, register a method with [`register_reply`](../ConversableAgent#register-reply).\n
24
+ To modify the way to get human input, override `get_human_input` method.\n
25
+ To modify the way to execute code blocks, single code block, or function call, override `execute_code_blocks`,\n
26
+ `run_code`, and `execute_function` methods respectively.\n
27
+ """
28
+
29
+ # Default UserProxyAgent.description values, based on human_input_mode
30
+ DEFAULT_USER_PROXY_AGENT_DESCRIPTIONS = {
31
+ "ALWAYS": "An attentive HUMAN user who can answer questions about the task, and can perform tasks such as running Python code or inputting command line commands at a Linux terminal and reporting back the execution results.",
32
+ "TERMINATE": "A user that can run Python code or input command line commands at a Linux terminal and report back the execution results.",
33
+ "NEVER": "A computer terminal that performs no other action than running Python scripts (provided to it quoted in ```python code blocks), or sh shell scripts (provided to it quoted in ```sh code blocks).",
34
+ }
35
+
36
+ def __init__(
37
+ self,
38
+ name: str,
39
+ is_termination_msg: Callable[[dict[str, Any]], bool] | None = None,
40
+ max_consecutive_auto_reply: int | None = None,
41
+ human_input_mode: Literal["ALWAYS", "TERMINATE", "NEVER"] = "ALWAYS",
42
+ function_map: dict[str, Callable[..., Any]] | None = None,
43
+ code_execution_config: dict[str, Any] | Literal[False] = {},
44
+ default_auto_reply: str | dict[str, Any] | None = "",
45
+ llm_config: LLMConfig | dict[str, Any] | Literal[False] | None = False,
46
+ system_message: str | list[str] | None = "",
47
+ description: str | None = None,
48
+ **kwargs: Any,
49
+ ):
50
+ """Initialize a UserProxyAgent.
51
+
52
+ Args:
53
+ name (str): name of the agent.\n
54
+ is_termination_msg (function): a function that takes a message in the form of a dictionary\n
55
+ and returns a boolean value indicating if this received message is a termination message.\n
56
+ The dict can contain the following keys: "content", "role", "name", "function_call".\n
57
+ max_consecutive_auto_reply (int): the maximum number of consecutive auto replies.\n
58
+ default to None (no limit provided, class attribute MAX_CONSECUTIVE_AUTO_REPLY will be used as the limit in this case).\n
59
+ The limit only plays a role when human_input_mode is not "ALWAYS".\n
60
+ human_input_mode (str): whether to ask for human inputs every time a message is received.\n
61
+ Possible values are "ALWAYS", "TERMINATE", "NEVER".\n
62
+ (1) When "ALWAYS", the agent prompts for human input every time a message is received.\n
63
+ Under this mode, the conversation stops when the human input is "exit",\n
64
+ or when is_termination_msg is True and there is no human input.\n
65
+ (2) When "TERMINATE", the agent only prompts for human input only when a termination message is received or\n
66
+ the number of auto reply reaches the max_consecutive_auto_reply.\n
67
+ (3) When "NEVER", the agent will never prompt for human input. Under this mode, the conversation stops\n
68
+ when the number of auto reply reaches the max_consecutive_auto_reply or when is_termination_msg is True.\n
69
+ function_map (dict[str, callable]): Mapping function names (passed to openai) to callable functions.\n
70
+ code_execution_config (dict or False): config for the code execution.\n
71
+ To disable code execution, set to False. Otherwise, set to a dictionary with the following keys:\n
72
+ - work_dir (Optional, str): The working directory for the code execution.\n
73
+ If None, a default working directory will be used.\n
74
+ The default working directory is the "extensions" directory under\n
75
+ "path_to_autogen".\n
76
+ - use_docker (Optional, list, str or bool): The docker image to use for code execution.\n
77
+ Default is True, which means the code will be executed in a docker container. A default list of images will be used.\n
78
+ If a list or a str of image name(s) is provided, the code will be executed in a docker container\n
79
+ with the first image successfully pulled.\n
80
+ If False, the code will be executed in the current environment.\n
81
+ We strongly recommend using docker for code execution.\n
82
+ - timeout (Optional, int): The maximum execution time in seconds.\n
83
+ - last_n_messages (Experimental, Optional, int): The number of messages to look back for code execution. Default to 1.\n
84
+ default_auto_reply (str or dict or None): the default auto reply message when no code execution or llm based reply is generated.\n
85
+ llm_config (LLMConfig or dict or False or None): llm inference configuration.\n
86
+ Please refer to [OpenAIWrapper.create](https://docs.ag2.ai/latest/docs/api-reference/autogen/OpenAIWrapper/#autogen.OpenAIWrapper.create)\n
87
+ for available options.\n
88
+ Default to False, which disables llm-based auto reply.\n
89
+ When set to None, will use self.DEFAULT_CONFIG, which defaults to False.\n
90
+ system_message (str or List): system message for ChatCompletion inference.\n
91
+ Only used when llm_config is not False. Use it to reprogram the agent.\n
92
+ description (str): a short description of the agent. This description is used by other agents\n
93
+ (e.g. the GroupChatManager) to decide when to call upon this agent. (Default: system_message)\n
94
+ **kwargs (dict): Please refer to other kwargs in\n
95
+ [ConversableAgent](https://docs.ag2.ai/latest/docs/api-reference/autogen/ConversableAgent).\n
96
+ """
97
+ super().__init__(
98
+ name=name,
99
+ system_message=system_message,
100
+ is_termination_msg=is_termination_msg,
101
+ max_consecutive_auto_reply=max_consecutive_auto_reply,
102
+ human_input_mode=human_input_mode,
103
+ function_map=function_map,
104
+ code_execution_config=code_execution_config,
105
+ llm_config=llm_config,
106
+ default_auto_reply=default_auto_reply,
107
+ description=(
108
+ description if description is not None else self.DEFAULT_USER_PROXY_AGENT_DESCRIPTIONS[human_input_mode]
109
+ ),
110
+ **kwargs,
111
+ )
112
+
113
+ if logging_enabled():
114
+ log_new_agent(self, locals())