ag2 0.10.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. ag2-0.10.2.dist-info/METADATA +819 -0
  2. ag2-0.10.2.dist-info/RECORD +423 -0
  3. ag2-0.10.2.dist-info/WHEEL +4 -0
  4. ag2-0.10.2.dist-info/licenses/LICENSE +201 -0
  5. ag2-0.10.2.dist-info/licenses/NOTICE.md +19 -0
  6. autogen/__init__.py +88 -0
  7. autogen/_website/__init__.py +3 -0
  8. autogen/_website/generate_api_references.py +426 -0
  9. autogen/_website/generate_mkdocs.py +1216 -0
  10. autogen/_website/notebook_processor.py +475 -0
  11. autogen/_website/process_notebooks.py +656 -0
  12. autogen/_website/utils.py +413 -0
  13. autogen/a2a/__init__.py +36 -0
  14. autogen/a2a/agent_executor.py +86 -0
  15. autogen/a2a/client.py +357 -0
  16. autogen/a2a/errors.py +18 -0
  17. autogen/a2a/httpx_client_factory.py +79 -0
  18. autogen/a2a/server.py +221 -0
  19. autogen/a2a/utils.py +207 -0
  20. autogen/agentchat/__init__.py +47 -0
  21. autogen/agentchat/agent.py +180 -0
  22. autogen/agentchat/assistant_agent.py +86 -0
  23. autogen/agentchat/chat.py +325 -0
  24. autogen/agentchat/contrib/__init__.py +5 -0
  25. autogen/agentchat/contrib/agent_eval/README.md +7 -0
  26. autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
  27. autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
  28. autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
  29. autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
  30. autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
  31. autogen/agentchat/contrib/agent_eval/task.py +42 -0
  32. autogen/agentchat/contrib/agent_optimizer.py +432 -0
  33. autogen/agentchat/contrib/capabilities/__init__.py +5 -0
  34. autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
  35. autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
  36. autogen/agentchat/contrib/capabilities/teachability.py +393 -0
  37. autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
  38. autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
  39. autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
  40. autogen/agentchat/contrib/capabilities/transforms.py +578 -0
  41. autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
  42. autogen/agentchat/contrib/capabilities/vision_capability.py +215 -0
  43. autogen/agentchat/contrib/captainagent/__init__.py +9 -0
  44. autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
  45. autogen/agentchat/contrib/captainagent/captainagent.py +514 -0
  46. autogen/agentchat/contrib/captainagent/tool_retriever.py +334 -0
  47. autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
  48. autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
  49. autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
  50. autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
  51. autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
  52. autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
  53. autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
  54. autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
  55. autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
  56. autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
  57. autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
  58. autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
  59. autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
  60. autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
  61. autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
  62. autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
  63. autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
  64. autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
  65. autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
  66. autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
  67. autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
  68. autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
  69. autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
  70. autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
  71. autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
  72. autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
  73. autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
  74. autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
  75. autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
  76. autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
  77. autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
  78. autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
  79. autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
  80. autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
  81. autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
  82. autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
  83. autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
  84. autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
  85. autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
  86. autogen/agentchat/contrib/graph_rag/document.py +29 -0
  87. autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +167 -0
  88. autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
  89. autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
  90. autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
  91. autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +263 -0
  92. autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
  93. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
  94. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
  95. autogen/agentchat/contrib/img_utils.py +397 -0
  96. autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
  97. autogen/agentchat/contrib/llava_agent.py +189 -0
  98. autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
  99. autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
  100. autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +325 -0
  101. autogen/agentchat/contrib/rag/__init__.py +10 -0
  102. autogen/agentchat/contrib/rag/chromadb_query_engine.py +268 -0
  103. autogen/agentchat/contrib/rag/llamaindex_query_engine.py +195 -0
  104. autogen/agentchat/contrib/rag/mongodb_query_engine.py +319 -0
  105. autogen/agentchat/contrib/rag/query_engine.py +76 -0
  106. autogen/agentchat/contrib/retrieve_assistant_agent.py +59 -0
  107. autogen/agentchat/contrib/retrieve_user_proxy_agent.py +704 -0
  108. autogen/agentchat/contrib/society_of_mind_agent.py +200 -0
  109. autogen/agentchat/contrib/swarm_agent.py +1404 -0
  110. autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
  111. autogen/agentchat/contrib/vectordb/__init__.py +5 -0
  112. autogen/agentchat/contrib/vectordb/base.py +224 -0
  113. autogen/agentchat/contrib/vectordb/chromadb.py +316 -0
  114. autogen/agentchat/contrib/vectordb/couchbase.py +405 -0
  115. autogen/agentchat/contrib/vectordb/mongodb.py +551 -0
  116. autogen/agentchat/contrib/vectordb/pgvectordb.py +927 -0
  117. autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
  118. autogen/agentchat/contrib/vectordb/utils.py +126 -0
  119. autogen/agentchat/contrib/web_surfer.py +304 -0
  120. autogen/agentchat/conversable_agent.py +4307 -0
  121. autogen/agentchat/group/__init__.py +67 -0
  122. autogen/agentchat/group/available_condition.py +91 -0
  123. autogen/agentchat/group/context_condition.py +77 -0
  124. autogen/agentchat/group/context_expression.py +238 -0
  125. autogen/agentchat/group/context_str.py +39 -0
  126. autogen/agentchat/group/context_variables.py +182 -0
  127. autogen/agentchat/group/events/transition_events.py +111 -0
  128. autogen/agentchat/group/group_tool_executor.py +324 -0
  129. autogen/agentchat/group/group_utils.py +659 -0
  130. autogen/agentchat/group/guardrails.py +179 -0
  131. autogen/agentchat/group/handoffs.py +303 -0
  132. autogen/agentchat/group/llm_condition.py +93 -0
  133. autogen/agentchat/group/multi_agent_chat.py +291 -0
  134. autogen/agentchat/group/on_condition.py +55 -0
  135. autogen/agentchat/group/on_context_condition.py +51 -0
  136. autogen/agentchat/group/patterns/__init__.py +18 -0
  137. autogen/agentchat/group/patterns/auto.py +160 -0
  138. autogen/agentchat/group/patterns/manual.py +177 -0
  139. autogen/agentchat/group/patterns/pattern.py +295 -0
  140. autogen/agentchat/group/patterns/random.py +106 -0
  141. autogen/agentchat/group/patterns/round_robin.py +117 -0
  142. autogen/agentchat/group/reply_result.py +24 -0
  143. autogen/agentchat/group/safeguards/__init__.py +21 -0
  144. autogen/agentchat/group/safeguards/api.py +241 -0
  145. autogen/agentchat/group/safeguards/enforcer.py +1158 -0
  146. autogen/agentchat/group/safeguards/events.py +140 -0
  147. autogen/agentchat/group/safeguards/validator.py +435 -0
  148. autogen/agentchat/group/speaker_selection_result.py +41 -0
  149. autogen/agentchat/group/targets/__init__.py +4 -0
  150. autogen/agentchat/group/targets/function_target.py +245 -0
  151. autogen/agentchat/group/targets/group_chat_target.py +133 -0
  152. autogen/agentchat/group/targets/group_manager_target.py +151 -0
  153. autogen/agentchat/group/targets/transition_target.py +424 -0
  154. autogen/agentchat/group/targets/transition_utils.py +6 -0
  155. autogen/agentchat/groupchat.py +1832 -0
  156. autogen/agentchat/realtime/__init__.py +3 -0
  157. autogen/agentchat/realtime/experimental/__init__.py +20 -0
  158. autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
  159. autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
  160. autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
  161. autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
  162. autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
  163. autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
  164. autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
  165. autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
  166. autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
  167. autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
  168. autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
  169. autogen/agentchat/realtime/experimental/clients/realtime_client.py +191 -0
  170. autogen/agentchat/realtime/experimental/function_observer.py +84 -0
  171. autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
  172. autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
  173. autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
  174. autogen/agentchat/realtime/experimental/realtime_swarm.py +533 -0
  175. autogen/agentchat/realtime/experimental/websockets.py +21 -0
  176. autogen/agentchat/realtime_agent/__init__.py +21 -0
  177. autogen/agentchat/user_proxy_agent.py +114 -0
  178. autogen/agentchat/utils.py +206 -0
  179. autogen/agents/__init__.py +3 -0
  180. autogen/agents/contrib/__init__.py +10 -0
  181. autogen/agents/contrib/time/__init__.py +8 -0
  182. autogen/agents/contrib/time/time_reply_agent.py +74 -0
  183. autogen/agents/contrib/time/time_tool_agent.py +52 -0
  184. autogen/agents/experimental/__init__.py +27 -0
  185. autogen/agents/experimental/deep_research/__init__.py +7 -0
  186. autogen/agents/experimental/deep_research/deep_research.py +52 -0
  187. autogen/agents/experimental/discord/__init__.py +7 -0
  188. autogen/agents/experimental/discord/discord.py +66 -0
  189. autogen/agents/experimental/document_agent/__init__.py +19 -0
  190. autogen/agents/experimental/document_agent/chroma_query_engine.py +301 -0
  191. autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +113 -0
  192. autogen/agents/experimental/document_agent/document_agent.py +643 -0
  193. autogen/agents/experimental/document_agent/document_conditions.py +50 -0
  194. autogen/agents/experimental/document_agent/document_utils.py +376 -0
  195. autogen/agents/experimental/document_agent/inmemory_query_engine.py +214 -0
  196. autogen/agents/experimental/document_agent/parser_utils.py +134 -0
  197. autogen/agents/experimental/document_agent/url_utils.py +417 -0
  198. autogen/agents/experimental/reasoning/__init__.py +7 -0
  199. autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
  200. autogen/agents/experimental/slack/__init__.py +7 -0
  201. autogen/agents/experimental/slack/slack.py +73 -0
  202. autogen/agents/experimental/telegram/__init__.py +7 -0
  203. autogen/agents/experimental/telegram/telegram.py +76 -0
  204. autogen/agents/experimental/websurfer/__init__.py +7 -0
  205. autogen/agents/experimental/websurfer/websurfer.py +70 -0
  206. autogen/agents/experimental/wikipedia/__init__.py +7 -0
  207. autogen/agents/experimental/wikipedia/wikipedia.py +88 -0
  208. autogen/browser_utils.py +309 -0
  209. autogen/cache/__init__.py +10 -0
  210. autogen/cache/abstract_cache_base.py +71 -0
  211. autogen/cache/cache.py +203 -0
  212. autogen/cache/cache_factory.py +88 -0
  213. autogen/cache/cosmos_db_cache.py +144 -0
  214. autogen/cache/disk_cache.py +97 -0
  215. autogen/cache/in_memory_cache.py +54 -0
  216. autogen/cache/redis_cache.py +119 -0
  217. autogen/code_utils.py +598 -0
  218. autogen/coding/__init__.py +30 -0
  219. autogen/coding/base.py +120 -0
  220. autogen/coding/docker_commandline_code_executor.py +283 -0
  221. autogen/coding/factory.py +56 -0
  222. autogen/coding/func_with_reqs.py +203 -0
  223. autogen/coding/jupyter/__init__.py +23 -0
  224. autogen/coding/jupyter/base.py +36 -0
  225. autogen/coding/jupyter/docker_jupyter_server.py +160 -0
  226. autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
  227. autogen/coding/jupyter/import_utils.py +82 -0
  228. autogen/coding/jupyter/jupyter_client.py +224 -0
  229. autogen/coding/jupyter/jupyter_code_executor.py +154 -0
  230. autogen/coding/jupyter/local_jupyter_server.py +164 -0
  231. autogen/coding/local_commandline_code_executor.py +341 -0
  232. autogen/coding/markdown_code_extractor.py +44 -0
  233. autogen/coding/utils.py +55 -0
  234. autogen/coding/yepcode_code_executor.py +197 -0
  235. autogen/doc_utils.py +35 -0
  236. autogen/environments/__init__.py +10 -0
  237. autogen/environments/docker_python_environment.py +365 -0
  238. autogen/environments/python_environment.py +125 -0
  239. autogen/environments/system_python_environment.py +85 -0
  240. autogen/environments/venv_python_environment.py +220 -0
  241. autogen/environments/working_directory.py +74 -0
  242. autogen/events/__init__.py +7 -0
  243. autogen/events/agent_events.py +1016 -0
  244. autogen/events/base_event.py +100 -0
  245. autogen/events/client_events.py +168 -0
  246. autogen/events/helpers.py +44 -0
  247. autogen/events/print_event.py +45 -0
  248. autogen/exception_utils.py +73 -0
  249. autogen/extensions/__init__.py +5 -0
  250. autogen/fast_depends/__init__.py +16 -0
  251. autogen/fast_depends/_compat.py +75 -0
  252. autogen/fast_depends/core/__init__.py +14 -0
  253. autogen/fast_depends/core/build.py +206 -0
  254. autogen/fast_depends/core/model.py +527 -0
  255. autogen/fast_depends/dependencies/__init__.py +15 -0
  256. autogen/fast_depends/dependencies/model.py +30 -0
  257. autogen/fast_depends/dependencies/provider.py +40 -0
  258. autogen/fast_depends/library/__init__.py +10 -0
  259. autogen/fast_depends/library/model.py +46 -0
  260. autogen/fast_depends/py.typed +6 -0
  261. autogen/fast_depends/schema.py +66 -0
  262. autogen/fast_depends/use.py +272 -0
  263. autogen/fast_depends/utils.py +177 -0
  264. autogen/formatting_utils.py +83 -0
  265. autogen/function_utils.py +13 -0
  266. autogen/graph_utils.py +173 -0
  267. autogen/import_utils.py +539 -0
  268. autogen/interop/__init__.py +22 -0
  269. autogen/interop/crewai/__init__.py +7 -0
  270. autogen/interop/crewai/crewai.py +88 -0
  271. autogen/interop/interoperability.py +71 -0
  272. autogen/interop/interoperable.py +46 -0
  273. autogen/interop/langchain/__init__.py +8 -0
  274. autogen/interop/langchain/langchain_chat_model_factory.py +156 -0
  275. autogen/interop/langchain/langchain_tool.py +78 -0
  276. autogen/interop/litellm/__init__.py +7 -0
  277. autogen/interop/litellm/litellm_config_factory.py +178 -0
  278. autogen/interop/pydantic_ai/__init__.py +7 -0
  279. autogen/interop/pydantic_ai/pydantic_ai.py +172 -0
  280. autogen/interop/registry.py +70 -0
  281. autogen/io/__init__.py +15 -0
  282. autogen/io/base.py +151 -0
  283. autogen/io/console.py +56 -0
  284. autogen/io/processors/__init__.py +12 -0
  285. autogen/io/processors/base.py +21 -0
  286. autogen/io/processors/console_event_processor.py +61 -0
  287. autogen/io/run_response.py +294 -0
  288. autogen/io/thread_io_stream.py +63 -0
  289. autogen/io/websockets.py +214 -0
  290. autogen/json_utils.py +42 -0
  291. autogen/llm_clients/MIGRATION_TO_V2.md +782 -0
  292. autogen/llm_clients/__init__.py +77 -0
  293. autogen/llm_clients/client_v2.py +122 -0
  294. autogen/llm_clients/models/__init__.py +55 -0
  295. autogen/llm_clients/models/content_blocks.py +389 -0
  296. autogen/llm_clients/models/unified_message.py +145 -0
  297. autogen/llm_clients/models/unified_response.py +83 -0
  298. autogen/llm_clients/openai_completions_client.py +444 -0
  299. autogen/llm_config/__init__.py +11 -0
  300. autogen/llm_config/client.py +59 -0
  301. autogen/llm_config/config.py +461 -0
  302. autogen/llm_config/entry.py +169 -0
  303. autogen/llm_config/types.py +37 -0
  304. autogen/llm_config/utils.py +223 -0
  305. autogen/logger/__init__.py +11 -0
  306. autogen/logger/base_logger.py +129 -0
  307. autogen/logger/file_logger.py +262 -0
  308. autogen/logger/logger_factory.py +42 -0
  309. autogen/logger/logger_utils.py +57 -0
  310. autogen/logger/sqlite_logger.py +524 -0
  311. autogen/math_utils.py +338 -0
  312. autogen/mcp/__init__.py +7 -0
  313. autogen/mcp/__main__.py +78 -0
  314. autogen/mcp/helpers.py +45 -0
  315. autogen/mcp/mcp_client.py +349 -0
  316. autogen/mcp/mcp_proxy/__init__.py +19 -0
  317. autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +62 -0
  318. autogen/mcp/mcp_proxy/mcp_proxy.py +577 -0
  319. autogen/mcp/mcp_proxy/operation_grouping.py +166 -0
  320. autogen/mcp/mcp_proxy/operation_renaming.py +110 -0
  321. autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
  322. autogen/mcp/mcp_proxy/security.py +399 -0
  323. autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
  324. autogen/messages/__init__.py +7 -0
  325. autogen/messages/agent_messages.py +946 -0
  326. autogen/messages/base_message.py +108 -0
  327. autogen/messages/client_messages.py +172 -0
  328. autogen/messages/print_message.py +48 -0
  329. autogen/oai/__init__.py +61 -0
  330. autogen/oai/anthropic.py +1516 -0
  331. autogen/oai/bedrock.py +800 -0
  332. autogen/oai/cerebras.py +302 -0
  333. autogen/oai/client.py +1658 -0
  334. autogen/oai/client_utils.py +196 -0
  335. autogen/oai/cohere.py +494 -0
  336. autogen/oai/gemini.py +1045 -0
  337. autogen/oai/gemini_types.py +156 -0
  338. autogen/oai/groq.py +319 -0
  339. autogen/oai/mistral.py +311 -0
  340. autogen/oai/oai_models/__init__.py +23 -0
  341. autogen/oai/oai_models/_models.py +16 -0
  342. autogen/oai/oai_models/chat_completion.py +86 -0
  343. autogen/oai/oai_models/chat_completion_audio.py +32 -0
  344. autogen/oai/oai_models/chat_completion_message.py +97 -0
  345. autogen/oai/oai_models/chat_completion_message_tool_call.py +60 -0
  346. autogen/oai/oai_models/chat_completion_token_logprob.py +62 -0
  347. autogen/oai/oai_models/completion_usage.py +59 -0
  348. autogen/oai/ollama.py +657 -0
  349. autogen/oai/openai_responses.py +451 -0
  350. autogen/oai/openai_utils.py +897 -0
  351. autogen/oai/together.py +387 -0
  352. autogen/remote/__init__.py +18 -0
  353. autogen/remote/agent.py +199 -0
  354. autogen/remote/agent_service.py +197 -0
  355. autogen/remote/errors.py +17 -0
  356. autogen/remote/httpx_client_factory.py +131 -0
  357. autogen/remote/protocol.py +37 -0
  358. autogen/remote/retry.py +102 -0
  359. autogen/remote/runtime.py +96 -0
  360. autogen/retrieve_utils.py +490 -0
  361. autogen/runtime_logging.py +161 -0
  362. autogen/testing/__init__.py +12 -0
  363. autogen/testing/messages.py +45 -0
  364. autogen/testing/test_agent.py +111 -0
  365. autogen/token_count_utils.py +280 -0
  366. autogen/tools/__init__.py +20 -0
  367. autogen/tools/contrib/__init__.py +9 -0
  368. autogen/tools/contrib/time/__init__.py +7 -0
  369. autogen/tools/contrib/time/time.py +40 -0
  370. autogen/tools/dependency_injection.py +249 -0
  371. autogen/tools/experimental/__init__.py +54 -0
  372. autogen/tools/experimental/browser_use/__init__.py +7 -0
  373. autogen/tools/experimental/browser_use/browser_use.py +154 -0
  374. autogen/tools/experimental/code_execution/__init__.py +7 -0
  375. autogen/tools/experimental/code_execution/python_code_execution.py +86 -0
  376. autogen/tools/experimental/crawl4ai/__init__.py +7 -0
  377. autogen/tools/experimental/crawl4ai/crawl4ai.py +150 -0
  378. autogen/tools/experimental/deep_research/__init__.py +7 -0
  379. autogen/tools/experimental/deep_research/deep_research.py +329 -0
  380. autogen/tools/experimental/duckduckgo/__init__.py +7 -0
  381. autogen/tools/experimental/duckduckgo/duckduckgo_search.py +103 -0
  382. autogen/tools/experimental/firecrawl/__init__.py +7 -0
  383. autogen/tools/experimental/firecrawl/firecrawl_tool.py +836 -0
  384. autogen/tools/experimental/google/__init__.py +14 -0
  385. autogen/tools/experimental/google/authentication/__init__.py +11 -0
  386. autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
  387. autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
  388. autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
  389. autogen/tools/experimental/google/drive/__init__.py +9 -0
  390. autogen/tools/experimental/google/drive/drive_functions.py +124 -0
  391. autogen/tools/experimental/google/drive/toolkit.py +88 -0
  392. autogen/tools/experimental/google/model.py +17 -0
  393. autogen/tools/experimental/google/toolkit_protocol.py +19 -0
  394. autogen/tools/experimental/google_search/__init__.py +8 -0
  395. autogen/tools/experimental/google_search/google_search.py +93 -0
  396. autogen/tools/experimental/google_search/youtube_search.py +181 -0
  397. autogen/tools/experimental/messageplatform/__init__.py +17 -0
  398. autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
  399. autogen/tools/experimental/messageplatform/discord/discord.py +284 -0
  400. autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
  401. autogen/tools/experimental/messageplatform/slack/slack.py +385 -0
  402. autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
  403. autogen/tools/experimental/messageplatform/telegram/telegram.py +271 -0
  404. autogen/tools/experimental/perplexity/__init__.py +7 -0
  405. autogen/tools/experimental/perplexity/perplexity_search.py +249 -0
  406. autogen/tools/experimental/reliable/__init__.py +10 -0
  407. autogen/tools/experimental/reliable/reliable.py +1311 -0
  408. autogen/tools/experimental/searxng/__init__.py +7 -0
  409. autogen/tools/experimental/searxng/searxng_search.py +142 -0
  410. autogen/tools/experimental/tavily/__init__.py +7 -0
  411. autogen/tools/experimental/tavily/tavily_search.py +176 -0
  412. autogen/tools/experimental/web_search_preview/__init__.py +7 -0
  413. autogen/tools/experimental/web_search_preview/web_search_preview.py +120 -0
  414. autogen/tools/experimental/wikipedia/__init__.py +7 -0
  415. autogen/tools/experimental/wikipedia/wikipedia.py +284 -0
  416. autogen/tools/function_utils.py +412 -0
  417. autogen/tools/tool.py +188 -0
  418. autogen/tools/toolkit.py +86 -0
  419. autogen/types.py +29 -0
  420. autogen/version.py +7 -0
  421. templates/client_template/main.jinja2 +72 -0
  422. templates/config_template/config.jinja2 +7 -0
  423. templates/main.jinja2 +61 -0
