ag2 0.9.1a1__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.1a1.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.1a1.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.1a1.dist-info/RECORD +0 -6
  355. ag2-0.9.1a1.dist-info/top_level.txt +0 -1
  356. {ag2-0.9.1a1.dist-info → ag2-0.9.1.post0.dist-info/licenses}/LICENSE +0 -0
  357. {ag2-0.9.1a1.dist-info → ag2-0.9.1.post0.dist-info/licenses}/NOTICE.md +0 -0
@@ -0,0 +1,7 @@
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 .slack import SlackAgent
6
+
7
+ __all__ = ["SlackAgent"]
@@ -0,0 +1,73 @@
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, Optional
6
+
7
+ from .... import ConversableAgent
8
+ from ....doc_utils import export_module
9
+ from ....tools.experimental import SlackRetrieveRepliesTool, SlackRetrieveTool, SlackSendTool
10
+
11
+ __all__ = ["SlackAgent"]
12
+
13
+
14
+ @export_module("autogen.agents.experimental")
15
+ class SlackAgent(ConversableAgent):
16
+ """An agent that can send messages and retrieve messages on Slack."""
17
+
18
+ DEFAULT_SYSTEM_MESSAGE = (
19
+ "You are a helpful AI assistant that communicates through Slack. "
20
+ "Remember that Slack uses Markdown-like formatting and has message length limits. "
21
+ "Keep messages clear and concise, and consider using appropriate formatting when helpful."
22
+ )
23
+
24
+ def __init__(
25
+ self,
26
+ name: str,
27
+ system_message: Optional[str] = None,
28
+ *,
29
+ bot_token: str,
30
+ channel_id: str,
31
+ has_writing_instructions: bool = True,
32
+ **kwargs: Any,
33
+ ) -> None:
34
+ """Initialize the SlackAgent.
35
+
36
+ Args:
37
+ name: name of the agent.
38
+ system_message: system message for the ChatCompletion inference.
39
+ bot_token: Bot User OAuth Token starting with "xoxb-".
40
+ channel_id: Channel ID where messages will be sent.
41
+ has_writing_instructions: Whether to add writing instructions to the system message. Defaults to True.
42
+ **kwargs: Additional keyword arguments passed to the parent ConversableAgent class.
43
+ """
44
+ slack_system_message = system_message or self.DEFAULT_SYSTEM_MESSAGE
45
+
46
+ self._send_tool = SlackSendTool(bot_token=bot_token, channel_id=channel_id)
47
+ self._retrieve_tool = SlackRetrieveTool(bot_token=bot_token, channel_id=channel_id)
48
+ self._retrieve_replies_tool = SlackRetrieveRepliesTool(bot_token=bot_token, channel_id=channel_id)
49
+
50
+ # Add formatting instructions
51
+ if has_writing_instructions:
52
+ formatting_instructions = (
53
+ "\nFormat guidelines for Slack:\n"
54
+ "Format guidelines for Slack:\n"
55
+ "1. Max message length: 40,000 characters\n"
56
+ "2. Supports Markdown-like formatting:\n"
57
+ " - *text* for italic\n"
58
+ " - **text** for bold\n"
59
+ " - `code` for inline code\n"
60
+ " - ```code block``` for multi-line code\n"
61
+ "3. Supports message threading for organized discussions\n"
62
+ "4. Can use :emoji_name: for emoji reactions\n"
63
+ "5. Supports block quotes with > prefix\n"
64
+ "6. Can use <!here> or <!channel> for notifications"
65
+ )
66
+
67
+ slack_system_message = slack_system_message + formatting_instructions
68
+
69
+ super().__init__(name=name, system_message=slack_system_message, **kwargs)
70
+
71
+ self.register_for_llm()(self._send_tool)
72
+ self.register_for_llm()(self._retrieve_tool)
73
+ self.register_for_llm()(self._retrieve_replies_tool)
@@ -0,0 +1,7 @@
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 .telegram import TelegramAgent
6
+
7
+ __all__ = ["TelegramAgent"]
@@ -0,0 +1,77 @@
1
+ # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from typing import Any, Optional
6
+
7
+ from .... import ConversableAgent
8
+ from ....doc_utils import export_module
9
+ from ....tools.experimental import TelegramRetrieveTool, TelegramSendTool
10
+
11
+ __all__ = ["TelegramAgent"]
12
+
13
+
14
+ @export_module("autogen.agents.experimental")
15
+ class TelegramAgent(ConversableAgent):
16
+ """An agent that can send messages and retrieve messages on Telegram."""
17
+
18
+ DEFAULT_SYSTEM_MESSAGE = (
19
+ "You are a helpful AI assistant that communicates through Telegram. "
20
+ "Remember that Telegram uses Markdown-like formatting and has message length limits. "
21
+ "Keep messages clear and concise, and consider using appropriate formatting when helpful."
22
+ )
23
+
24
+ def __init__(
25
+ self,
26
+ name: str,
27
+ system_message: Optional[str] = None,
28
+ *,
29
+ api_id: str,
30
+ api_hash: str,
31
+ chat_id: str,
32
+ has_writing_instructions: bool = True,
33
+ **kwargs: Any,
34
+ ) -> None:
35
+ """Initialize the TelegramAgent.
36
+
37
+ Args:
38
+ name: The name of the agent.
39
+ system_message: The system message for the agent.
40
+ api_id: Telegram API ID from https://my.telegram.org/apps.
41
+ api_hash: Telegram API hash from https://my.telegram.org/apps.
42
+ chat_id: The ID of the destination (Channel, Group, or User ID).
43
+ has_writing_instructions (bool): Whether to add writing instructions to the system message. Defaults to True.
44
+ **kwargs: Additional keyword arguments passed to the parent ConversableAgent class.
45
+ """
46
+
47
+ telegram_system_message = system_message or self.DEFAULT_SYSTEM_MESSAGE
48
+
49
+ self._send_tool = TelegramSendTool(api_id=api_id, api_hash=api_hash, chat_id=chat_id)
50
+ self._retrieve_tool = TelegramRetrieveTool(api_id=api_id, api_hash=api_hash, chat_id=chat_id)
51
+
52
+ # Add formatting instructions
53
+ if has_writing_instructions:
54
+ formatting_instructions = (
55
+ "\nFormat guidelines for Telegram:\n"
56
+ "1. Max message length: 4096 characters\n"
57
+ "2. HTML formatting:\n"
58
+ " - <b>bold</b>\n"
59
+ " - <i>italic</i>\n"
60
+ " - <code>code</code>\n"
61
+ " - <pre>code block</pre>\n"
62
+ " - <a href='URL'>link</a>\n"
63
+ " - <u>underline</u>\n"
64
+ " - <s>strikethrough</s>\n"
65
+ "3. HTML rules:\n"
66
+ " - Tags must be properly closed\n"
67
+ " - Can't nest identical tags\n"
68
+ " - Links require full URLs (with http://)\n"
69
+ "4. Supports @mentions and emoji"
70
+ )
71
+
72
+ telegram_system_message = telegram_system_message + formatting_instructions
73
+
74
+ super().__init__(name=name, system_message=telegram_system_message, **kwargs)
75
+
76
+ self.register_for_llm()(self._send_tool)
77
+ self.register_for_llm()(self._retrieve_tool)
@@ -0,0 +1,7 @@
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 .websurfer import WebSurferAgent
6
+
7
+ __all__ = ["WebSurferAgent"]
@@ -0,0 +1,62 @@
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, Literal, Optional, Union
6
+
7
+ from .... import ConversableAgent
8
+ from ....doc_utils import export_module
9
+ from ....llm_config import LLMConfig
10
+ from ....tools import Tool
11
+ from ....tools.experimental import (
12
+ BrowserUseTool,
13
+ Crawl4AITool,
14
+ DuckDuckGoSearchTool,
15
+ PerplexitySearchTool,
16
+ TavilySearchTool,
17
+ )
18
+
19
+ __all__ = ["WebSurferAgent"]
20
+
21
+
22
+ @export_module("autogen.agents.experimental")
23
+ class WebSurferAgent(ConversableAgent):
24
+ """An agent that uses web tools to interact with the web."""
25
+
26
+ def __init__(
27
+ self,
28
+ *,
29
+ llm_config: Optional[Union[LLMConfig, dict[str, Any]]] = None,
30
+ web_tool_llm_config: Optional[Union[LLMConfig, dict[str, Any]]] = None,
31
+ web_tool: Literal["browser_use", "crawl4ai", "duckduckgo", "perplexity", "tavily"] = "browser_use",
32
+ web_tool_kwargs: Optional[dict[str, Any]] = None,
33
+ **kwargs: Any,
34
+ ) -> None:
35
+ """Initialize the WebSurferAgent.
36
+
37
+ Args:
38
+ llm_config: The LLM configuration.
39
+ web_tool_llm_config: The LLM configuration for the web tool. If not provided, the llm_config will be used.
40
+ web_tool: The web tool to use. Defaults to "browser_use".
41
+ web_tool_kwargs: The keyword arguments for the web tool. Defaults to None.
42
+ **kwargs: Additional keyword arguments passed to the parent ConversableAgent class.
43
+ """
44
+ llm_config = LLMConfig.get_current_llm_config(llm_config) # type: ignore[arg-type]
45
+ web_tool_kwargs = web_tool_kwargs if web_tool_kwargs else {}
46
+ web_tool_llm_config = web_tool_llm_config if web_tool_llm_config else llm_config
47
+ if web_tool == "browser_use":
48
+ self.tool: Tool = BrowserUseTool(llm_config=web_tool_llm_config, **web_tool_kwargs) # type: ignore[arg-type]
49
+ elif web_tool == "crawl4ai":
50
+ self.tool = Crawl4AITool(llm_config=web_tool_llm_config, **web_tool_kwargs)
51
+ elif web_tool == "perplexity":
52
+ self.tool = PerplexitySearchTool(**web_tool_kwargs)
53
+ elif web_tool == "tavily":
54
+ self.tool = TavilySearchTool(llm_config=web_tool_llm_config, **web_tool_kwargs)
55
+ elif web_tool == "duckduckgo":
56
+ self.tool = DuckDuckGoSearchTool(**web_tool_kwargs)
57
+ else:
58
+ raise ValueError(f"Unsupported {web_tool=}.")
59
+
60
+ super().__init__(llm_config=llm_config, **kwargs)
61
+
62
+ self.register_for_llm()(self.tool)
@@ -0,0 +1,7 @@
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 .wikipedia import WikipediaAgent
6
+
7
+ __all__ = ["WikipediaAgent"]
@@ -0,0 +1,90 @@
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, List, Optional, Union
6
+
7
+ from .... import ConversableAgent
8
+ from ....doc_utils import export_module
9
+ from ....tools.experimental import WikipediaPageLoadTool, WikipediaQueryRunTool
10
+
11
+
12
+ @export_module("autogen.agents.experimental")
13
+ class WikipediaAgent(ConversableAgent):
14
+ """
15
+ An AI agent that leverages Wikipedia tools to provide accurate, concise answers
16
+ to user queries.
17
+
18
+ Tools:
19
+ - WikipediaQueryRunTool: searches Wikipedia for relevant article titles.
20
+ - WikipediaPageLoadTool: loads full Wikipedia pages (and metadata) for in‑depth content.
21
+
22
+ Attributes:
23
+ _query_run_tool (WikipediaQueryRunTool): for running title/keyword searches.
24
+ _page_load_tool (WikipediaPageLoadTool): for fetching full page content.
25
+
26
+ Parameters:
27
+ system_message (Optional[Union[str, List[str]]]):
28
+ Custom system prompt(s). If None, DEFAULT_SYSTEM_MESSAGE is used.
29
+ Must be a str or a list of strings, otherwise raises ValueError.
30
+ format_instructions (Optional[str]): Extra formatting instructions to append.
31
+ language (str): ISO code for the Wikipedia language edition (default: "en").
32
+ top_k (int): Number of top search results to return (default: 2).
33
+ **kwargs: Passed through to the base ConversableAgent.
34
+
35
+ Raises:
36
+ ValueError: If `system_message` is not a str or list of str.
37
+ """
38
+
39
+ DEFAULT_SYSTEM_MESSAGE = (
40
+ "You are a knowledgeable AI assistant with access to Wikipedia.\n"
41
+ "Use your tools when necessary. Respond to user queries by providing accurate and concise information.\n"
42
+ "If a question requires external data, utilize the appropriate tool to retrieve it."
43
+ )
44
+
45
+ def __init__(
46
+ self,
47
+ system_message: Optional[Union[str, List[str]]] = None,
48
+ format_instructions: Optional[str] = None,
49
+ language: str = "en",
50
+ top_k: int = 2,
51
+ **kwargs: Any,
52
+ ) -> None:
53
+ """
54
+ Initialize the WikipediaAgent with optional custom prompts and tools.
55
+
56
+ Args:
57
+ system_message (Optional[Union[str, List[str]]]):
58
+ Custom system prompt(s). If None, DEFAULT_SYSTEM_MESSAGE is used.
59
+ Must be a str or list of strings.
60
+ format_instructions (Optional[str]): Extra formatting instructions to append.
61
+ language (str): Wikipedia language code (default: "en").
62
+ top_k (int): How many top search results to fetch (default: 2).
63
+ **kwargs: Other parameters for ConversableAgent.
64
+
65
+ Raises:
66
+ ValueError: If `system_message` is not a str or list of str.
67
+ """
68
+ # Use explicit system_message or fall back to default
69
+ system_message = system_message or self.DEFAULT_SYSTEM_MESSAGE
70
+
71
+ # Append formatting instructions if provided
72
+ if format_instructions is not None:
73
+ instructions = f"\n\nFollow this format:\n\n{format_instructions}"
74
+ if isinstance(system_message, list):
75
+ system_message.append(instructions)
76
+ elif isinstance(system_message, str):
77
+ system_message = system_message + instructions
78
+ else:
79
+ raise ValueError(f"system_message must be str or list[str], got {type(system_message).__name__}")
80
+
81
+ # Initialize Wikipedia tools
82
+ self._query_run_tool = WikipediaQueryRunTool(language=language, top_k=top_k)
83
+ self._page_load_tool = WikipediaPageLoadTool(language=language, top_k=top_k)
84
+
85
+ # Initialize the base ConversableAgent
86
+ super().__init__(system_message=system_message, **kwargs)
87
+
88
+ # Register tools for LLM recommendations
89
+ self.register_for_llm()(self._query_run_tool)
90
+ self.register_for_llm()(self._page_load_tool)
@@ -0,0 +1,309 @@
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 io
8
+ import mimetypes
9
+ import os
10
+ import re
11
+ import uuid
12
+ from contextlib import suppress
13
+ from typing import Any, Optional, Union
14
+ from urllib.parse import urljoin, urlparse
15
+
16
+ from .import_utils import optional_import_block, require_optional_import
17
+
18
+ with optional_import_block():
19
+ import markdownify
20
+ import requests
21
+ from bs4 import BeautifulSoup
22
+
23
+ # Optional PDF support
24
+ with optional_import_block() as result:
25
+ import pdfminer
26
+ import pdfminer.high_level
27
+
28
+ IS_PDF_CAPABLE = result.is_successful
29
+
30
+ # Other optional dependencies
31
+ with optional_import_block():
32
+ import pathvalidate
33
+
34
+
35
+ @require_optional_import(["markdownify", "requests", "bs4", "pdfminer", "pathvalidate"], "websurfer")
36
+ class SimpleTextBrowser:
37
+ """(In preview) An extremely simple text-based web browser comparable to Lynx. Suitable for Agentic use."""
38
+
39
+ def __init__(
40
+ self,
41
+ start_page: Optional[str] = None,
42
+ viewport_size: Optional[int] = 1024 * 8,
43
+ downloads_folder: Optional[Union[str, None]] = None,
44
+ bing_base_url: str = "https://api.bing.microsoft.com/v7.0/search",
45
+ bing_api_key: Optional[Union[str, None]] = None,
46
+ request_kwargs: Optional[Union[dict[str, Any], None]] = None,
47
+ ):
48
+ """Initialize the browser with the given parameters.
49
+
50
+ Args:
51
+ start_page (Optional[str], optional): The initial page to load. Defaults to None.
52
+ viewport_size (Optional[int], optional): The number of characters to display per page. Defaults to 1024 * 8.
53
+ downloads_folder (Optional[Union[str, None]], optional): The folder to save downloads to. Defaults to None.
54
+ bing_base_url (str, optional): The base URL for Bing searches. Defaults to "https://api.bing.microsoft.com/v7.0/search".
55
+ bing_api_key (Optional[Union[str, None]], optional): The API key for Bing searches. Defaults to None.
56
+ request_kwargs (Optional[Union[dict[str, Any], None]], optional): Additional keyword arguments to pass to the requests library. Defaults to None.
57
+ """
58
+ self.start_page: str = start_page if start_page else "about:blank"
59
+ self.viewport_size = viewport_size # Applies only to the standard uri types
60
+ self.downloads_folder = downloads_folder
61
+ self.history: list[str] = list()
62
+ self.page_title: Optional[str] = None
63
+ self.viewport_current_page = 0
64
+ self.viewport_pages: list[tuple[int, int]] = list()
65
+ self.set_address(self.start_page)
66
+ self.bing_base_url = bing_base_url
67
+ self.bing_api_key = bing_api_key
68
+ self.request_kwargs = request_kwargs
69
+
70
+ self._page_content = ""
71
+
72
+ @property
73
+ def address(self) -> str:
74
+ """Return the address of the current page."""
75
+ return self.history[-1]
76
+
77
+ def set_address(self, uri_or_path: str) -> None:
78
+ """Set the address of the current page.
79
+
80
+ Args:
81
+ uri_or_path (str): The URI or path to set as the current page.
82
+ """
83
+ self.history.append(uri_or_path)
84
+
85
+ # Handle special URIs
86
+ if uri_or_path == "about:blank":
87
+ self._set_page_content("")
88
+ elif uri_or_path.startswith("bing:"):
89
+ self._bing_search(uri_or_path[len("bing:") :].strip())
90
+ else:
91
+ if not uri_or_path.startswith("http:") and not uri_or_path.startswith("https:"):
92
+ uri_or_path = urljoin(self.address, uri_or_path)
93
+ self.history[-1] = uri_or_path # Update the address with the fully-qualified path
94
+ self._fetch_page(uri_or_path)
95
+
96
+ self.viewport_current_page = 0
97
+
98
+ @property
99
+ def viewport(self) -> str:
100
+ """Return the content of the current viewport."""
101
+ bounds = self.viewport_pages[self.viewport_current_page]
102
+ return self.page_content[bounds[0] : bounds[1]]
103
+
104
+ @property
105
+ def page_content(self) -> str:
106
+ """Return the full contents of the current page."""
107
+ return self._page_content
108
+
109
+ def _set_page_content(self, content: str) -> None:
110
+ """Sets the text content of the current page."""
111
+ self._page_content = content
112
+ self._split_pages()
113
+ if self.viewport_current_page >= len(self.viewport_pages):
114
+ self.viewport_current_page = len(self.viewport_pages) - 1
115
+
116
+ def page_down(self) -> None:
117
+ """Move the viewport down by one page."""
118
+ self.viewport_current_page = min(self.viewport_current_page + 1, len(self.viewport_pages) - 1)
119
+
120
+ def page_up(self) -> None:
121
+ """Move the viewport up by one page."""
122
+ self.viewport_current_page = max(self.viewport_current_page - 1, 0)
123
+
124
+ def visit_page(self, path_or_uri: str) -> str:
125
+ """Update the address, visit the page, and return the content of the viewport.
126
+
127
+ Args:
128
+ path_or_uri (str): The URI or path to visit.
129
+ """
130
+ self.set_address(path_or_uri)
131
+ return self.viewport
132
+
133
+ def _split_pages(self) -> None:
134
+ # Split only regular pages
135
+ if not self.address.startswith("http:") and not self.address.startswith("https:"):
136
+ self.viewport_pages = [(0, len(self._page_content))]
137
+ return
138
+
139
+ # Handle empty pages
140
+ if len(self._page_content) == 0:
141
+ self.viewport_pages = [(0, 0)]
142
+ return
143
+
144
+ # Break the viewport into pages
145
+ self.viewport_pages = []
146
+ start_idx = 0
147
+ while start_idx < len(self._page_content):
148
+ end_idx = min(start_idx + self.viewport_size, len(self._page_content)) # type: ignore[operator]
149
+ # Adjust to end on a space
150
+ while end_idx < len(self._page_content) and self._page_content[end_idx - 1] not in [" ", "\t", "\r", "\n"]:
151
+ end_idx += 1
152
+ self.viewport_pages.append((start_idx, end_idx))
153
+ start_idx = end_idx
154
+
155
+ def _bing_api_call(self, query: str) -> dict[str, dict[str, list[dict[str, Union[str, dict[str, str]]]]]]:
156
+ # Make sure the key was set
157
+ if self.bing_api_key is None:
158
+ raise ValueError("Missing Bing API key.")
159
+
160
+ # Prepare the request parameters
161
+ request_kwargs = self.request_kwargs.copy() if self.request_kwargs is not None else {}
162
+
163
+ if "headers" not in request_kwargs:
164
+ request_kwargs["headers"] = {}
165
+ request_kwargs["headers"]["Ocp-Apim-Subscription-Key"] = self.bing_api_key
166
+
167
+ if "params" not in request_kwargs:
168
+ request_kwargs["params"] = {}
169
+ request_kwargs["params"]["q"] = query
170
+ request_kwargs["params"]["textDecorations"] = False
171
+ request_kwargs["params"]["textFormat"] = "raw"
172
+
173
+ request_kwargs["stream"] = False
174
+
175
+ # Make the request
176
+ response = requests.get(self.bing_base_url, **request_kwargs)
177
+ response.raise_for_status()
178
+ results = response.json()
179
+
180
+ return results # type: ignore[no-any-return]
181
+
182
+ def _bing_search(self, query: str) -> None:
183
+ results = self._bing_api_call(query)
184
+
185
+ web_snippets: list[str] = list()
186
+ idx = 0
187
+ for page in results["webPages"]["value"]:
188
+ idx += 1
189
+ web_snippets.append(f"{idx}. [{page['name']}]({page['url']})\n{page['snippet']}")
190
+ if "deepLinks" in page:
191
+ for dl in page["deepLinks"]:
192
+ idx += 1
193
+ web_snippets.append(
194
+ f"{idx}. [{dl['name']}]({dl['url']})\n{dl.get('snippet', '')}" # type: ignore[index]
195
+ )
196
+
197
+ news_snippets = list()
198
+ if "news" in results:
199
+ for page in results["news"]["value"]:
200
+ idx += 1
201
+ news_snippets.append(f"{idx}. [{page['name']}]({page['url']})\n{page['description']}")
202
+
203
+ self.page_title = f"{query} - Search"
204
+
205
+ content = (
206
+ f"A Bing search for '{query}' found {len(web_snippets) + len(news_snippets)} results:\n\n## Web Results\n"
207
+ + "\n\n".join(web_snippets)
208
+ )
209
+ if len(news_snippets) > 0:
210
+ content += "\n\n## News Results:\n" + "\n\n".join(news_snippets)
211
+ self._set_page_content(content)
212
+
213
+ def _fetch_page(self, url: str) -> None:
214
+ try:
215
+ # Prepare the request parameters
216
+ request_kwargs = self.request_kwargs.copy() if self.request_kwargs is not None else {}
217
+ request_kwargs["stream"] = True
218
+
219
+ # Send a HTTP request to the URL
220
+ response = requests.get(url, **request_kwargs)
221
+ response.raise_for_status()
222
+
223
+ # If the HTTP request returns a status code 200, proceed
224
+ if response.status_code == 200:
225
+ content_type = response.headers.get("content-type", "")
226
+ for ct in ["text/html", "text/plain", "application/pdf"]:
227
+ if ct in content_type.lower():
228
+ content_type = ct
229
+ break
230
+
231
+ if content_type == "text/html":
232
+ # Get the content of the response
233
+ html = ""
234
+ for chunk in response.iter_content(chunk_size=512, decode_unicode=True):
235
+ html += chunk
236
+
237
+ soup = BeautifulSoup(html, "html.parser")
238
+
239
+ # Remove javascript and style blocks
240
+ for script in soup(["script", "style"]):
241
+ script.extract()
242
+
243
+ # Convert to markdown -- Wikipedia gets special attention to get a clean version of the page
244
+ if url.startswith("https://en.wikipedia.org/"):
245
+ body_elm = soup.find("div", {"id": "mw-content-text"})
246
+ title_elm = soup.find("span", {"class": "mw-page-title-main"})
247
+
248
+ if body_elm:
249
+ # What's the title
250
+ main_title = soup.title.string
251
+ if title_elm and len(title_elm) > 0:
252
+ main_title = title_elm.string
253
+ webpage_text = (
254
+ "# " + main_title + "\n\n" + markdownify.MarkdownConverter().convert_soup(body_elm)
255
+ )
256
+ else:
257
+ webpage_text = markdownify.MarkdownConverter().convert_soup(soup)
258
+ else:
259
+ webpage_text = markdownify.MarkdownConverter().convert_soup(soup)
260
+
261
+ # Convert newlines
262
+ webpage_text = re.sub(r"\r\n", "\n", webpage_text)
263
+
264
+ # Remove excessive blank lines
265
+ self.page_title = soup.title.string
266
+ self._set_page_content(re.sub(r"\n{2,}", "\n\n", webpage_text).strip())
267
+ elif content_type == "text/plain":
268
+ # Get the content of the response
269
+ plain_text = ""
270
+ for chunk in response.iter_content(chunk_size=512, decode_unicode=True):
271
+ plain_text += chunk
272
+
273
+ self.page_title = None
274
+ self._set_page_content(plain_text)
275
+ elif IS_PDF_CAPABLE and content_type == "application/pdf":
276
+ pdf_data = io.BytesIO(response.raw.read())
277
+ self.page_title = None
278
+ self._set_page_content(pdfminer.high_level.extract_text(pdf_data))
279
+ elif self.downloads_folder is not None:
280
+ # Try producing a safe filename
281
+ fname = None
282
+ with suppress(NameError):
283
+ fname = pathvalidate.sanitize_filename(os.path.basename(urlparse(url).path)).strip()
284
+
285
+ # No suitable name, so make one
286
+ if fname is None:
287
+ extension = mimetypes.guess_extension(content_type)
288
+ if extension is None:
289
+ extension = ".download"
290
+ fname = str(uuid.uuid4()) + extension
291
+
292
+ # Open a file for writing
293
+ download_path = os.path.abspath(os.path.join(self.downloads_folder, fname))
294
+ with open(download_path, "wb") as fh:
295
+ for chunk in response.iter_content(chunk_size=512):
296
+ fh.write(chunk)
297
+
298
+ # Return a page describing what just happened
299
+ self.page_title = "Download complete."
300
+ self._set_page_content(f"Downloaded '{url}' to '{download_path}'.")
301
+ else:
302
+ self.page_title = f"Error - Unsupported Content-Type '{content_type}'"
303
+ self._set_page_content(self.page_title)
304
+ else:
305
+ self.page_title = "Error"
306
+ self._set_page_content("Failed to retrieve " + url)
307
+ except requests.exceptions.RequestException as e:
308
+ self.page_title = "Error"
309
+ self._set_page_content(str(e))
@@ -0,0 +1,10 @@
1
+ # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ #
5
+ # Portions derived from https://github.com/microsoft/autogen are under the MIT License.
6
+ # SPDX-License-Identifier: MIT
7
+ from .abstract_cache_base import AbstractCache
8
+ from .cache import Cache
9
+
10
+ __all__ = ["AbstractCache", "Cache"]