ag2 0.9.1__py3-none-any.whl → 0.9.1.post0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ag2 might be problematic. Click here for more details.

Files changed (357) hide show
  1. {ag2-0.9.1.dist-info → ag2-0.9.1.post0.dist-info}/METADATA +264 -73
  2. ag2-0.9.1.post0.dist-info/RECORD +392 -0
  3. {ag2-0.9.1.dist-info → ag2-0.9.1.post0.dist-info}/WHEEL +1 -2
  4. autogen/__init__.py +89 -0
  5. autogen/_website/__init__.py +3 -0
  6. autogen/_website/generate_api_references.py +427 -0
  7. autogen/_website/generate_mkdocs.py +1174 -0
  8. autogen/_website/notebook_processor.py +476 -0
  9. autogen/_website/process_notebooks.py +656 -0
  10. autogen/_website/utils.py +412 -0
  11. autogen/agentchat/__init__.py +44 -0
  12. autogen/agentchat/agent.py +182 -0
  13. autogen/agentchat/assistant_agent.py +85 -0
  14. autogen/agentchat/chat.py +309 -0
  15. autogen/agentchat/contrib/__init__.py +5 -0
  16. autogen/agentchat/contrib/agent_eval/README.md +7 -0
  17. autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
  18. autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
  19. autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
  20. autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
  21. autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
  22. autogen/agentchat/contrib/agent_eval/task.py +42 -0
  23. autogen/agentchat/contrib/agent_optimizer.py +429 -0
  24. autogen/agentchat/contrib/capabilities/__init__.py +5 -0
  25. autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
  26. autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
  27. autogen/agentchat/contrib/capabilities/teachability.py +393 -0
  28. autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
  29. autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
  30. autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
  31. autogen/agentchat/contrib/capabilities/transforms.py +566 -0
  32. autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
  33. autogen/agentchat/contrib/capabilities/vision_capability.py +214 -0
  34. autogen/agentchat/contrib/captainagent/__init__.py +9 -0
  35. autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
  36. autogen/agentchat/contrib/captainagent/captainagent.py +512 -0
  37. autogen/agentchat/contrib/captainagent/tool_retriever.py +335 -0
  38. autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
  39. autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
  40. autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
  41. autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
  42. autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
  43. autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
  44. autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
  45. autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
  46. autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
  47. autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
  48. autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
  49. autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
  50. autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
  51. autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
  52. autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
  53. autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
  54. autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
  55. autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
  56. autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
  57. autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
  58. autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
  59. autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
  60. autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
  61. autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
  62. autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
  63. autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
  64. autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
  65. autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
  66. autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
  67. autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
  68. autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
  69. autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
  70. autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
  71. autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
  72. autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
  73. autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
  74. autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
  75. autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
  76. autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
  77. autogen/agentchat/contrib/graph_rag/document.py +29 -0
  78. autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +170 -0
  79. autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
  80. autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
  81. autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
  82. autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +268 -0
  83. autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
  84. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
  85. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
  86. autogen/agentchat/contrib/img_utils.py +397 -0
  87. autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
  88. autogen/agentchat/contrib/llava_agent.py +187 -0
  89. autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
  90. autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
  91. autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +324 -0
  92. autogen/agentchat/contrib/rag/__init__.py +10 -0
  93. autogen/agentchat/contrib/rag/chromadb_query_engine.py +272 -0
  94. autogen/agentchat/contrib/rag/llamaindex_query_engine.py +198 -0
  95. autogen/agentchat/contrib/rag/mongodb_query_engine.py +329 -0
  96. autogen/agentchat/contrib/rag/query_engine.py +74 -0
  97. autogen/agentchat/contrib/retrieve_assistant_agent.py +56 -0
  98. autogen/agentchat/contrib/retrieve_user_proxy_agent.py +703 -0
  99. autogen/agentchat/contrib/society_of_mind_agent.py +199 -0
  100. autogen/agentchat/contrib/swarm_agent.py +1425 -0
  101. autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
  102. autogen/agentchat/contrib/vectordb/__init__.py +5 -0
  103. autogen/agentchat/contrib/vectordb/base.py +232 -0
  104. autogen/agentchat/contrib/vectordb/chromadb.py +315 -0
  105. autogen/agentchat/contrib/vectordb/couchbase.py +407 -0
  106. autogen/agentchat/contrib/vectordb/mongodb.py +550 -0
  107. autogen/agentchat/contrib/vectordb/pgvectordb.py +928 -0
  108. autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
  109. autogen/agentchat/contrib/vectordb/utils.py +126 -0
  110. autogen/agentchat/contrib/web_surfer.py +303 -0
  111. autogen/agentchat/conversable_agent.py +4020 -0
  112. autogen/agentchat/group/__init__.py +64 -0
  113. autogen/agentchat/group/available_condition.py +91 -0
  114. autogen/agentchat/group/context_condition.py +77 -0
  115. autogen/agentchat/group/context_expression.py +238 -0
  116. autogen/agentchat/group/context_str.py +41 -0
  117. autogen/agentchat/group/context_variables.py +192 -0
  118. autogen/agentchat/group/group_tool_executor.py +202 -0
  119. autogen/agentchat/group/group_utils.py +591 -0
  120. autogen/agentchat/group/handoffs.py +244 -0
  121. autogen/agentchat/group/llm_condition.py +93 -0
  122. autogen/agentchat/group/multi_agent_chat.py +237 -0
  123. autogen/agentchat/group/on_condition.py +58 -0
  124. autogen/agentchat/group/on_context_condition.py +54 -0
  125. autogen/agentchat/group/patterns/__init__.py +18 -0
  126. autogen/agentchat/group/patterns/auto.py +159 -0
  127. autogen/agentchat/group/patterns/manual.py +176 -0
  128. autogen/agentchat/group/patterns/pattern.py +288 -0
  129. autogen/agentchat/group/patterns/random.py +106 -0
  130. autogen/agentchat/group/patterns/round_robin.py +117 -0
  131. autogen/agentchat/group/reply_result.py +26 -0
  132. autogen/agentchat/group/speaker_selection_result.py +41 -0
  133. autogen/agentchat/group/targets/__init__.py +4 -0
  134. autogen/agentchat/group/targets/group_chat_target.py +132 -0
  135. autogen/agentchat/group/targets/group_manager_target.py +151 -0
  136. autogen/agentchat/group/targets/transition_target.py +413 -0
  137. autogen/agentchat/group/targets/transition_utils.py +6 -0
  138. autogen/agentchat/groupchat.py +1694 -0
  139. autogen/agentchat/realtime/__init__.py +3 -0
  140. autogen/agentchat/realtime/experimental/__init__.py +20 -0
  141. autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
  142. autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
  143. autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
  144. autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
  145. autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
  146. autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
  147. autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
  148. autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
  149. autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
  150. autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
  151. autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
  152. autogen/agentchat/realtime/experimental/clients/realtime_client.py +190 -0
  153. autogen/agentchat/realtime/experimental/function_observer.py +85 -0
  154. autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
  155. autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
  156. autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
  157. autogen/agentchat/realtime/experimental/realtime_swarm.py +475 -0
  158. autogen/agentchat/realtime/experimental/websockets.py +21 -0
  159. autogen/agentchat/realtime_agent/__init__.py +21 -0
  160. autogen/agentchat/user_proxy_agent.py +111 -0
  161. autogen/agentchat/utils.py +206 -0
  162. autogen/agents/__init__.py +3 -0
  163. autogen/agents/contrib/__init__.py +10 -0
  164. autogen/agents/contrib/time/__init__.py +8 -0
  165. autogen/agents/contrib/time/time_reply_agent.py +73 -0
  166. autogen/agents/contrib/time/time_tool_agent.py +51 -0
  167. autogen/agents/experimental/__init__.py +27 -0
  168. autogen/agents/experimental/deep_research/__init__.py +7 -0
  169. autogen/agents/experimental/deep_research/deep_research.py +52 -0
  170. autogen/agents/experimental/discord/__init__.py +7 -0
  171. autogen/agents/experimental/discord/discord.py +66 -0
  172. autogen/agents/experimental/document_agent/__init__.py +19 -0
  173. autogen/agents/experimental/document_agent/chroma_query_engine.py +316 -0
  174. autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +118 -0
  175. autogen/agents/experimental/document_agent/document_agent.py +461 -0
  176. autogen/agents/experimental/document_agent/document_conditions.py +50 -0
  177. autogen/agents/experimental/document_agent/document_utils.py +380 -0
  178. autogen/agents/experimental/document_agent/inmemory_query_engine.py +220 -0
  179. autogen/agents/experimental/document_agent/parser_utils.py +130 -0
  180. autogen/agents/experimental/document_agent/url_utils.py +426 -0
  181. autogen/agents/experimental/reasoning/__init__.py +7 -0
  182. autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
  183. autogen/agents/experimental/slack/__init__.py +7 -0
  184. autogen/agents/experimental/slack/slack.py +73 -0
  185. autogen/agents/experimental/telegram/__init__.py +7 -0
  186. autogen/agents/experimental/telegram/telegram.py +77 -0
  187. autogen/agents/experimental/websurfer/__init__.py +7 -0
  188. autogen/agents/experimental/websurfer/websurfer.py +62 -0
  189. autogen/agents/experimental/wikipedia/__init__.py +7 -0
  190. autogen/agents/experimental/wikipedia/wikipedia.py +90 -0
  191. autogen/browser_utils.py +309 -0
  192. autogen/cache/__init__.py +10 -0
  193. autogen/cache/abstract_cache_base.py +75 -0
  194. autogen/cache/cache.py +203 -0
  195. autogen/cache/cache_factory.py +88 -0
  196. autogen/cache/cosmos_db_cache.py +144 -0
  197. autogen/cache/disk_cache.py +102 -0
  198. autogen/cache/in_memory_cache.py +58 -0
  199. autogen/cache/redis_cache.py +123 -0
  200. autogen/code_utils.py +596 -0
  201. autogen/coding/__init__.py +22 -0
  202. autogen/coding/base.py +119 -0
  203. autogen/coding/docker_commandline_code_executor.py +268 -0
  204. autogen/coding/factory.py +47 -0
  205. autogen/coding/func_with_reqs.py +202 -0
  206. autogen/coding/jupyter/__init__.py +23 -0
  207. autogen/coding/jupyter/base.py +36 -0
  208. autogen/coding/jupyter/docker_jupyter_server.py +167 -0
  209. autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
  210. autogen/coding/jupyter/import_utils.py +82 -0
  211. autogen/coding/jupyter/jupyter_client.py +231 -0
  212. autogen/coding/jupyter/jupyter_code_executor.py +160 -0
  213. autogen/coding/jupyter/local_jupyter_server.py +172 -0
  214. autogen/coding/local_commandline_code_executor.py +405 -0
  215. autogen/coding/markdown_code_extractor.py +45 -0
  216. autogen/coding/utils.py +56 -0
  217. autogen/doc_utils.py +34 -0
  218. autogen/events/__init__.py +7 -0
  219. autogen/events/agent_events.py +1010 -0
  220. autogen/events/base_event.py +99 -0
  221. autogen/events/client_events.py +167 -0
  222. autogen/events/helpers.py +36 -0
  223. autogen/events/print_event.py +46 -0
  224. autogen/exception_utils.py +73 -0
  225. autogen/extensions/__init__.py +5 -0
  226. autogen/fast_depends/__init__.py +16 -0
  227. autogen/fast_depends/_compat.py +80 -0
  228. autogen/fast_depends/core/__init__.py +14 -0
  229. autogen/fast_depends/core/build.py +225 -0
  230. autogen/fast_depends/core/model.py +576 -0
  231. autogen/fast_depends/dependencies/__init__.py +15 -0
  232. autogen/fast_depends/dependencies/model.py +29 -0
  233. autogen/fast_depends/dependencies/provider.py +39 -0
  234. autogen/fast_depends/library/__init__.py +10 -0
  235. autogen/fast_depends/library/model.py +46 -0
  236. autogen/fast_depends/py.typed +6 -0
  237. autogen/fast_depends/schema.py +66 -0
  238. autogen/fast_depends/use.py +280 -0
  239. autogen/fast_depends/utils.py +187 -0
  240. autogen/formatting_utils.py +83 -0
  241. autogen/function_utils.py +13 -0
  242. autogen/graph_utils.py +178 -0
  243. autogen/import_utils.py +526 -0
  244. autogen/interop/__init__.py +22 -0
  245. autogen/interop/crewai/__init__.py +7 -0
  246. autogen/interop/crewai/crewai.py +88 -0
  247. autogen/interop/interoperability.py +71 -0
  248. autogen/interop/interoperable.py +46 -0
  249. autogen/interop/langchain/__init__.py +8 -0
  250. autogen/interop/langchain/langchain_chat_model_factory.py +155 -0
  251. autogen/interop/langchain/langchain_tool.py +82 -0
  252. autogen/interop/litellm/__init__.py +7 -0
  253. autogen/interop/litellm/litellm_config_factory.py +113 -0
  254. autogen/interop/pydantic_ai/__init__.py +7 -0
  255. autogen/interop/pydantic_ai/pydantic_ai.py +168 -0
  256. autogen/interop/registry.py +69 -0
  257. autogen/io/__init__.py +15 -0
  258. autogen/io/base.py +151 -0
  259. autogen/io/console.py +56 -0
  260. autogen/io/processors/__init__.py +12 -0
  261. autogen/io/processors/base.py +21 -0
  262. autogen/io/processors/console_event_processor.py +56 -0
  263. autogen/io/run_response.py +293 -0
  264. autogen/io/thread_io_stream.py +63 -0
  265. autogen/io/websockets.py +213 -0
  266. autogen/json_utils.py +43 -0
  267. autogen/llm_config.py +379 -0
  268. autogen/logger/__init__.py +11 -0
  269. autogen/logger/base_logger.py +128 -0
  270. autogen/logger/file_logger.py +261 -0
  271. autogen/logger/logger_factory.py +42 -0
  272. autogen/logger/logger_utils.py +57 -0
  273. autogen/logger/sqlite_logger.py +523 -0
  274. autogen/math_utils.py +339 -0
  275. autogen/mcp/__init__.py +7 -0
  276. autogen/mcp/mcp_client.py +208 -0
  277. autogen/messages/__init__.py +7 -0
  278. autogen/messages/agent_messages.py +948 -0
  279. autogen/messages/base_message.py +107 -0
  280. autogen/messages/client_messages.py +171 -0
  281. autogen/messages/print_message.py +49 -0
  282. autogen/oai/__init__.py +53 -0
  283. autogen/oai/anthropic.py +714 -0
  284. autogen/oai/bedrock.py +628 -0
  285. autogen/oai/cerebras.py +299 -0
  286. autogen/oai/client.py +1435 -0
  287. autogen/oai/client_utils.py +169 -0
  288. autogen/oai/cohere.py +479 -0
  289. autogen/oai/gemini.py +990 -0
  290. autogen/oai/gemini_types.py +129 -0
  291. autogen/oai/groq.py +305 -0
  292. autogen/oai/mistral.py +303 -0
  293. autogen/oai/oai_models/__init__.py +11 -0
  294. autogen/oai/oai_models/_models.py +16 -0
  295. autogen/oai/oai_models/chat_completion.py +87 -0
  296. autogen/oai/oai_models/chat_completion_audio.py +32 -0
  297. autogen/oai/oai_models/chat_completion_message.py +86 -0
  298. autogen/oai/oai_models/chat_completion_message_tool_call.py +37 -0
  299. autogen/oai/oai_models/chat_completion_token_logprob.py +63 -0
  300. autogen/oai/oai_models/completion_usage.py +60 -0
  301. autogen/oai/ollama.py +643 -0
  302. autogen/oai/openai_utils.py +881 -0
  303. autogen/oai/together.py +370 -0
  304. autogen/retrieve_utils.py +491 -0
  305. autogen/runtime_logging.py +160 -0
  306. autogen/token_count_utils.py +267 -0
  307. autogen/tools/__init__.py +20 -0
  308. autogen/tools/contrib/__init__.py +9 -0
  309. autogen/tools/contrib/time/__init__.py +7 -0
  310. autogen/tools/contrib/time/time.py +41 -0
  311. autogen/tools/dependency_injection.py +254 -0
  312. autogen/tools/experimental/__init__.py +43 -0
  313. autogen/tools/experimental/browser_use/__init__.py +7 -0
  314. autogen/tools/experimental/browser_use/browser_use.py +161 -0
  315. autogen/tools/experimental/crawl4ai/__init__.py +7 -0
  316. autogen/tools/experimental/crawl4ai/crawl4ai.py +153 -0
  317. autogen/tools/experimental/deep_research/__init__.py +7 -0
  318. autogen/tools/experimental/deep_research/deep_research.py +328 -0
  319. autogen/tools/experimental/duckduckgo/__init__.py +7 -0
  320. autogen/tools/experimental/duckduckgo/duckduckgo_search.py +109 -0
  321. autogen/tools/experimental/google/__init__.py +14 -0
  322. autogen/tools/experimental/google/authentication/__init__.py +11 -0
  323. autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
  324. autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
  325. autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
  326. autogen/tools/experimental/google/drive/__init__.py +9 -0
  327. autogen/tools/experimental/google/drive/drive_functions.py +124 -0
  328. autogen/tools/experimental/google/drive/toolkit.py +88 -0
  329. autogen/tools/experimental/google/model.py +17 -0
  330. autogen/tools/experimental/google/toolkit_protocol.py +19 -0
  331. autogen/tools/experimental/google_search/__init__.py +8 -0
  332. autogen/tools/experimental/google_search/google_search.py +93 -0
  333. autogen/tools/experimental/google_search/youtube_search.py +181 -0
  334. autogen/tools/experimental/messageplatform/__init__.py +17 -0
  335. autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
  336. autogen/tools/experimental/messageplatform/discord/discord.py +288 -0
  337. autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
  338. autogen/tools/experimental/messageplatform/slack/slack.py +391 -0
  339. autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
  340. autogen/tools/experimental/messageplatform/telegram/telegram.py +275 -0
  341. autogen/tools/experimental/perplexity/__init__.py +7 -0
  342. autogen/tools/experimental/perplexity/perplexity_search.py +260 -0
  343. autogen/tools/experimental/tavily/__init__.py +7 -0
  344. autogen/tools/experimental/tavily/tavily_search.py +183 -0
  345. autogen/tools/experimental/web_search_preview/__init__.py +7 -0
  346. autogen/tools/experimental/web_search_preview/web_search_preview.py +114 -0
  347. autogen/tools/experimental/wikipedia/__init__.py +7 -0
  348. autogen/tools/experimental/wikipedia/wikipedia.py +287 -0
  349. autogen/tools/function_utils.py +411 -0
  350. autogen/tools/tool.py +187 -0
  351. autogen/tools/toolkit.py +86 -0
  352. autogen/types.py +29 -0
  353. autogen/version.py +7 -0
  354. ag2-0.9.1.dist-info/RECORD +0 -6
  355. ag2-0.9.1.dist-info/top_level.txt +0 -1
  356. {ag2-0.9.1.dist-info → ag2-0.9.1.post0.dist-info/licenses}/LICENSE +0 -0
  357. {ag2-0.9.1.dist-info → ag2-0.9.1.post0.dist-info/licenses}/NOTICE.md +0 -0
