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,67 @@
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
+ __all__: list[str] = []
6
+
7
+ from .available_condition import ExpressionAvailableCondition, StringAvailableCondition
8
+ from .context_condition import ExpressionContextCondition, StringContextCondition
9
+ from .context_expression import ContextExpression
10
+ from .context_str import ContextStr
11
+ from .context_variables import ContextVariables
12
+ from .handoffs import Handoffs
13
+ from .llm_condition import ContextStrLLMCondition, StringLLMCondition
14
+ from .on_condition import OnCondition
15
+ from .on_context_condition import OnContextCondition
16
+ from .reply_result import ReplyResult
17
+ from .speaker_selection_result import SpeakerSelectionResult
18
+ from .targets.group_chat_target import GroupChatConfig, GroupChatTarget
19
+
20
+ """
21
+ from .targets.group_manager_target import (
22
+ GroupManagerSelectionMessageContextStr,
23
+ GroupManagerSelectionMessageString,
24
+ GroupManagerTarget,
25
+ )
26
+ """
27
+ from .targets.function_target import FunctionTarget, FunctionTargetResult
28
+ from .targets.transition_target import (
29
+ AgentNameTarget,
30
+ AgentTarget,
31
+ AskUserTarget,
32
+ NestedChatTarget,
33
+ RevertToUserTarget,
34
+ StayTarget,
35
+ TerminateTarget,
36
+ )
37
+
38
+ __all__ = [
39
+ "AgentNameTarget",
40
+ "AgentTarget",
41
+ "AskUserTarget",
42
+ "ContextExpression",
43
+ "ContextStr",
44
+ "ContextStrLLMCondition",
45
+ "ContextVariables",
46
+ "ExpressionAvailableCondition",
47
+ "ExpressionContextCondition",
48
+ "FunctionTarget",
49
+ "FunctionTargetResult",
50
+ "GroupChatConfig",
51
+ "GroupChatTarget",
52
+ # "GroupManagerSelectionMessageContextStr",
53
+ # "GroupManagerSelectionMessageString",
54
+ # "GroupManagerTarget",
55
+ "Handoffs",
56
+ "NestedChatTarget",
57
+ "OnCondition",
58
+ "OnContextCondition",
59
+ "ReplyResult",
60
+ "RevertToUserTarget",
61
+ "SpeakerSelectionResult",
62
+ "StayTarget",
63
+ "StringAvailableCondition",
64
+ "StringContextCondition",
65
+ "StringLLMCondition",
66
+ "TerminateTarget",
67
+ ]
@@ -0,0 +1,91 @@
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 typing import TYPE_CHECKING, Any
6
+
7
+ from pydantic import BaseModel
8
+
9
+ from .context_expression import ContextExpression
10
+
11
+ if TYPE_CHECKING:
12
+ # Avoid circular import
13
+ from ..conversable_agent import ConversableAgent
14
+
15
+ __all__ = ["AvailableCondition", "ExpressionAvailableCondition", "StringAvailableCondition"]
16
+
17
+
18
+ class AvailableCondition(BaseModel):
19
+ """Protocol for determining if a condition is available to be evaluated."""
20
+
21
+ def is_available(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> bool:
22
+ """Determine if the condition should be considered for evaluation.
23
+
24
+ Args:
25
+ agent: The agent evaluating the condition
26
+ messages: The conversation history
27
+
28
+ Returns:
29
+ True if the condition should be evaluated, False otherwise
30
+ """
31
+ raise NotImplementedError("Requires subclasses to implement.")
32
+
33
+
34
+ class StringAvailableCondition(AvailableCondition):
35
+ """String-based available condition.
36
+
37
+ This condition checks if a named context variable exists and is truthy.
38
+ """
39
+
40
+ context_variable: str
41
+
42
+ def __init__(self, context_variable: str, **data: Any) -> None:
43
+ """Initialize with a context variable name as a positional parameter.
44
+
45
+ Args:
46
+ context_variable: The name of the context variable to check
47
+ data: Additional data for the parent class
48
+ """
49
+ super().__init__(context_variable=context_variable, **data)
50
+
51
+ def is_available(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> bool:
52
+ """Check if the named context variable is truthy.
53
+
54
+ Args:
55
+ agent: The agent with context variables
56
+ messages: The conversation history (not used)
57
+
58
+ Returns:
59
+ True if the variable exists and is truthy, False otherwise
60
+ """
61
+ return bool(agent.context_variables.get(self.context_variable, False))
62
+
63
+
64
+ class ExpressionAvailableCondition(AvailableCondition):
65
+ """Expression-based available condition.
66
+
67
+ This condition evaluates a ContextExpression against the context variables.
68
+ """
69
+
70
+ expression: ContextExpression
71
+
72
+ def __init__(self, expression: ContextExpression, **data: Any) -> None:
73
+ """Initialize with an expression as a positional parameter.
74
+
75
+ Args:
76
+ expression: The context expression to evaluate
77
+ data: Additional data for the parent class
78
+ """
79
+ super().__init__(expression=expression, **data)
80
+
81
+ def is_available(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> bool:
82
+ """Evaluate the expression against the context variables.
83
+
84
+ Args:
85
+ agent: The agent with context variables
86
+ messages: The conversation history (not used)
87
+
88
+ Returns:
89
+ Boolean result of the expression evaluation
90
+ """
91
+ return self.expression.evaluate(agent.context_variables)
@@ -0,0 +1,77 @@
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
+
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel
9
+
10
+ from .context_expression import ContextExpression
11
+ from .context_variables import ContextVariables
12
+
13
+ __all__ = ["ContextCondition", "ExpressionContextCondition", "StringContextCondition"]
14
+
15
+
16
+ class ContextCondition(BaseModel):
17
+ """Protocol for conditions evaluated directly using context variables."""
18
+
19
+ def evaluate(self, context_variables: ContextVariables) -> bool:
20
+ """Evaluate the condition to a boolean result.
21
+
22
+ Args:
23
+ context_variables: The context variables to evaluate against
24
+
25
+ Returns:
26
+ Boolean result of the condition evaluation
27
+ """
28
+ raise NotImplementedError("Requires subclasses to implement.")
29
+
30
+
31
+ class StringContextCondition(ContextCondition):
32
+ """Simple string-based context condition.
33
+
34
+ This condition checks if a named context variable exists and is truthy.
35
+ """
36
+
37
+ variable_name: str
38
+
39
+ def evaluate(self, context_variables: ContextVariables) -> bool:
40
+ """Check if the named context variable is truthy.
41
+
42
+ Args:
43
+ context_variables: The context variables to check against
44
+
45
+ Returns:
46
+ True if the variable exists and is truthy, False otherwise
47
+ """
48
+ return bool(context_variables.get(self.variable_name, False))
49
+
50
+
51
+ class ExpressionContextCondition(ContextCondition):
52
+ """Complex expression-based context condition.
53
+
54
+ This condition evaluates a ContextExpression against the context variables.
55
+ """
56
+
57
+ expression: ContextExpression
58
+
59
+ def __init__(self, expression: ContextExpression, **data: Any) -> None:
60
+ """Initialize with an expression as a positional parameter.
61
+
62
+ Args:
63
+ expression: The context expression to evaluate
64
+ data: Additional data for the parent class
65
+ """
66
+ super().__init__(expression=expression, **data)
67
+
68
+ def evaluate(self, context_variables: ContextVariables) -> bool:
69
+ """Evaluate the expression against the context variables.
70
+
71
+ Args:
72
+ context_variables: The context variables to evaluate against
73
+
74
+ Returns:
75
+ Boolean result of the expression evaluation
76
+ """
77
+ return self.expression.evaluate(context_variables)
@@ -0,0 +1,238 @@
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 ast
6
+ import re
7
+ from dataclasses import dataclass
8
+
9
+ from ...doc_utils import export_module
10
+ from .context_variables import ContextVariables
11
+
12
+
13
+ @dataclass
14
+ @export_module("autogen")
15
+ class ContextExpression:
16
+ """A class to evaluate logical expressions using context variables.\n
17
+ \n
18
+ Args:\n
19
+ expression (str): A string containing a logical expression with context variable references.\n
20
+ - Variable references use ${var_name} syntax: ${logged_in}, ${attempts}\n
21
+ - String literals can use normal quotes: 'hello', "world"\n
22
+ - Supported operators:\n
23
+ - Logical: not/!, and/&, or/|\n
24
+ - Comparison: >, <, >=, <=, ==, !=\n
25
+ - Supported functions:\n
26
+ - len(${var_name}): Gets the length of a list, string, or other collection\n
27
+ - Parentheses can be used for grouping\n
28
+ - Examples:\n
29
+ - "not ${logged_in} and ${is_admin} or ${guest_checkout}"\n
30
+ - "!${logged_in} & ${is_admin} | ${guest_checkout}"\n
31
+ - "len(${orders}) > 0 & ${user_active}"\n
32
+ - "len(${cart_items}) == 0 | ${checkout_started}"\n
33
+ \n
34
+ Raises:\n
35
+ SyntaxError: If the expression cannot be parsed\n
36
+ ValueError: If the expression contains disallowed operations\n
37
+ """
38
+
39
+ expression: str
40
+
41
+ def __post_init__(self) -> None:
42
+ # Validate the expression immediately upon creation
43
+ try:
44
+ # Extract variable references and replace with placeholders
45
+ self._variable_names = self._extract_variable_names(self.expression)
46
+
47
+ # Convert symbolic operators to Python keywords
48
+ python_expr = self._convert_to_python_syntax(self.expression)
49
+
50
+ # Sanitize for AST parsing
51
+ sanitized_expr = self._prepare_for_ast(python_expr)
52
+
53
+ # Use ast to parse and validate the expression
54
+ self._ast = ast.parse(sanitized_expr, mode="eval")
55
+
56
+ # Verify it only contains allowed operations
57
+ self._validate_operations(self._ast.body)
58
+
59
+ # Store the Python-syntax version for evaluation
60
+ self._python_expr = python_expr
61
+
62
+ except SyntaxError as e:
63
+ raise SyntaxError(f"Invalid expression syntax in '{self.expression}': {str(e)}")
64
+ except Exception as e:
65
+ raise ValueError(f"Error validating expression '{self.expression}': {str(e)}")
66
+
67
+ def _extract_variable_names(self, expr: str) -> list[str]:
68
+ """Extract all variable references ${var_name} from the expression."""
69
+ # Find all patterns like ${var_name}
70
+ matches = re.findall(r"\${([^}]*)}", expr)
71
+ return matches
72
+
73
+ def _convert_to_python_syntax(self, expr: str) -> str:
74
+ """Convert symbolic operators to Python keywords."""
75
+ # We need to be careful about operators inside string literals
76
+ # First, temporarily replace string literals with placeholders
77
+ string_literals = []
78
+
79
+ def replace_string_literal(match: re.Match[str]) -> str:
80
+ string_literals.append(match.group(0))
81
+ return f"__STRING_LITERAL_{len(string_literals) - 1}__"
82
+
83
+ # Replace both single and double quoted strings
84
+ expr_without_strings = re.sub(r"'[^']*'|\"[^\"]*\"", replace_string_literal, expr)
85
+
86
+ # Handle the NOT operator (!) - no parentheses handling needed
87
+ # Replace standalone ! before variables or expressions
88
+ expr_without_strings = re.sub(r"!\s*(\${|\()", "not \\1", expr_without_strings)
89
+
90
+ # Handle AND and OR operators - simpler approach without parentheses handling
91
+ expr_without_strings = re.sub(r"\s+&\s+", " and ", expr_without_strings)
92
+ expr_without_strings = re.sub(r"\s+\|\s+", " or ", expr_without_strings)
93
+
94
+ # Now put string literals back
95
+ for i, literal in enumerate(string_literals):
96
+ expr_without_strings = expr_without_strings.replace(f"__STRING_LITERAL_{i}__", literal)
97
+
98
+ return expr_without_strings
99
+
100
+ def _prepare_for_ast(self, expr: str) -> str:
101
+ """Convert the expression to valid Python for AST parsing by replacing variables with placeholders."""
102
+ # Replace ${var_name} with var_name for AST parsing
103
+ processed_expr = expr
104
+ for var_name in self._variable_names:
105
+ processed_expr = processed_expr.replace(f"${{{var_name}}}", var_name)
106
+
107
+ return processed_expr
108
+
109
+ def _validate_operations(self, node: ast.AST) -> None:
110
+ """Recursively validate that only allowed operations exist in the AST."""
111
+ allowed_node_types = (
112
+ # Boolean operations
113
+ ast.BoolOp,
114
+ ast.UnaryOp,
115
+ ast.And,
116
+ ast.Or,
117
+ ast.Not,
118
+ # Comparison operations
119
+ ast.Compare,
120
+ ast.Eq,
121
+ ast.NotEq,
122
+ ast.Lt,
123
+ ast.LtE,
124
+ ast.Gt,
125
+ ast.GtE,
126
+ # Basic nodes
127
+ ast.Name,
128
+ ast.Load,
129
+ ast.Constant,
130
+ ast.Expression,
131
+ # Support for basic numeric operations in comparisons
132
+ ast.Num,
133
+ ast.NameConstant,
134
+ # Support for negative numbers
135
+ ast.USub,
136
+ ast.UnaryOp,
137
+ # Support for string literals
138
+ ast.Str,
139
+ ast.Constant,
140
+ # Support for function calls (specifically len())
141
+ ast.Call,
142
+ )
143
+
144
+ if not isinstance(node, allowed_node_types):
145
+ raise ValueError(f"Operation type {type(node).__name__} is not allowed in logical expressions")
146
+
147
+ # Special validation for function calls - only allow len()
148
+ if isinstance(node, ast.Call):
149
+ if not (isinstance(node.func, ast.Name) and node.func.id == "len"):
150
+ raise ValueError(f"Only the len() function is allowed, got: {getattr(node.func, 'id', 'unknown')}")
151
+ if len(node.args) != 1:
152
+ raise ValueError(f"len() function must have exactly one argument, got {len(node.args)}")
153
+
154
+ # Special validation for Compare nodes
155
+ if isinstance(node, ast.Compare):
156
+ for op in node.ops:
157
+ if not isinstance(op, (ast.Eq, ast.NotEq, ast.Lt, ast.LtE, ast.Gt, ast.GtE)):
158
+ raise ValueError(f"Comparison operator {type(op).__name__} is not allowed")
159
+
160
+ # Recursively check child nodes
161
+ for child in ast.iter_child_nodes(node):
162
+ self._validate_operations(child)
163
+
164
+ def evaluate(self, context_variables: ContextVariables) -> bool:
165
+ """Evaluate the expression using the provided context variables.
166
+
167
+ Args:
168
+ context_variables: Dictionary of context variables to use for evaluation
169
+
170
+ Returns:
171
+ bool: The result of evaluating the expression
172
+
173
+ Raises:
174
+ KeyError: If a variable referenced in the expression is not found in the context
175
+ """
176
+ # Create a modified expression that we can safely evaluate
177
+ eval_expr = self._python_expr # Use the Python-syntax version
178
+
179
+ # First, handle len() functions with variable references inside
180
+ len_pattern = r"len\(\${([^}]*)}\)"
181
+ len_matches = list(re.finditer(len_pattern, eval_expr))
182
+
183
+ # Process all len() operations first
184
+ for match in len_matches:
185
+ var_name = match.group(1)
186
+ # Check if variable exists in context, raise KeyError if not
187
+ if not context_variables.contains(var_name):
188
+ raise KeyError(f"Missing context variable: '{var_name}'")
189
+
190
+ var_value = context_variables.get(var_name)
191
+
192
+ # Calculate the length - works for lists, strings, dictionaries, etc.
193
+ try:
194
+ length_value = len(var_value) # type: ignore[arg-type]
195
+ except TypeError:
196
+ # If the value doesn't support len(), treat as 0
197
+ length_value = 0
198
+
199
+ # Replace the len() expression with the actual length
200
+ full_match = match.group(0)
201
+ eval_expr = eval_expr.replace(full_match, str(length_value))
202
+
203
+ # Then replace remaining variable references with their values
204
+ for var_name in self._variable_names:
205
+ # Skip variables that were already processed in len() expressions
206
+ if any(m.group(1) == var_name for m in len_matches):
207
+ continue
208
+
209
+ # Check if variable exists in context, raise KeyError if not
210
+ if not context_variables.contains(var_name):
211
+ raise KeyError(f"Missing context variable: '{var_name}'")
212
+
213
+ # Get the value from context
214
+ var_value = context_variables.get(var_name)
215
+
216
+ # Format the value appropriately based on its type
217
+ if isinstance(var_value, (bool, int, float)):
218
+ formatted_value = str(var_value)
219
+ elif isinstance(var_value, str):
220
+ formatted_value = f"'{var_value}'" # Quote strings
221
+ elif isinstance(var_value, (list, dict, tuple)):
222
+ # For collections, convert to their boolean evaluation
223
+ formatted_value = str(bool(var_value))
224
+ else:
225
+ formatted_value = str(var_value)
226
+
227
+ # Replace the variable reference with the formatted value
228
+ eval_expr = eval_expr.replace(f"${{{var_name}}}", formatted_value)
229
+
230
+ try:
231
+ return eval(eval_expr) # type: ignore[no-any-return]
232
+ except Exception as e:
233
+ raise ValueError(
234
+ f"Error evaluating expression '{self.expression}' (are you sure you're using ${{my_context_variable_key}}): {str(e)}"
235
+ )
236
+
237
+ def __str__(self) -> str:
238
+ return f"ContextExpression('{self.expression}')"
@@ -0,0 +1,39 @@
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
+
6
+ from pydantic import BaseModel
7
+
8
+ from .context_variables import ContextVariables
9
+
10
+ __all__ = ["ContextStr"]
11
+
12
+
13
+ class ContextStr(BaseModel):
14
+ """A string that requires context variable substitution.
15
+
16
+ Use the format method to substitute context variables into the string.
17
+ """
18
+
19
+ """The string to be substituted with context variables. It is expected that the string will contain `{var}` placeholders and that string format will be able to replace all values."""
20
+ template: str
21
+
22
+ def format(self, context_variables: ContextVariables) -> str | None:
23
+ """Substitute context variables into the string.
24
+
25
+ Args:
26
+ context_variables (ContextVariables): The context variables to substitute into the string.
27
+
28
+ Returns:
29
+ Optional[str]: The formatted string with context variables substituted.
30
+ """
31
+ context = context_variables.to_dict()
32
+
33
+ if not context:
34
+ return self.template
35
+
36
+ return self.template.format(**context)
37
+
38
+ def __str__(self) -> str:
39
+ return f"ContextStr, unformatted: {self.template}"
@@ -0,0 +1,182 @@
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 Generator, Iterable
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel, Field
9
+
10
+ __all__ = ["ContextVariables"]
11
+
12
+ # Parameter name for context variables
13
+ # Use the value in functions and they will be substituted with the context variables:
14
+ # e.g. def my_function(context_variables: ContextVariables, my_other_parameters: Any) -> Any:
15
+ __CONTEXT_VARIABLES_PARAM_NAME__ = "context_variables"
16
+
17
+
18
+ class ContextVariables(BaseModel):
19
+ """Stores and manages context variables for agentic workflows.
20
+
21
+ Utilises a dictionary-like interface for setting, getting, and removing variables.
22
+ """
23
+
24
+ # Internal storage for context variables
25
+ data: dict[str, Any] = Field(default_factory=dict)
26
+
27
+ def __init__(self, data: dict[str, Any] | None = None, **kwargs: Any) -> None:
28
+ """Initialize with data dictionary as an optional positional parameter.
29
+
30
+ Args:
31
+ data: Initial dictionary of context variables (optional)
32
+ kwargs: Additional keyword arguments for the parent class
33
+ """
34
+ init_data = data or {}
35
+ super().__init__(data=init_data, **kwargs)
36
+
37
+ def get(self, key: str, default: Any | None = None) -> Any | None:
38
+ """Get a value from the context by key.
39
+
40
+ Args:
41
+ key: The key to retrieve
42
+ default: The default value to return if key is not found
43
+
44
+ Returns:
45
+ The value associated with the key or default if not found
46
+ """
47
+ return self.data.get(key, default)
48
+
49
+ def set(self, key: str, value: Any) -> None:
50
+ """Set a value in the context by key.
51
+
52
+ Args:
53
+ key: The key to set
54
+ value: The value to store
55
+ """
56
+ self.data[key] = value
57
+
58
+ def remove(self, key: str) -> bool:
59
+ """Remove a key from the context.
60
+
61
+ Args:
62
+ key: The key to remove
63
+
64
+ Returns:
65
+ True if the key was removed, False if it didn't exist
66
+ """
67
+ if key in self.data:
68
+ del self.data[key]
69
+ return True
70
+ return False
71
+
72
+ def keys(self) -> Iterable[str]:
73
+ """Get all keys in the context.
74
+
75
+ Returns:
76
+ An iterable of all keys
77
+ """
78
+ return self.data.keys()
79
+
80
+ def values(self) -> Iterable[Any]:
81
+ """Get all values in the context.
82
+
83
+ Returns:
84
+ An iterable of all values
85
+ """
86
+ return self.data.values()
87
+
88
+ def items(self) -> Iterable[tuple[str, Any]]:
89
+ """Get all key-value pairs in the context.
90
+
91
+ Returns:
92
+ An iterable of all key-value pairs
93
+ """
94
+ return self.data.items()
95
+
96
+ def clear(self) -> None:
97
+ """Clear all keys and values from the context."""
98
+ self.data.clear()
99
+
100
+ def contains(self, key: str) -> bool:
101
+ """Check if a key exists in the context.
102
+
103
+ Args:
104
+ key: The key to check
105
+
106
+ Returns:
107
+ True if the key exists, False otherwise
108
+ """
109
+ return key in self.data
110
+
111
+ def update(self, other: dict[str, Any]) -> None:
112
+ """Update context with key-value pairs from another dictionary.
113
+
114
+ Args:
115
+ other: Dictionary containing key-value pairs to add
116
+ """
117
+ self.data.update(other)
118
+
119
+ def to_dict(self) -> dict[str, Any]:
120
+ """Convert context variables to a dictionary.
121
+
122
+ Returns:
123
+ Dictionary representation of all context variables
124
+ """
125
+ return self.data.copy()
126
+
127
+ # Dictionary-compatible interface
128
+ def __getitem__(self, key: str) -> Any:
129
+ """Get a value using dictionary syntax: context[key]"""
130
+ try:
131
+ return self.data[key]
132
+ except KeyError:
133
+ raise KeyError(f"Context variable '{key}' not found")
134
+
135
+ def __setitem__(self, key: str, value: Any) -> None:
136
+ """Set a value using dictionary syntax: context[key] = value"""
137
+ self.data[key] = value
138
+
139
+ def __delitem__(self, key: str) -> None:
140
+ """Delete a key using dictionary syntax: del context[key]"""
141
+ try:
142
+ del self.data[key]
143
+ except KeyError:
144
+ raise KeyError(f"Cannot delete non-existent context variable '{key}'")
145
+
146
+ def __contains__(self, key: str) -> bool:
147
+ """Check if key exists using 'in' operator: key in context"""
148
+ return key in self.data
149
+
150
+ def __len__(self) -> int:
151
+ """Get the number of items: len(context)"""
152
+ return len(self.data)
153
+
154
+ def __iter__(self) -> Generator[tuple[str, Any], None, None]:
155
+ """Iterate over keys: for key in context"""
156
+ for key in self.data:
157
+ yield (key, self.data[key])
158
+
159
+ def __str__(self) -> str:
160
+ """String representation of context variables."""
161
+ return f"ContextVariables({self.data})"
162
+
163
+ def __repr__(self) -> str:
164
+ """Detailed representation of context variables."""
165
+ return f"ContextVariables(data={self.data!r})"
166
+
167
+ # Utility methods
168
+ @classmethod
169
+ def from_dict(cls, data: dict[str, Any]) -> "ContextVariables":
170
+ """Create a new ContextVariables instance from a dictionary.
171
+
172
+ E.g.:
173
+ my_context = {"user_id": "12345", "settings": {"theme": "dark"}}
174
+ context = ContextVariables.from_dict(my_context)
175
+
176
+ Args:
177
+ data: Dictionary of key-value pairs
178
+
179
+ Returns:
180
+ New ContextVariables instance
181
+ """
182
+ return cls(data=data)