autogen/a2a/client.py ADDED
@@ -0,0 +1,357 @@
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 asyncio
6
+ import logging
7
+ from collections.abc import Sequence
8
+ from pprint import pformat
9
+ from typing import Any, cast
10
+ from uuid import uuid4
11
+
12
+ import httpx
13
+ from a2a.client import A2ACardResolver, A2AClientHTTPError, Client, ClientCallInterceptor, ClientConfig, ClientEvent
14
+ from a2a.client import ClientFactory as A2AClientFactory
15
+ from a2a.types import AgentCard, Message, Task, TaskIdParams, TaskQueryParams, TaskState
16
+ from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH, EXTENDED_AGENT_CARD_PATH, PREV_AGENT_CARD_WELL_KNOWN_PATH
17
+ from typing_extensions import Self
18
+
19
+ from autogen import ConversableAgent
20
+ from autogen.agentchat.group import ContextVariables
21
+ from autogen.doc_utils import export_module
22
+ from autogen.events.agent_events import TerminationEvent
23
+ from autogen.io.base import IOStream
24
+ from autogen.oai.client import OpenAIWrapper
25
+ from autogen.remote.httpx_client_factory import ClientFactory, EmptyClientFactory
26
+ from autogen.remote.protocol import RequestMessage, ResponseMessage
27
+
28
+ from .errors import A2aAgentNotFoundError, A2aClientError
29
+ from .utils import (
30
+ request_message_to_a2a,
31
+ response_message_from_a2a_message,
32
+ response_message_from_a2a_task,
33
+ )
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+
38
+ @export_module("autogen.a2a")
39
+ class A2aRemoteAgent(ConversableAgent):
40
+ """`a2a-sdk`-based client for handling asynchronous communication with an A2A server.
41
+
42
+ It has fully-compatible with original `ConversableAgent` API, so you can easily integrate
43
+ remote A2A agents to existing collaborations.
44
+
45
+ Args:
46
+ url: The URL of the A2A server to connect to.
47
+ name: A unique identifier for this client instance.
48
+ silent: whether to print the message sent. If None, will use the value of silent in each function.
49
+ client: An optional HTTPX client instance factory.
50
+ client_config: A2A Client configuration options.
51
+ max_reconnects: Maximum number of reconnection attempts before giving up.
52
+ polling_interval: Time in seconds between polling operations. Works for A2A Servers doesn't support streaming.
53
+ interceptors: A list of interceptors to use for the client.
54
+ """
55
+
56
+ def __init__(
57
+ self,
58
+ url: str,
59
+ name: str,
60
+ *,
61
+ silent: bool | None = None,
62
+ client: ClientFactory | None = None,
63
+ client_config: ClientConfig | None = None,
64
+ interceptors: Sequence[ClientCallInterceptor] = (),
65
+ max_reconnects: int = 3,
66
+ polling_interval: float = 0.5,
67
+ ) -> None:
68
+ self.url = url # make it public for backward compatibility
69
+
70
+ self._httpx_client_factory = client or EmptyClientFactory()
71
+ self._card_resolver = A2ACardResolver(
72
+ httpx_client=self._httpx_client_factory(),
73
+ base_url=url,
74
+ )
75
+
76
+ self._max_reconnects = max_reconnects
77
+ self._polling_interval = polling_interval
78
+
79
+ super().__init__(name, silent=silent)
80
+
81
+ self.__llm_config: dict[str, Any] = {}
82
+
83
+ self._client_config = client_config or ClientConfig()
84
+ self._interceptors = list(interceptors)
85
+ self._agent_card: AgentCard | None = None
86
+
87
+ self.replace_reply_func(
88
+ ConversableAgent.generate_oai_reply,
89
+ A2aRemoteAgent.generate_remote_reply,
90
+ )
91
+ self.replace_reply_func(
92
+ ConversableAgent.a_generate_oai_reply,
93
+ A2aRemoteAgent.a_generate_remote_reply,
94
+ )
95
+
96
+ @classmethod
97
+ def from_card(
98
+ cls,
99
+ card: AgentCard,
100
+ *,
101
+ silent: bool | None = None,
102
+ client: ClientFactory | None = None,
103
+ client_config: ClientConfig | None = None,
104
+ max_reconnects: int = 3,
105
+ polling_interval: float = 0.5,
106
+ interceptors: Sequence[ClientCallInterceptor] = (),
107
+ ) -> Self:
108
+ """Creates an A2aRemoteAgent instance from an existing AgentCard.
109
+
110
+ This method allows you to instantiate an A2aRemoteAgent directly using a pre-existing
111
+ AgentCard, such as one retrieved from a discovery service or constructed manually.
112
+ The resulting agent will use the data from the given card and avoid redundant card
113
+ fetching. The agent's registryURL is set to "UNKNOWN" since it is assumed to be derived
114
+ from the card.
115
+
116
+ Args:
117
+ card: The agent card containing metadata and configuration for the remote agent.
118
+ silent: whether to print the message sent. If None, will use the value of silent in each function.
119
+ client: An optional HTTPX client instance factory.
120
+ client_config: A2A Client configuration options.
121
+ max_reconnects: Maximum number of reconnection attempts before giving up.
122
+ polling_interval: Time in seconds between polling operations. Works for A2A Servers doesn't support streaming.
123
+ interceptors: A list of interceptors to use for the client.
124
+
125
+ Returns:
126
+ Self: An instance of the A2aRemoteAgent configured with the provided card.
127
+ """
128
+ instance = cls(
129
+ url="UNKNOWN",
130
+ name=card.name,
131
+ silent=silent,
132
+ client=client,
133
+ client_config=client_config,
134
+ max_reconnects=max_reconnects,
135
+ polling_interval=polling_interval,
136
+ interceptors=interceptors,
137
+ )
138
+ instance._agent_card = card
139
+ return instance
140
+
141
+ def generate_remote_reply(
142
+ self,
143
+ messages: list[dict[str, Any]] | None = None,
144
+ sender: ConversableAgent | None = None,
145
+ config: OpenAIWrapper | None = None,
146
+ ) -> tuple[bool, dict[str, Any] | None]:
147
+ raise NotImplementedError(f"{self.__class__.__name__} does not support synchronous reply generation")
148
+
149
+ async def a_generate_remote_reply(
150
+ self,
151
+ messages: list[dict[str, Any]] | None = None,
152
+ sender: ConversableAgent | None = None,
153
+ config: OpenAIWrapper | None = None,
154
+ ) -> tuple[bool, dict[str, Any] | None]:
155
+ if messages is None:
156
+ messages = self._oai_messages[sender]
157
+
158
+ if not self._agent_card:
159
+ self._agent_card = await self._get_agent_card()
160
+
161
+ context_id = uuid4().hex
162
+
163
+ self._client_config.httpx_client = self._httpx_client_factory()
164
+ async with self._client_config.httpx_client:
165
+ agent_client = A2AClientFactory(self._client_config).create(
166
+ self._agent_card,
167
+ interceptors=self._interceptors,
168
+ )
169
+
170
+ while True:
171
+ initial_message = request_message_to_a2a(
172
+ request_message=RequestMessage(
173
+ messages=messages,
174
+ context=self.context_variables.data,
175
+ client_tools=self.__llm_config.get("tools", []),
176
+ ),
177
+ context_id=context_id,
178
+ )
179
+
180
+ if self._agent_card.capabilities.streaming:
181
+ reply = await self._ask_streaming(agent_client, initial_message)
182
+ else:
183
+ reply = await self._ask_polling(agent_client, initial_message)
184
+
185
+ if not reply:
186
+ return True, None
187
+
188
+ messages = reply.messages
189
+ if reply.input_required is not None:
190
+ user_input = await self.a_get_human_input(prompt=f"Input for `{self.name}`\n{reply.input_required}")
191
+
192
+ if user_input == "exit":
193
+ IOStream.get_default().send(
194
+ TerminationEvent(
195
+ termination_reason="User requested to end the conversation",
196
+ sender=self,
197
+ recipient=sender,
198
+ )
199
+ )
200
+ return True, None
201
+
202
+ messages.append({"content": user_input, "role": "user"})
203
+ continue
204
+
205
+ if sender and reply.context:
206
+ context_variables = ContextVariables(reply.context)
207
+ self.context_variables.update(context_variables.to_dict())
208
+ sender.context_variables.update(context_variables.to_dict())
209
+
210
+ return True, reply.messages[-1]
211
+
212
+ async def _ask_streaming(self, client: Client, message: Message) -> ResponseMessage | None:
213
+ connection_attemps = 1
214
+ try:
215
+ async for event in client.send_message(message):
216
+ result, task = self._process_event(event)
217
+ if not task:
218
+ return result
219
+ except httpx.ConnectError as e:
220
+ if task and connection_attemps < self._max_reconnects:
221
+ pass
222
+
223
+ if not self._agent_card:
224
+ raise A2aClientError("Failed to connect to the agent: agent card not found") from e
225
+ raise A2aClientError(f"Failed to connect to the agent: {pformat(self._agent_card.model_dump())}") from e
226
+
227
+ task = cast(Task, task)
228
+ while connection_attemps < self._max_reconnects:
229
+ try:
230
+ async for event in client.resubscribe(TaskIdParams(id=task.id)):
231
+ result, task = self._process_event(event)
232
+ if not task:
233
+ return result
234
+
235
+ except httpx.ConnectError as e:
236
+ connection_attemps += 1
237
+ if connection_attemps < self._max_reconnects:
238
+ pass
239
+
240
+ if not self._agent_card:
241
+ raise A2aClientError("Failed to connect to the agent: agent card not found") from e
242
+ raise A2aClientError(f"Failed to connect to the agent: {pformat(self._agent_card.model_dump())}") from e
243
+
244
+ return None
245
+
246
+ async def _ask_polling(self, client: Client, message: Message) -> ResponseMessage | None:
247
+ try:
248
+ async for event in client.send_message(message):
249
+ result, started_task = self._process_event(event)
250
+ if not started_task:
251
+ return result
252
+ break
253
+ except httpx.ConnectError as e:
254
+ if not self._agent_card:
255
+ raise A2aClientError("Failed to connect to the agent: agent card not found") from e
256
+ raise A2aClientError(f"Failed to connect to the agent: {pformat(self._agent_card.model_dump())}") from e
257
+
258
+ started_task, connection_attemps = cast(Task, started_task), 0
259
+ while connection_attemps < self._max_reconnects:
260
+ while True:
261
+ try:
262
+ task = await client.get_task(TaskQueryParams(id=started_task.id))
263
+
264
+ except httpx.ConnectError as e:
265
+ connection_attemps += 1
266
+ if connection_attemps < self._max_reconnects:
267
+ pass
268
+
269
+ if not self._agent_card:
270
+ raise A2aClientError("Failed to connect to the agent: agent card not found") from e
271
+ raise A2aClientError(
272
+ f"Failed to connect to the agent: {pformat(self._agent_card.model_dump())}"
273
+ ) from e
274
+
275
+ else:
276
+ if _is_task_completed(task):
277
+ return response_message_from_a2a_task(task)
278
+
279
+ await asyncio.sleep(self._polling_interval)
280
+
281
+ return None
282
+
283
+ def _process_event(self, event: ClientEvent | Message) -> tuple[ResponseMessage | None, Task | None]:
284
+ if isinstance(event, Message):
285
+ return response_message_from_a2a_message(event), None
286
+
287
+ task, _ = event
288
+ if _is_task_completed(task):
289
+ return response_message_from_a2a_task(task), None
290
+
291
+ return None, task
292
+
293
+ def update_tool_signature(
294
+ self,
295
+ tool_sig: str | dict[str, Any],
296
+ is_remove: bool,
297
+ silent_override: bool = False,
298
+ ) -> None:
299
+ self.__llm_config = self._update_tool_config(
300
+ self.__llm_config,
301
+ tool_sig=tool_sig,
302
+ is_remove=is_remove,
303
+ silent_override=silent_override,
304
+ )
305
+
306
+ async def _get_agent_card(
307
+ self,
308
+ auth_http_kwargs: dict[str, Any] | None = None,
309
+ ) -> AgentCard:
310
+ card: AgentCard | None = None
311
+
312
+ try:
313
+ logger.info(
314
+ f"Attempting to fetch public agent card from: {self._card_resolver.base_url}{AGENT_CARD_WELL_KNOWN_PATH}"
315
+ )
316
+
317
+ try:
318
+ card = await self._card_resolver.get_agent_card(relative_card_path=AGENT_CARD_WELL_KNOWN_PATH)
319
+ except A2AClientHTTPError as e_public:
320
+ if e_public.status_code == 404:
321
+ logger.info(
322
+ f"Attempting to fetch public agent card from: {self._card_resolver.base_url}{PREV_AGENT_CARD_WELL_KNOWN_PATH}"
323
+ )
324
+ card = await self._card_resolver.get_agent_card(relative_card_path=PREV_AGENT_CARD_WELL_KNOWN_PATH)
325
+ else:
326
+ raise e_public
327
+
328
+ if card.supports_authenticated_extended_card:
329
+ try:
330
+ card = await self._card_resolver.get_agent_card(
331
+ relative_card_path=EXTENDED_AGENT_CARD_PATH,
332
+ http_kwargs=auth_http_kwargs,
333
+ )
334
+ except Exception as e_extended:
335
+ logger.warning(
336
+ f"Failed to fetch extended agent card: {e_extended}. Will proceed with public card.",
337
+ exc_info=True,
338
+ )
339
+
340
+ except Exception as e:
341
+ raise A2aAgentNotFoundError(f"{self.name}: {self._card_resolver.base_url}") from e
342
+
343
+ return card
344
+
345
+
346
+ def _is_task_completed(task: Task) -> bool:
347
+ if task.status.state is TaskState.failed:
348
+ raise A2aClientError(f"Task failed: {pformat(task.model_dump())}")
349
+
350
+ if task.status.state is TaskState.rejected:
351
+ raise A2aClientError(f"Task rejected: {pformat(task.model_dump())}")
352
+
353
+ return task.status.state in (
354
+ TaskState.completed,
355
+ TaskState.canceled,
356
+ TaskState.input_required,
357
+ )
autogen/a2a/errors.py ADDED
@@ -0,0 +1,18 @@
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 autogen.remote.errors import RemoteAgentError, RemoteAgentNotFoundError
7
+
8
+
9
+ class A2aClientError(RemoteAgentError):
10
+ """Base class for A2A agent errors"""
11
+
12
+ pass
13
+
14
+
15
+ class A2aAgentNotFoundError(A2aClientError, RemoteAgentNotFoundError):
16
+ """Raised when a A2A agent is not found"""
17
+
18
+ pass
@@ -0,0 +1,79 @@
1
+ # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from typing import Any
6
+ from uuid import uuid4
7
+
8
+ from a2a.types import AgentCapabilities, AgentCard, DataPart, Message, Part, Role, SendMessageSuccessResponse, TextPart
9
+ from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH, EXTENDED_AGENT_CARD_PATH, PREV_AGENT_CARD_WELL_KNOWN_PATH
10
+ from httpx import MockTransport, Request, Response
11
+
12
+ from autogen.doc_utils import export_module
13
+ from autogen.remote.httpx_client_factory import HttpxClientFactory
14
+
15
+
16
+ @export_module("autogen.a2a")
17
+ def MockClient( # noqa: N802
18
+ response_message: str | dict[str, Any] | TextPart | DataPart | Part,
19
+ ) -> HttpxClientFactory:
20
+ """Create a mock HTTP client for testing A2A agent interactions.
21
+
22
+ This function creates a mock HTTP client that simulates responses from an A2A agent server.
23
+ It handles both agent card requests and message sending requests with configurable responses.
24
+
25
+ Args:
26
+ response_message: The message to return in response to SendMessage requests.
27
+
28
+ Returns:
29
+ An HttpxClientFactory configured with a mock transport that handles requests
30
+ to agent card endpoints and message sending endpoints.
31
+
32
+ Example:
33
+ >>> client = MockClient("Hello, world!")
34
+ >>> agent = A2aRemoteAgent(name="remote", url="http://fake", client=client)
35
+ """
36
+ if isinstance(response_message, Part):
37
+ parts = [response_message]
38
+ elif isinstance(response_message, (DataPart, TextPart)):
39
+ parts = [Part(root=response_message)]
40
+ elif isinstance(response_message, str):
41
+ parts = [Part(root=DataPart(data={"role": "assistant", "content": response_message}))]
42
+ elif isinstance(response_message, dict):
43
+ parts = [Part(root=DataPart(data={"role": "assistant", **response_message}))]
44
+ else:
45
+ raise ValueError(f"Invalid message type: {type(response_message)}")
46
+
47
+ async def mock_handler(request: Request) -> Response:
48
+ if (
49
+ request.url.path == AGENT_CARD_WELL_KNOWN_PATH
50
+ or request.url.path == EXTENDED_AGENT_CARD_PATH
51
+ or request.url.path == PREV_AGENT_CARD_WELL_KNOWN_PATH
52
+ ):
53
+ return Response(
54
+ status_code=200,
55
+ content=AgentCard(
56
+ capabilities=AgentCapabilities(streaming=False),
57
+ default_input_modes=["text"],
58
+ default_output_modes=["text"],
59
+ name="mock_agent",
60
+ description="mock_agent",
61
+ url="http://localhost:8000",
62
+ supports_authenticated_extended_card=False,
63
+ version="0.1.0",
64
+ skills=[],
65
+ ).model_dump_json(),
66
+ )
67
+
68
+ return Response(
69
+ status_code=200,
70
+ content=SendMessageSuccessResponse(
71
+ result=Message(
72
+ message_id=str(uuid4()),
73
+ role=Role.agent,
74
+ parts=parts,
75
+ ),
76
+ ).model_dump_json(),
77
+ )
78
+
79
+ return HttpxClientFactory(transport=MockTransport(handler=mock_handler))
autogen/a2a/server.py ADDED
@@ -0,0 +1,221 @@
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 warnings
6
+ from collections.abc import Callable
7
+ from typing import TYPE_CHECKING
8
+
9
+ from a2a.server.request_handlers import DefaultRequestHandler
10
+ from a2a.server.tasks import InMemoryTaskStore
11
+ from a2a.types import AgentCapabilities, AgentCard, AgentSkill
12
+ from pydantic import Field
13
+
14
+ from autogen import ConversableAgent
15
+ from autogen.doc_utils import export_module
16
+
17
+ from .agent_executor import AutogenAgentExecutor
18
+
19
+ if TYPE_CHECKING:
20
+ from a2a.server.agent_execution import RequestContextBuilder
21
+ from a2a.server.apps import CallContextBuilder
22
+ from a2a.server.context import ServerCallContext
23
+ from a2a.server.events import QueueManager
24
+ from a2a.server.request_handlers import RequestHandler
25
+ from a2a.server.tasks import PushNotificationConfigStore, PushNotificationSender, TaskStore
26
+ from starlette.applications import Starlette
27
+
28
+ from autogen import ConversableAgent
29
+
30
+
31
+ @export_module("autogen.a2a")
32
+ class CardSettings(AgentCard):
33
+ """Original A2A AgentCard object inheritor making some fields optional."""
34
+
35
+ name: str | None = None # type: ignore[assignment]
36
+ """
37
+ A human-readable name for the agent. Uses original agent name if not set.
38
+ """
39
+
40
+ description: str | None = None # type: ignore[assignment]
41
+ """
42
+ A human-readable description of the agent, assisting users and other agents
43
+ in understanding its purpose. Uses original agent description if not set.
44
+ """
45
+
46
+ url: str | None = None # type: ignore[assignment]
47
+ """
48
+ The preferred endpoint URL for interacting with the agent.
49
+ This URL MUST support the transport specified by 'preferredTransport'.
50
+ Uses original A2aAgentServer url if not set.
51
+ """
52
+
53
+ version: str = "0.1.0"
54
+ """
55
+ The agent's own version number. The format is defined by the provider.
56
+ """
57
+
58
+ default_input_modes: list[str] = Field(default_factory=lambda: ["text"])
59
+ """
60
+ Default set of supported input MIME types for all skills, which can be
61
+ overridden on a per-skill basis.
62
+ """
63
+
64
+ default_output_modes: list[str] = Field(default_factory=lambda: ["text"])
65
+ """
66
+ Default set of supported output MIME types for all skills, which can be
67
+ overridden on a per-skill basis.
68
+ """
69
+
70
+ capabilities: AgentCapabilities = Field(default_factory=lambda: AgentCapabilities(streaming=True))
71
+ """
72
+ A declaration of optional capabilities supported by the agent.
73
+ """
74
+
75
+ skills: list[AgentSkill] = Field(default_factory=list)
76
+ """
77
+ The set of skills, or distinct capabilities, that the agent can perform.
78
+ """
79
+
80
+
81
+ @export_module("autogen.a2a")
82
+ class A2aAgentServer:
83
+ """A server wrapper for running an AG2 agent via the A2A protocol.
84
+
85
+ This class provides functionality to wrap an AG2 ConversableAgent into an A2A server
86
+ that can be used to interact with the agent through A2A requests.
87
+ """
88
+
89
+ def __init__(
90
+ self,
91
+ agent: "ConversableAgent",
92
+ *,
93
+ url: str | None = "http://localhost:8000",
94
+ agent_card: CardSettings | None = None,
95
+ card_modifier: Callable[["AgentCard"], "AgentCard"] | None = None,
96
+ extended_agent_card: CardSettings | None = None,
97
+ extended_card_modifier: Callable[["AgentCard", "ServerCallContext"], "AgentCard"] | None = None,
98
+ ) -> None:
99
+ """Initialize the A2aAgentServer.
100
+
101
+ Args:
102
+ agent: The Autogen ConversableAgent to serve.
103
+ url: The base URL for the A2A server.
104
+ agent_card: Configuration for the base agent card.
105
+ card_modifier: Function to modify the base agent card.
106
+ extended_agent_card: Configuration for the extended agent card.
107
+ extended_card_modifier: Function to modify the extended agent card.
108
+ """
109
+ self.agent = agent
110
+
111
+ if not agent_card:
112
+ agent_card = CardSettings()
113
+
114
+ if agent_card.url and url != "http://localhost:8000":
115
+ warnings.warn(
116
+ (
117
+ "You can't use `agent_card.url` and `url` options in the same time. "
118
+ f"`agent_card.url` has a higher priority, so `{agent_card.url}` will be used."
119
+ ),
120
+ RuntimeWarning,
121
+ stacklevel=2,
122
+ )
123
+
124
+ self.card = AgentCard.model_validate({
125
+ # use agent options by default
126
+ "name": agent.name,
127
+ "description": agent.description,
128
+ "url": url,
129
+ "supports_authenticated_extended_card": extended_agent_card is not None,
130
+ # exclude name and description if not provided
131
+ **agent_card.model_dump(exclude_none=True),
132
+ })
133
+
134
+ self.extended_agent_card: AgentCard | None = None
135
+ if extended_agent_card:
136
+ if extended_agent_card.url and url != "http://localhost:8000":
137
+ warnings.warn(
138
+ (
139
+ "You can't use `extended_agent_card.url` and `url` options in the same time. "
140
+ f"`agent_card.url` has a higher priority, so `{extended_agent_card.url}` will be used."
141
+ ),
142
+ RuntimeWarning,
143
+ stacklevel=2,
144
+ )
145
+
146
+ self.extended_agent_card = AgentCard.model_validate({
147
+ "name": agent.name,
148
+ "description": agent.description,
149
+ "url": url,
150
+ **extended_agent_card.model_dump(exclude_none=True),
151
+ })
152
+
153
+ self.card_modifier = card_modifier
154
+ self.extended_card_modifier = extended_card_modifier
155
+
156
+ @property
157
+ def executor(self) -> AutogenAgentExecutor:
158
+ """Get the A2A agent executor."""
159
+ return AutogenAgentExecutor(self.agent)
160
+
161
+ def build_request_handler(
162
+ self,
163
+ *,
164
+ task_store: "TaskStore | None" = None,
165
+ queue_manager: "QueueManager | None" = None,
166
+ push_config_store: "PushNotificationConfigStore | None" = None,
167
+ push_sender: "PushNotificationSender | None" = None,
168
+ request_context_builder: "RequestContextBuilder | None" = None,
169
+ ) -> "RequestHandler":
170
+ """Build a request handler for A2A application.
171
+
172
+ Args:
173
+ task_store: The task store to use.
174
+ queue_manager: The queue manager to use.
175
+ push_config_store: The push notification config store to use.
176
+ push_sender: The push notification sender to use.
177
+ request_context_builder: The request context builder to use.
178
+
179
+ Returns:
180
+ A configured RequestHandler instance.
181
+ """
182
+ return DefaultRequestHandler(
183
+ agent_executor=self.executor,
184
+ task_store=task_store or InMemoryTaskStore(),
185
+ queue_manager=queue_manager,
186
+ push_config_store=push_config_store,
187
+ push_sender=push_sender,
188
+ request_context_builder=request_context_builder,
189
+ )
190
+
191
+ def build_starlette_app(
192
+ self,
193
+ *,
194
+ request_handler: "RequestHandler | None" = None,
195
+ context_builder: "CallContextBuilder | None" = None,
196
+ ) -> "Starlette":
197
+ """Build a Starlette A2A application for ASGI server.
198
+
199
+ Args:
200
+ request_handler: The request handler to use.
201
+ context_builder: The context builder to use.
202
+
203
+ Returns:
204
+ A configured Starlette application instance.
205
+ """
206
+ from a2a.server.apps import A2AStarletteApplication
207
+
208
+ return A2AStarletteApplication(
209
+ agent_card=self.card,
210
+ extended_agent_card=self.extended_agent_card,
211
+ http_handler=request_handler
212
+ or DefaultRequestHandler(
213
+ agent_executor=self.executor,
214
+ task_store=InMemoryTaskStore(),
215
+ ),
216
+ context_builder=context_builder,
217
+ card_modifier=self.card_modifier,
218
+ extended_card_modifier=self.extended_card_modifier,
219
+ ).build()
220
+
221
+ build = build_starlette_app # default alias for build_starlette_app