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,284 @@
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 Any
6
+
7
+ import requests
8
+ from pydantic import BaseModel
9
+
10
+ from autogen.import_utils import optional_import_block, require_optional_import
11
+ from autogen.tools import Tool
12
+
13
+ with optional_import_block():
14
+ import wikipediaapi
15
+
16
+ # Maximum allowed length for a query string.
17
+ MAX_QUERY_LENGTH = 300
18
+ # Maximum number of pages to retrieve from a search.
19
+ MAX_PAGE_RETRIEVE = 100
20
+ # Maximum number of characters to return from a Wikipedia page.
21
+ MAX_ARTICLE_LENGTH = 10000
22
+
23
+
24
+ class Document(BaseModel):
25
+ """Pydantic model representing a Wikipedia document.
26
+
27
+ Attributes:
28
+ page_content (str): Textual content of the Wikipedia page
29
+ (possibly truncated).
30
+ metadata (dict[str, str]): Additional info, including:
31
+ - source URL
32
+ - title
33
+ - pageid
34
+ - timestamp
35
+ - word count
36
+ - size
37
+ """
38
+
39
+ page_content: str
40
+ metadata: dict[str, str]
41
+
42
+
43
+ class WikipediaClient:
44
+ """Client for interacting with the Wikipedia API.
45
+
46
+ Supports searching and page retrieval on a specified language edition.
47
+
48
+ Public methods:
49
+ search(query: str, limit: int) -> list[dict[str, Any]]
50
+ get_page(title: str) -> Optional[wikipediaapi.WikipediaPage]
51
+
52
+ Attributes:
53
+ base_url (str): URL of the MediaWiki API endpoint.
54
+ headers (dict[str, str]): HTTP headers, including User-Agent.
55
+ wiki (wikipediaapi.Wikipedia): Low-level Wikipedia API client.
56
+ """
57
+
58
+ def __init__(self, language: str = "en", tool_name: str = "wikipedia-client") -> None:
59
+ """Initialize the WikipediaClient.
60
+
61
+ Args:
62
+ language (str): ISO code of the Wikipedia edition (e.g., 'en', 'es').
63
+ tool_name (str): Identifier for User-Agent header.
64
+ """
65
+ self.base_url = f"https://{language}.wikipedia.org/w/api.php"
66
+ self.headers = {"User-Agent": f"autogen.Agent ({tool_name})"}
67
+ self.wiki = wikipediaapi.Wikipedia(
68
+ language=language,
69
+ extract_format=wikipediaapi.ExtractFormat.WIKI,
70
+ user_agent=f"autogen.Agent ({tool_name})",
71
+ )
72
+
73
+ def search(self, query: str, limit: int = 3) -> Any:
74
+ """Search Wikipedia for pages matching a query string.
75
+
76
+ Args:
77
+ query (str): The search keywords.
78
+ limit (int): Max number of results to return.
79
+
80
+ Returns:
81
+ list[dict[str, Any]]: Each dict has keys:
82
+ - 'title' (str)
83
+ - 'size' (int)
84
+ - 'wordcount' (int)
85
+ - 'timestamp' (str)
86
+
87
+ Raises:
88
+ requests.HTTPError: If the HTTP request to the API fails.
89
+ """
90
+ params = {
91
+ "action": "query",
92
+ "format": "json",
93
+ "list": "search",
94
+ "srsearch": query,
95
+ "srlimit": str(limit),
96
+ "srprop": "size|wordcount|timestamp",
97
+ }
98
+
99
+ response = requests.get(url=self.base_url, params=params, headers=self.headers)
100
+ response.raise_for_status()
101
+ data = response.json()
102
+ search_data = data.get("query", {}).get("search", [])
103
+ return search_data
104
+
105
+ def get_page(self, title: str) -> Any | None:
106
+ """Retrieve a WikipediaPage object by title.
107
+
108
+ Args:
109
+ title (str): Title of the Wikipedia page.
110
+
111
+ Returns:
112
+ wikipediaapi.WikipediaPage | None: The page object if it exists,
113
+ otherwise None.
114
+
115
+ Raises:
116
+ wikipediaapi.WikipediaException: On lower‑level API errors.
117
+ """
118
+ page = self.wiki.page(title)
119
+ if not page.exists():
120
+ return None
121
+ return page
122
+
123
+
124
+ @require_optional_import(["wikipediaapi"], "wikipedia")
125
+ class WikipediaQueryRunTool(Tool):
126
+ """Tool for querying Wikipedia and returning summarized page results.
127
+
128
+ This tool uses the `wikipediaapi` package to perform searches
129
+ against a specified language edition of Wikipedia and returns
130
+ up to `top_k` page summaries.
131
+
132
+ Public methods:
133
+ query_run(query: str) -> list[str] | str
134
+
135
+ Attributes:
136
+ language (str): Language code for the Wikipedia edition (e.g., 'en', 'es').
137
+ top_k (int): Max number of page summaries returned (≤ MAX_PAGE_RETRIEVE).
138
+ verbose (bool): If True, enables debug logging to stdout.
139
+ wiki_cli (WikipediaClient): Internal client for Wikipedia API calls.
140
+ """
141
+
142
+ def __init__(self, language: str = "en", top_k: int = 3, verbose: bool = False) -> None:
143
+ """Initialize the WikipediaQueryRunTool.
144
+
145
+ Args:
146
+ language (str): ISO code of the Wikipedia edition to query.
147
+ top_k (int): Desired number of summaries (capped by MAX_PAGE_RETRIEVE).
148
+ verbose (bool): If True, print debug information during searches.
149
+ """
150
+ self.language = language
151
+ self.tool_name = "wikipedia-query-run"
152
+ self.wiki_cli = WikipediaClient(language, self.tool_name)
153
+ self.top_k = min(top_k, MAX_PAGE_RETRIEVE)
154
+ self.verbose = verbose
155
+ super().__init__(
156
+ name=self.tool_name,
157
+ description="Run a Wikipedia query and return page summaries.",
158
+ func_or_tool=self.query_run,
159
+ )
160
+
161
+ def query_run(self, query: str) -> list[str] | str:
162
+ """Search Wikipedia and return formatted page summaries.
163
+
164
+ Truncates `query` to MAX_QUERY_LENGTH before searching.
165
+
166
+ Args:
167
+ query (str): Search term(s) to look up in Wikipedia.
168
+
169
+ Returns:
170
+ list[str]: Each element is "Page: <title>\nSummary: <text>".
171
+ str: Error message if no results are found or on exception.
172
+
173
+ Note:
174
+ Automatically handles API exceptions and returns error strings for robust operation
175
+ """
176
+ try:
177
+ if self.verbose:
178
+ print(f"INFO\t [{self.tool_name}] search query='{query[:MAX_QUERY_LENGTH]}' top_k={self.top_k}")
179
+ search_results = self.wiki_cli.search(query[:MAX_QUERY_LENGTH], limit=self.top_k)
180
+ summaries: list[str] = []
181
+ for item in search_results:
182
+ title = item["title"]
183
+ page = self.wiki_cli.get_page(title)
184
+ # Only format the summary if the page exists and has a summary.
185
+ if page is not None and page.summary:
186
+ summary = f"Page: {title}\nSummary: {page.summary}"
187
+ summaries.append(summary)
188
+ if not summaries:
189
+ return "No good Wikipedia Search Result was found"
190
+ return summaries
191
+ except Exception as e:
192
+ return f"wikipedia search failed: {str(e)}"
193
+
194
+
195
+ @require_optional_import(["wikipediaapi"], "wikipedia")
196
+ class WikipediaPageLoadTool(Tool):
197
+ """A tool to load up to N characters of Wikipedia page content along with metadata.
198
+
199
+ This tool uses a language-specific Wikipedia client to search for relevant articles
200
+ and returns a list of Document objects containing truncated page content and metadata
201
+ (source URL, title, page ID, timestamp, word count, and size). Ideal for agents
202
+ requiring structured Wikipedia data for research, summarization, or contextual enrichment.
203
+
204
+ Attributes:
205
+ language (str): Wikipedia language code (default: "en").
206
+ top_k (int): Maximum number of pages to retrieve per query (default: 3).
207
+ truncate (int): Maximum number of characters of content per page (default: 4000).
208
+ verbose (bool): If True, prints debug information (default: False).
209
+ tool_name (str): Identifier used in User-Agent header.
210
+ wiki_cli (WikipediaClient): Client for interacting with the Wikipedia API.
211
+ """
212
+
213
+ def __init__(self, language: str = "en", top_k: int = 3, truncate: int = 4000, verbose: bool = False) -> None:
214
+ """Initializes the WikipediaPageLoadTool with configurable language, result count, and content length.
215
+
216
+ Args:
217
+ language (str): The language code for the Wikipedia edition (default is "en").
218
+ top_k (int): The maximum number of pages to retrieve per query (default is 3;
219
+ capped at MAX_PAGE_RETRIEVE).
220
+ truncate (int): The maximum number of characters to extract from each page (default is 4000;
221
+ capped at MAX_ARTICLE_LENGTH).
222
+ verbose (bool): If True, enables verbose/debug logging (default is False).
223
+ """
224
+ self.language = language
225
+ self.top_k = min(top_k, MAX_PAGE_RETRIEVE)
226
+ self.truncate = min(truncate, MAX_ARTICLE_LENGTH)
227
+ self.verbose = verbose
228
+ self.tool_name = "wikipedia-page-load"
229
+ self.wiki_cli = WikipediaClient(language, self.tool_name)
230
+ super().__init__(
231
+ name=self.tool_name,
232
+ description=(
233
+ "Search Wikipedia for relevant pages using a language-specific client. "
234
+ "Returns a list of documents with truncated content and metadata including title, URL, "
235
+ "page ID, timestamp, word count, and page size. Configure number of results with the 'top_k' parameter "
236
+ "and content length with 'truncate'. Useful for research, summarization, or contextual enrichment."
237
+ ),
238
+ func_or_tool=self.content_search,
239
+ )
240
+
241
+ def content_search(self, query: str) -> list[Document] | str:
242
+ """Executes a Wikipedia search and returns page content plus metadata.
243
+
244
+ Args:
245
+ query (str): The search term to query Wikipedia.
246
+
247
+ Returns:
248
+ Union[list[Document], str]:
249
+ - list[Document]: Documents with up to `truncate` characters of page text
250
+ and metadata if pages are found.
251
+ - str: Error message if the search fails or no pages are found.
252
+
253
+ Notes:
254
+ - Errors are caught internally and returned as strings.
255
+ - If no matching pages have text content, returns
256
+ "No good Wikipedia Search Result was found".
257
+ """
258
+ try:
259
+ if self.verbose:
260
+ print(f"INFO\t [{self.tool_name}] search query='{query[:MAX_QUERY_LENGTH]}' top_k={self.top_k}")
261
+ search_results = self.wiki_cli.search(query[:MAX_QUERY_LENGTH], limit=self.top_k)
262
+ docs: list[Document] = []
263
+ for item in search_results:
264
+ page = self.wiki_cli.get_page(item["title"])
265
+ # Only process pages that exist and have text content.
266
+ if page is not None and page.text:
267
+ document = Document(
268
+ page_content=page.text[: self.truncate],
269
+ metadata={
270
+ "source": f"https://{self.language}.wikipedia.org/?curid={item['pageid']}",
271
+ "title": item["title"],
272
+ "pageid": str(item["pageid"]),
273
+ "timestamp": str(item["timestamp"]),
274
+ "wordcount": str(item["wordcount"]),
275
+ "size": str(item["size"]),
276
+ },
277
+ )
278
+ docs.append(document)
279
+ if not docs:
280
+ return "No good Wikipedia Search Result was found"
281
+ return docs
282
+
283
+ except Exception as e:
284
+ return f"wikipedia search failed: {str(e)}"
@@ -0,0 +1,412 @@
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
+ import functools
8
+ import inspect
9
+ import json
10
+ from collections.abc import Callable
11
+ from logging import getLogger
12
+ from typing import Annotated, Any, ForwardRef, Literal, TypeVar, get_args, get_origin
13
+
14
+ from packaging.version import parse
15
+ from pydantic import BaseModel, Field, TypeAdapter
16
+ from pydantic import __version__ as pydantic_version
17
+ from pydantic.json_schema import JsonSchemaValue
18
+
19
+ from ..doc_utils import export_module
20
+ from ..fast_depends.utils import is_coroutine_callable
21
+ from .dependency_injection import Field as AG2Field
22
+
23
+ if parse(pydantic_version) < parse("2.10.2"):
24
+ from pydantic._internal._typing_extra import eval_type_lenient as try_eval_type
25
+ else:
26
+ from pydantic._internal._typing_extra import try_eval_type
27
+
28
+
29
+ __all__ = ["get_function_schema", "load_basemodels_if_needed", "serialize_to_str"]
30
+
31
+ logger = getLogger(__name__)
32
+
33
+ T = TypeVar("T")
34
+
35
+
36
+ def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any:
37
+ """Get the type annotation of a parameter.
38
+
39
+ Args:
40
+ annotation: The annotation of the parameter
41
+ globalns: The global namespace of the function
42
+
43
+ Returns:
44
+ The type annotation of the parameter
45
+ """
46
+ if isinstance(annotation, AG2Field):
47
+ annotation = annotation.description
48
+ if isinstance(annotation, str):
49
+ annotation = ForwardRef(annotation)
50
+ annotation, _ = try_eval_type(annotation, globalns, globalns)
51
+ return annotation
52
+
53
+
54
+ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
55
+ """Get the signature of a function with type annotations.
56
+
57
+ Args:
58
+ call: The function to get the signature for
59
+
60
+ Returns:
61
+ The signature of the function with type annotations
62
+ """
63
+ signature = inspect.signature(call)
64
+ globalns = getattr(call, "__globals__", {})
65
+ typed_params = [
66
+ inspect.Parameter(
67
+ name=param.name,
68
+ kind=param.kind,
69
+ default=param.default,
70
+ annotation=get_typed_annotation(param.annotation, globalns),
71
+ )
72
+ for param in signature.parameters.values()
73
+ ]
74
+ typed_signature = inspect.Signature(typed_params)
75
+ return typed_signature
76
+
77
+
78
+ def get_typed_return_annotation(call: Callable[..., Any]) -> Any:
79
+ """Get the return annotation of a function.
80
+
81
+ Args:
82
+ call: The function to get the return annotation for
83
+
84
+ Returns:
85
+ The return annotation of the function
86
+ """
87
+ signature = inspect.signature(call)
88
+ annotation = signature.return_annotation
89
+
90
+ if annotation is inspect.Signature.empty:
91
+ return None
92
+
93
+ globalns = getattr(call, "__globals__", {})
94
+ return get_typed_annotation(annotation, globalns)
95
+
96
+
97
+ def get_param_annotations(typed_signature: inspect.Signature) -> dict[str, Annotated[type[Any], str] | type[Any]]:
98
+ """Get the type annotations of the parameters of a function
99
+
100
+ Args:
101
+ typed_signature: The signature of the function with type annotations
102
+
103
+ Returns:
104
+ A dictionary of the type annotations of the parameters of the function
105
+ """
106
+ return {
107
+ k: v.annotation for k, v in typed_signature.parameters.items() if v.annotation is not inspect.Signature.empty
108
+ }
109
+
110
+
111
+ class Parameters(BaseModel):
112
+ """Parameters of a function as defined by the OpenAI API"""
113
+
114
+ type: Literal["object"] = "object"
115
+ properties: dict[str, JsonSchemaValue]
116
+ required: list[str]
117
+
118
+
119
+ class Function(BaseModel):
120
+ """A function as defined by the OpenAI API"""
121
+
122
+ description: Annotated[str, Field(description="Description of the function")]
123
+ name: Annotated[str, Field(description="Name of the function")]
124
+ parameters: Annotated[Parameters, Field(description="Parameters of the function")]
125
+
126
+
127
+ class ToolFunction(BaseModel):
128
+ """A function under tool as defined by the OpenAI API."""
129
+
130
+ type: Literal["function"] = "function"
131
+ function: Annotated[Function, Field(description="Function under tool")]
132
+
133
+
134
+ def get_parameter_json_schema(k: str, v: Any, default_values: dict[str, Any]) -> JsonSchemaValue:
135
+ """Get a JSON schema for a parameter as defined by the OpenAI API
136
+
137
+ Args:
138
+ k: The name of the parameter
139
+ v: The type of the parameter
140
+ default_values: The default values of the parameters of the function
141
+
142
+ Returns:
143
+ A Pydanitc model for the parameter
144
+ """
145
+
146
+ def type2description(k: str, v: Annotated[type[Any], str] | type[Any]) -> str:
147
+ if not hasattr(v, "__metadata__"):
148
+ return k
149
+
150
+ # handles Annotated
151
+ retval = v.__metadata__[0]
152
+ if isinstance(retval, AG2Field):
153
+ return retval.description # type: ignore[return-value]
154
+ else:
155
+ raise ValueError(f"Invalid {retval} for parameter {k}, should be a DescriptionField, got {type(retval)}")
156
+
157
+ schema = TypeAdapter(v).json_schema()
158
+ if k in default_values:
159
+ dv = default_values[k]
160
+ schema["default"] = dv
161
+
162
+ schema["description"] = type2description(k, v)
163
+
164
+ return schema
165
+
166
+
167
+ def get_required_params(typed_signature: inspect.Signature) -> list[str]:
168
+ """Get the required parameters of a function
169
+
170
+ Args:
171
+ typed_signature: The signature of the function as returned by inspect.signature
172
+
173
+ Returns:
174
+ A list of the required parameters of the function
175
+ """
176
+ return [k for k, v in typed_signature.parameters.items() if v.default == inspect.Signature.empty]
177
+
178
+
179
+ def get_default_values(typed_signature: inspect.Signature) -> dict[str, Any]:
180
+ """Get default values of parameters of a function
181
+
182
+ Args:
183
+ typed_signature: The signature of the function as returned by inspect.signature
184
+
185
+ Returns:
186
+ A dictionary of the default values of the parameters of the function
187
+ """
188
+ return {k: v.default for k, v in typed_signature.parameters.items() if v.default != inspect.Signature.empty}
189
+
190
+
191
+ def get_parameters(
192
+ required: list[str],
193
+ param_annotations: dict[str, Annotated[type[Any], str] | type[Any]],
194
+ default_values: dict[str, Any],
195
+ ) -> Parameters:
196
+ """Get the parameters of a function as defined by the OpenAI API
197
+
198
+ Args:
199
+ required: The required parameters of the function
200
+ param_annotations: The type annotations of the parameters of the function
201
+ default_values: The default values of the parameters of the function
202
+
203
+ Returns:
204
+ A Pydantic model for the parameters of the function
205
+ """
206
+ return Parameters(
207
+ properties={
208
+ k: get_parameter_json_schema(k, v, default_values)
209
+ for k, v in param_annotations.items()
210
+ if v is not inspect.Signature.empty
211
+ },
212
+ required=required,
213
+ )
214
+
215
+
216
+ def get_missing_annotations(typed_signature: inspect.Signature, required: list[str]) -> tuple[set[str], set[str]]:
217
+ """Get the missing annotations of a function
218
+
219
+ Ignores the parameters with default values as they are not required to be annotated, but logs a warning.
220
+
221
+ Args:
222
+ typed_signature: The signature of the function with type annotations
223
+ required: The required parameters of the function
224
+
225
+ Returns:
226
+ A set of the missing annotations of the function
227
+ """
228
+ all_missing = {k for k, v in typed_signature.parameters.items() if v.annotation is inspect.Signature.empty}
229
+ missing = all_missing.intersection(set(required))
230
+ unannotated_with_default = all_missing.difference(missing)
231
+ return missing, unannotated_with_default
232
+
233
+
234
+ @export_module("autogen.tools")
235
+ def get_function_schema(f: Callable[..., Any], *, name: str | None = None, description: str) -> dict[str, Any]:
236
+ """Get a JSON schema for a function as defined by the OpenAI API
237
+
238
+ Args:
239
+ f: The function to get the JSON schema for
240
+ name: The name of the function
241
+ description: The description of the function
242
+
243
+ Returns:
244
+ A JSON schema for the function
245
+
246
+ Raises:
247
+ TypeError: If the function is not annotated
248
+
249
+ Examples:
250
+ ```python
251
+ def f(a: Annotated[str, "Parameter a"], b: int = 2, c: Annotated[float, "Parameter c"] = 0.1) -> None:
252
+ pass
253
+
254
+
255
+ get_function_schema(f, description="function f")
256
+
257
+ # {'type': 'function',
258
+ # 'function': {'description': 'function f',
259
+ # 'name': 'f',
260
+ # 'parameters': {'type': 'object',
261
+ # 'properties': {'a': {'type': 'str', 'description': 'Parameter a'},
262
+ # 'b': {'type': 'int', 'description': 'b'},
263
+ # 'c': {'type': 'float', 'description': 'Parameter c'}},
264
+ # 'required': ['a']}}}
265
+ ```
266
+
267
+ """
268
+ typed_signature = get_typed_signature(f)
269
+ required = get_required_params(typed_signature)
270
+ default_values = get_default_values(typed_signature)
271
+ param_annotations = get_param_annotations(typed_signature)
272
+ return_annotation = get_typed_return_annotation(f)
273
+ missing, unannotated_with_default = get_missing_annotations(typed_signature, required)
274
+
275
+ if return_annotation is None:
276
+ logger.warning(
277
+ f"The return type of the function '{f.__name__}' is not annotated. Although annotating it is "
278
+ + "optional, the function should return either a string, a subclass of 'pydantic.BaseModel'."
279
+ )
280
+
281
+ if unannotated_with_default != set():
282
+ unannotated_with_default_s = [f"'{k}'" for k in sorted(unannotated_with_default)]
283
+ logger.warning(
284
+ f"The following parameters of the function '{f.__name__}' with default values are not annotated: "
285
+ + f"{', '.join(unannotated_with_default_s)}."
286
+ )
287
+
288
+ if missing != set():
289
+ missing_s = [f"'{k}'" for k in sorted(missing)]
290
+ raise TypeError(
291
+ f"All parameters of the function '{f.__name__}' without default values must be annotated. "
292
+ + f"The annotations are missing for the following parameters: {', '.join(missing_s)}"
293
+ )
294
+
295
+ fname = name if name else f.__name__
296
+
297
+ parameters = get_parameters(required, param_annotations, default_values=default_values)
298
+
299
+ function = ToolFunction(
300
+ function=Function(
301
+ description=description,
302
+ name=fname,
303
+ parameters=parameters,
304
+ )
305
+ )
306
+
307
+ return function.model_dump()
308
+
309
+
310
+ def get_load_param_if_needed_function(t: Any) -> Callable[[dict[str, Any], type[BaseModel]], BaseModel] | None:
311
+ """Get a function to load a parameter if it is a Pydantic model
312
+
313
+ Args:
314
+ t: The type annotation of the parameter
315
+
316
+ Returns:
317
+ A function to load the parameter if it is a Pydantic model, otherwise None
318
+
319
+ """
320
+ origin = get_origin(t)
321
+
322
+ if origin is Annotated:
323
+ args = get_args(t)
324
+ if args:
325
+ return get_load_param_if_needed_function(args[0])
326
+ else:
327
+ # Invalid Annotated usage
328
+ return None
329
+
330
+ # Handle generic types (list[str], dict[str,Any], Union[...], etc.) or where t is not a type at all
331
+ # This means it's not a BaseModel subclass
332
+ if origin is not None or not isinstance(t, type):
333
+ return None
334
+
335
+ def load_base_model(v: dict[str, Any], model_type: type[BaseModel]) -> BaseModel:
336
+ return model_type(**v)
337
+
338
+ # Check if it's a class and a subclass of BaseModel
339
+ if issubclass(t, BaseModel):
340
+ return load_base_model
341
+ else:
342
+ return None
343
+
344
+
345
+ @export_module("autogen.tools")
346
+ def load_basemodels_if_needed(func: Callable[..., Any]) -> Callable[..., Any]:
347
+ """A decorator to load the parameters of a function if they are Pydantic models
348
+
349
+ Args:
350
+ func: The function with annotated parameters
351
+
352
+ Returns:
353
+ A function that loads the parameters before calling the original function
354
+
355
+ """
356
+ # get the type annotations of the parameters
357
+ typed_signature = get_typed_signature(func)
358
+ param_annotations = get_param_annotations(typed_signature)
359
+
360
+ # get functions for loading BaseModels when needed based on the type annotations
361
+ kwargs_mapping_with_nones = {k: get_load_param_if_needed_function(t) for k, t in param_annotations.items()}
362
+
363
+ # remove the None values
364
+ kwargs_mapping = {k: f for k, f in kwargs_mapping_with_nones.items() if f is not None}
365
+
366
+ # a function that loads the parameters before calling the original function
367
+ @functools.wraps(func)
368
+ def _load_parameters_if_needed(*args: Any, **kwargs: Any) -> Any:
369
+ # load the BaseModels if needed
370
+ for k, f in kwargs_mapping.items():
371
+ kwargs[k] = f(kwargs[k], param_annotations[k])
372
+
373
+ # call the original function
374
+ return func(*args, **kwargs)
375
+
376
+ @functools.wraps(func)
377
+ async def _a_load_parameters_if_needed(*args: Any, **kwargs: Any) -> Any:
378
+ # load the BaseModels if needed
379
+ for k, f in kwargs_mapping.items():
380
+ kwargs[k] = f(kwargs[k], param_annotations[k])
381
+
382
+ # call the original function
383
+ return await func(*args, **kwargs)
384
+
385
+ if is_coroutine_callable(func):
386
+ return _a_load_parameters_if_needed
387
+ else:
388
+ return _load_parameters_if_needed
389
+
390
+
391
+ class _SerializableResult(BaseModel):
392
+ result: Any
393
+
394
+
395
+ @export_module("autogen.tools")
396
+ def serialize_to_str(x: Any) -> str:
397
+ if isinstance(x, str):
398
+ return x
399
+ if isinstance(x, BaseModel):
400
+ return x.model_dump_json()
401
+
402
+ retval_model = _SerializableResult(result=x)
403
+ try:
404
+ return str(retval_model.model_dump()["result"])
405
+ except Exception:
406
+ pass
407
+
408
+ # try json.dumps() and then just return str(x) if that fails too
409
+ try:
410
+ return json.dumps(x, ensure_ascii=False)
411
+ except Exception:
412
+ return str(x)