@@ -0,0 +1,109 @@
1
+ # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ from typing import Annotated, Any
5
+
6
+ from ....doc_utils import export_module
7
+ from ....import_utils import optional_import_block, require_optional_import
8
+ from ... import Tool
9
+
10
+ with optional_import_block():
11
+ from duckduckgo_search import DDGS
12
+
13
+
14
+ @require_optional_import(
15
+ [
16
+ "duckduckgo_search",
17
+ ],
18
+ "duckduckgo_search",
19
+ )
20
+ def _execute_duckduckgo_query(
21
+ query: str,
22
+ num_results: int = 5,
23
+ ) -> list[dict[str, Any]]:
24
+ """
25
+ Execute a search query using the DuckDuckGo Search API.
26
+
27
+ Args:
28
+ query (str): The search query string.
29
+ num_results (int, optional): The maximum number of results to return. Defaults to 5.
30
+
31
+ Returns:
32
+ list[dict[str, Any]]: A list of search results from the DuckDuckGo API.
33
+ """
34
+ with DDGS() as ddgs:
35
+ try:
36
+ # region='wt-wt' means worldwide
37
+ results = list(ddgs.text(query, region="wt-wt", max_results=num_results))
38
+ except Exception as e:
39
+ print(f"DuckDuckGo Search failed: {e}")
40
+ results = []
41
+ return results
42
+
43
+
44
+ def _duckduckgo_search(
45
+ query: str,
46
+ num_results: int = 5,
47
+ ) -> list[dict[str, Any]]:
48
+ """
49
+ Perform a DuckDuckGo search and format the results.
50
+
51
+ This function takes search parameters, executes the query using `_execute_duckduckgo_query`,
52
+ and formats the results into a list of dictionaries containing title, link, and snippet.
53
+
54
+ Args:
55
+ query (str): The search query string.
56
+ num_results (int, optional): The maximum number of results to return. Defaults to 5.
57
+
58
+ Returns:
59
+ list[dict[str, Any]]: A list of dictionaries, where each dictionary represents a search result
60
+ with keys 'title', 'link', and 'snippet'. Returns an empty list if no results are found.
61
+ """
62
+ res = _execute_duckduckgo_query(
63
+ query=query,
64
+ num_results=num_results,
65
+ )
66
+
67
+ return [
68
+ {"title": item.get("title", ""), "link": item.get("href", ""), "snippet": item.get("body", "")} for item in res
69
+ ]
70
+
71
+
72
+ @export_module("autogen.tools.experimental")
73
+ class DuckDuckGoSearchTool(Tool):
74
+ """
75
+ DuckDuckGoSearchTool is a tool that uses DuckDuckGo to perform a search.
76
+
77
+ This tool allows agents to leverage the DuckDuckGo search engine for information retrieval.
78
+ DuckDuckGo does not require an API key, making it easy to use.
79
+ """
80
+
81
+ def __init__(self) -> None:
82
+ """
83
+ Initializes the DuckDuckGoSearchTool.
84
+ """
85
+
86
+ def duckduckgo_search(
87
+ query: Annotated[str, "The search query."],
88
+ num_results: Annotated[int, "The number of results to return."] = 5,
89
+ ) -> list[dict[str, Any]]:
90
+ """
91
+ Performs a search using the DuckDuckGo Search API and returns formatted results.
92
+
93
+ Args:
94
+ query: The search query string.
95
+ num_results: The maximum number of results to return. Defaults to 5.
96
+
97
+ Returns:
98
+ A list of dictionaries, each containing 'title', 'link', and 'snippet' of a search result.
99
+ """
100
+ return _duckduckgo_search(
101
+ query=query,
102
+ num_results=num_results,
103
+ )
104
+
105
+ super().__init__(
106
+ name="duckduckgo_search",
107
+ description="Use the DuckDuckGo Search API to perform a search.",
108
+ func_or_tool=duckduckgo_search,
109
+ )
@@ -0,0 +1,14 @@
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 .authentication import GoogleCredentialsLocalProvider, GoogleCredentialsProvider
6
+ from .drive import GoogleDriveToolkit
7
+ from .toolkit_protocol import GoogleToolkitProtocol
8
+
9
+ __all__ = [
10
+ "GoogleCredentialsLocalProvider",
11
+ "GoogleCredentialsProvider",
12
+ "GoogleDriveToolkit",
13
+ "GoogleToolkitProtocol",
14
+ ]
@@ -0,0 +1,11 @@
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 .credentials_local_provider import GoogleCredentialsLocalProvider
6
+ from .credentials_provider import GoogleCredentialsProvider
7
+
8
+ __all__ = [
9
+ "GoogleCredentialsLocalProvider",
10
+ "GoogleCredentialsProvider",
11
+ ]
@@ -0,0 +1,43 @@
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 .....doc_utils import export_module
7
+ from .....import_utils import optional_import_block
8
+ from .credentials_provider import GoogleCredentialsProvider
9
+
10
+ with optional_import_block():
11
+ from google.oauth2.credentials import Credentials
12
+
13
+
14
+ __all__ = ["GoogleCredenentialsHostedProvider"]
15
+
16
+
17
+ @export_module("autogen.tools.experimental.google.authentication")
18
+ class GoogleCredenentialsHostedProvider(GoogleCredentialsProvider):
19
+ def __init__(
20
+ self,
21
+ host: str,
22
+ port: int = 8080,
23
+ *,
24
+ kwargs: dict[str, str],
25
+ ) -> None:
26
+ self._host = host
27
+ self._port = port
28
+ self._kwargs = kwargs
29
+
30
+ raise NotImplementedError("This class is not implemented yet.")
31
+
32
+ @property
33
+ def host(self) -> str:
34
+ """The host from which to get the credentials."""
35
+ return self._host
36
+
37
+ @property
38
+ def port(self) -> int:
39
+ """The port from which to get the credentials."""
40
+ return self._port
41
+
42
+ def get_credentials(self) -> "Credentials": # type: ignore[no-any-unimported]
43
+ raise NotImplementedError("This class is not implemented yet.")
@@ -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
+
6
+ import os
7
+ from typing import Optional
8
+
9
+ from .....doc_utils import export_module
10
+ from .....import_utils import optional_import_block, require_optional_import
11
+ from .credentials_provider import GoogleCredentialsProvider
12
+
13
+ with optional_import_block():
14
+ from google.auth.transport.requests import Request
15
+ from google.oauth2.credentials import Credentials
16
+ from google_auth_oauthlib.flow import InstalledAppFlow
17
+
18
+
19
+ __all__ = ["GoogleCredentialsLocalProvider"]
20
+
21
+
22
+ @export_module("autogen.tools.experimental.google.authentication")
23
+ class GoogleCredentialsLocalProvider(GoogleCredentialsProvider):
24
+ def __init__(
25
+ self,
26
+ client_secret_file: str,
27
+ scopes: list[str], # e.g. ['https://www.googleapis.com/auth/drive/readonly']
28
+ token_file: Optional[str] = None,
29
+ port: int = 8080,
30
+ ) -> None:
31
+ """A Google credentials provider that gets the credentials locally.
32
+
33
+ Args:
34
+ client_secret_file (str): The path to the client secret file.
35
+ scopes (list[str]): The scopes to request.
36
+ token_file (str): Optional path to the token file. If not provided, the token will not be saved.
37
+ port (int): The port from which to get the credentials.
38
+ """
39
+ self.client_secret_file = client_secret_file
40
+ self.scopes = scopes
41
+ self.token_file = token_file
42
+ self._port = port
43
+
44
+ @property
45
+ def host(self) -> str:
46
+ """Localhost is the default host."""
47
+ return "localhost"
48
+
49
+ @property
50
+ def port(self) -> int:
51
+ """The port from which to get the credentials."""
52
+ return self._port
53
+
54
+ @require_optional_import(
55
+ [
56
+ "google_auth_httplib2",
57
+ "google_auth_oauthlib",
58
+ ],
59
+ "google-api",
60
+ )
61
+ def _refresh_or_get_new_credentials(self, creds: Optional["Credentials"]) -> "Credentials": # type: ignore[no-any-unimported]
62
+ if creds and creds.expired and creds.refresh_token:
63
+ creds.refresh(Request()) # type: ignore[no-untyped-call]
64
+ else:
65
+ flow = InstalledAppFlow.from_client_secrets_file(self.client_secret_file, self.scopes)
66
+ creds = flow.run_local_server(host=self.host, port=self.port)
67
+ return creds # type: ignore[return-value]
68
+
69
+ @require_optional_import(
70
+ [
71
+ "google_auth_httplib2",
72
+ "google_auth_oauthlib",
73
+ ],
74
+ "google-api",
75
+ )
76
+ def get_credentials(self) -> "Credentials": # type: ignore[no-any-unimported]
77
+ """Get the Google credentials."""
78
+ creds = None
79
+ if self.token_file and os.path.exists(self.token_file):
80
+ creds = Credentials.from_authorized_user_file(self.token_file) # type: ignore[no-untyped-call]
81
+
82
+ # If there are no (valid) credentials available, let the user log in.
83
+ if not creds or not creds.valid:
84
+ creds = self._refresh_or_get_new_credentials(creds)
85
+
86
+ if self.token_file:
87
+ # Save the credentials for the next run
88
+ with open(self.token_file, "w") as token:
89
+ token.write(creds.to_json()) # type: ignore[no-untyped-call]
90
+
91
+ return creds # type: ignore[no-any-return]
@@ -0,0 +1,35 @@
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 Optional, Protocol, runtime_checkable
7
+
8
+ from .....doc_utils import export_module
9
+ from .....import_utils import optional_import_block
10
+
11
+ with optional_import_block():
12
+ from google.oauth2.credentials import Credentials
13
+
14
+
15
+ __all__ = ["GoogleCredentialsProvider"]
16
+
17
+
18
+ @runtime_checkable
19
+ @export_module("autogen.tools.experimental.google.authentication")
20
+ class GoogleCredentialsProvider(Protocol):
21
+ """A protocol for Google credentials provider."""
22
+
23
+ def get_credentials(self) -> Optional["Credentials"]: # type: ignore[no-any-unimported]
24
+ """Get the Google credentials."""
25
+ ...
26
+
27
+ @property
28
+ def host(self) -> str:
29
+ """The host from which to get the credentials."""
30
+ ...
31
+
32
+ @property
33
+ def port(self) -> int:
34
+ """The port from which to get the credentials."""
35
+ ...
@@ -0,0 +1,9 @@
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 .toolkit import GoogleDriveToolkit
6
+
7
+ __all__ = [
8
+ "GoogleDriveToolkit",
9
+ ]
@@ -0,0 +1,124 @@
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 io
6
+ from pathlib import Path
7
+ from typing import Any, Optional
8
+
9
+ from .....import_utils import optional_import_block, require_optional_import
10
+ from ..model import GoogleFileInfo
11
+
12
+ with optional_import_block():
13
+ from googleapiclient.http import MediaIoBaseDownload
14
+
15
+
16
+ __all__ = [
17
+ "download_file",
18
+ "list_files_and_folders",
19
+ ]
20
+
21
+
22
+ @require_optional_import(
23
+ [
24
+ "googleapiclient",
25
+ ],
26
+ "google-api",
27
+ )
28
+ def list_files_and_folders(service: Any, page_size: int, folder_id: Optional[str]) -> list[GoogleFileInfo]:
29
+ kwargs = {
30
+ "pageSize": page_size,
31
+ "fields": "nextPageToken, files(id, name, mimeType)",
32
+ }
33
+ if folder_id:
34
+ kwargs["q"] = f"'{folder_id}' in parents and trashed=false" # Search for files in the folder
35
+ response = service.files().list(**kwargs).execute()
36
+ result = response.get("files", [])
37
+ if not isinstance(result, list):
38
+ raise ValueError(f"Expected a list of files, but got {result}")
39
+ result = [GoogleFileInfo(**file_info) for file_info in result]
40
+ return result
41
+
42
+
43
+ def _get_file_extension(mime_type: str) -> Optional[str]:
44
+ """Returns the correct file extension for a given MIME type."""
45
+ mime_extensions = {
46
+ "application/vnd.google-apps.document": "docx", # Google Docs → Word
47
+ "application/vnd.google-apps.spreadsheet": "csv", # Google Sheets → CSV
48
+ "application/vnd.google-apps.presentation": "pptx", # Google Slides → PowerPoint
49
+ "video/quicktime": "mov",
50
+ "application/vnd.google.colaboratory": "ipynb",
51
+ "application/pdf": "pdf",
52
+ "image/jpeg": "jpg",
53
+ "image/png": "png",
54
+ "text/plain": "txt",
55
+ "application/zip": "zip",
56
+ }
57
+
58
+ return mime_extensions.get(mime_type)
59
+
60
+
61
+ @require_optional_import(
62
+ [
63
+ "googleapiclient",
64
+ ],
65
+ "google-api",
66
+ )
67
+ def download_file(
68
+ service: Any,
69
+ file_id: str,
70
+ file_name: str,
71
+ mime_type: str,
72
+ download_folder: Path,
73
+ subfolder_path: Optional[str] = None,
74
+ ) -> str:
75
+ """Download or export file based on its MIME type, optionally saving to a subfolder."""
76
+ file_extension = _get_file_extension(mime_type)
77
+ if file_extension and (not file_name.lower().endswith(file_extension.lower())):
78
+ file_name = f"{file_name}.{file_extension}"
79
+
80
+ # Define export formats for Google Docs, Sheets, and Slides
81
+ export_mime_types = {
82
+ "application/vnd.google-apps.document": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", # Google Docs → Word
83
+ "application/vnd.google-apps.spreadsheet": "text/csv", # Google Sheets → CSV
84
+ "application/vnd.google-apps.presentation": "application/vnd.openxmlformats-officedocument.presentationml.presentation", # Google Slides → PowerPoint
85
+ }
86
+
87
+ # Google Docs, Sheets, and Slides cannot be downloaded directly using service.files().get_media() because they are Google-native files
88
+ if mime_type in export_mime_types:
89
+ request = service.files().export(fileId=file_id, mimeType=export_mime_types[mime_type])
90
+ else:
91
+ # Download normal files (videos, images, etc.)
92
+ request = service.files().get_media(fileId=file_id)
93
+
94
+ # Determine the final destination directory
95
+ destination_dir = download_folder
96
+ if subfolder_path:
97
+ destination_dir = download_folder / subfolder_path
98
+ # Ensure the subfolder exists, create it if necessary
99
+ destination_dir.mkdir(parents=True, exist_ok=True)
100
+
101
+ # Construct the full path for the file
102
+ file_path = destination_dir / file_name
103
+
104
+ # Save file
105
+ try:
106
+ with io.BytesIO() as buffer:
107
+ downloader = MediaIoBaseDownload(buffer, request)
108
+ done = False
109
+ while not done:
110
+ _, done = downloader.next_chunk()
111
+
112
+ buffer.seek(0)
113
+
114
+ with open(file_path, "wb") as f:
115
+ f.write(buffer.getvalue())
116
+
117
+ # Print out the relative path of the downloaded file
118
+ relative_path = Path(subfolder_path) / file_name if subfolder_path else Path(file_name)
119
+ return f"✅ Downloaded: {relative_path}"
120
+
121
+ except Exception as e:
122
+ # Error message if unable to download
123
+ relative_path = Path(subfolder_path) / file_name if subfolder_path else Path(file_name)
124
+ return f"❌ FAILED to download {relative_path}: {e}"
@@ -0,0 +1,88 @@
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 pathlib import Path
6
+ from typing import Annotated, Literal, Optional, Union
7
+
8
+ from .....doc_utils import export_module
9
+ from .....import_utils import optional_import_block
10
+ from .... import Toolkit, tool
11
+ from ..model import GoogleFileInfo
12
+ from ..toolkit_protocol import GoogleToolkitProtocol
13
+ from .drive_functions import download_file, list_files_and_folders
14
+
15
+ with optional_import_block():
16
+ from google.oauth2.credentials import Credentials
17
+ from googleapiclient.discovery import build
18
+
19
+ __all__ = [
20
+ "GoogleDriveToolkit",
21
+ ]
22
+
23
+
24
+ @export_module("autogen.tools.experimental.google.drive")
25
+ class GoogleDriveToolkit(Toolkit, GoogleToolkitProtocol):
26
+ """A tool map for Google Drive."""
27
+
28
+ def __init__( # type: ignore[no-any-unimported]
29
+ self,
30
+ *,
31
+ credentials: "Credentials",
32
+ download_folder: Union[Path, str],
33
+ exclude: Optional[list[Literal["list_drive_files_and_folders", "download_file_from_drive"]]] = None,
34
+ api_version: str = "v3",
35
+ ) -> None:
36
+ """Initialize the Google Drive tool map.
37
+
38
+ Args:
39
+ credentials: The Google OAuth2 credentials.
40
+ download_folder: The folder to download files to.
41
+ exclude: The tool names to exclude.
42
+ api_version: The Google Drive API version to use."
43
+ """
44
+ self.service = build(serviceName="drive", version=api_version, credentials=credentials)
45
+
46
+ if isinstance(download_folder, str):
47
+ download_folder = Path(download_folder)
48
+ download_folder.mkdir(parents=True, exist_ok=True)
49
+
50
+ @tool(description="List files and folders in a Google Drive")
51
+ def list_drive_files_and_folders(
52
+ page_size: Annotated[int, "The number of files to list per page."] = 10,
53
+ folder_id: Annotated[
54
+ Optional[str],
55
+ "The ID of the folder to list files from. If not provided, lists all files in the root folder.",
56
+ ] = None,
57
+ ) -> list[GoogleFileInfo]:
58
+ return list_files_and_folders(service=self.service, page_size=page_size, folder_id=folder_id)
59
+
60
+ @tool(description="download a file from Google Drive")
61
+ def download_file_from_drive(
62
+ file_info: Annotated[GoogleFileInfo, "The file info to download."],
63
+ subfolder_path: Annotated[
64
+ Optional[str],
65
+ "The subfolder path to save the file in. If not provided, saves in the main download folder.",
66
+ ] = None,
67
+ ) -> str:
68
+ return download_file(
69
+ service=self.service,
70
+ file_id=file_info.id,
71
+ file_name=file_info.name,
72
+ mime_type=file_info.mime_type,
73
+ download_folder=download_folder,
74
+ subfolder_path=subfolder_path,
75
+ )
76
+
77
+ if exclude is None:
78
+ exclude = []
79
+
80
+ tools = [tool for tool in [list_drive_files_and_folders, download_file_from_drive] if tool.name not in exclude]
81
+ super().__init__(tools=tools)
82
+
83
+ @classmethod
84
+ def recommended_scopes(cls) -> list[str]:
85
+ """Return the recommended scopes manatory for using tools from this tool map."""
86
+ return [
87
+ "https://www.googleapis.com/auth/drive.readonly",
88
+ ]
@@ -0,0 +1,17 @@
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 Annotated
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+ __all__ = [
10
+ "GoogleFileInfo",
11
+ ]
12
+
13
+
14
+ class GoogleFileInfo(BaseModel):
15
+ name: Annotated[str, Field(description="The name of the file.")]
16
+ id: Annotated[str, Field(description="The ID of the file.")]
17
+ mime_type: Annotated[str, Field(alias="mimeType", description="The MIME type of the file.")]
@@ -0,0 +1,19 @@
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 Protocol, runtime_checkable
6
+
7
+ __all__ = [
8
+ "GoogleToolkitProtocol",
9
+ ]
10
+
11
+
12
+ @runtime_checkable
13
+ class GoogleToolkitProtocol(Protocol):
14
+ """A protocol for Google tool maps."""
15
+
16
+ @classmethod
17
+ def recommended_scopes(cls) -> list[str]:
18
+ """Defines a required static method without implementation."""
19
+ ...
@@ -0,0 +1,8 @@
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 .google_search import GoogleSearchTool
6
+ from .youtube_search import YoutubeSearchTool
7
+
8
+ __all__ = ["GoogleSearchTool", "YoutubeSearchTool"]
@@ -0,0 +1,93 @@
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
+ import logging
7
+ from typing import Annotated, Any, Optional
8
+
9
+ from ....doc_utils import export_module
10
+ from ....import_utils import optional_import_block, require_optional_import
11
+ from ... import Depends, Tool
12
+ from ...dependency_injection import on
13
+
14
+ with optional_import_block():
15
+ from googleapiclient.discovery import build
16
+
17
+
18
+ @require_optional_import(
19
+ [
20
+ "googleapiclient",
21
+ ],
22
+ "google-search",
23
+ )
24
+ def _execute_query(query: str, search_api_key: str, search_engine_id: str, num_results: int) -> Any:
25
+ service = build("customsearch", "v1", developerKey=search_api_key)
26
+ return service.cse().list(q=query, cx=search_engine_id, num=num_results).execute()
27
+
28
+
29
+ def _google_search(
30
+ query: str,
31
+ search_api_key: str,
32
+ search_engine_id: str,
33
+ num_results: int,
34
+ ) -> list[dict[str, Any]]:
35
+ res = _execute_query(
36
+ query=query, search_api_key=search_api_key, search_engine_id=search_engine_id, num_results=num_results
37
+ )
38
+
39
+ return [
40
+ {"title": item.get("title", ""), "link": item.get("link", ""), "snippet": item.get("snippet", "")}
41
+ for item in res.get("items", [])
42
+ ]
43
+
44
+
45
+ @export_module("autogen.tools.experimental")
46
+ class GoogleSearchTool(Tool):
47
+ """GoogleSearchTool is a tool that uses the Google Search API to perform a search."""
48
+
49
+ def __init__(
50
+ self,
51
+ *,
52
+ search_api_key: Optional[str] = None,
53
+ search_engine_id: Optional[str] = None,
54
+ use_internal_llm_tool_if_available: bool = True,
55
+ ):
56
+ """GoogleSearchTool is a tool that uses the Google Search API to perform a search.
57
+
58
+ Args:
59
+ search_api_key: The API key for the Google Search API.
60
+ search_engine_id: The search engine ID for the Google Search API.
61
+ use_internal_llm_tool_if_available: Whether to use the predefined (e.g. Gemini GenaAI) search tool. Currently, this can only be used for agents with the Gemini (GenAI) configuration.
62
+ """
63
+ self.search_api_key = search_api_key
64
+ self.search_engine_id = search_engine_id
65
+ self.use_internal_llm_tool_if_available = use_internal_llm_tool_if_available
66
+
67
+ if not use_internal_llm_tool_if_available and (search_api_key is None or search_engine_id is None):
68
+ raise ValueError(
69
+ "search_api_key and search_engine_id must be provided if use_internal_llm_tool_if_available is False"
70
+ )
71
+
72
+ if use_internal_llm_tool_if_available and (search_api_key is not None or search_engine_id is not None):
73
+ logging.warning("search_api_key and search_engine_id will be ignored if internal LLM tool is available")
74
+
75
+ def google_search(
76
+ query: Annotated[str, "The search query."],
77
+ search_api_key: Annotated[Optional[str], Depends(on(search_api_key))],
78
+ search_engine_id: Annotated[Optional[str], Depends(on(search_engine_id))],
79
+ num_results: Annotated[int, "The number of results to return."] = 10,
80
+ ) -> list[dict[str, Any]]:
81
+ if search_api_key is None or search_engine_id is None:
82
+ raise ValueError(
83
+ "Your LLM is not configured to use prebuilt google-search tool.\n"
84
+ "Please provide search_api_key and search_engine_id.\n"
85
+ )
86
+ return _google_search(query, search_api_key, search_engine_id, num_results)
87
+
88
+ super().__init__(
89
+ # GeminiClient will look for a tool with the name "prebuilt_google_search"
90
+ name="prebuilt_google_search" if use_internal_llm_tool_if_available else "google_search",
91
+ description="Use the Google Search API to perform a search.",
92
+ func_or_tool=google_search,
93
+ )