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.
- ag2-0.10.2.dist-info/METADATA +819 -0
- ag2-0.10.2.dist-info/RECORD +423 -0
- ag2-0.10.2.dist-info/WHEEL +4 -0
- ag2-0.10.2.dist-info/licenses/LICENSE +201 -0
- ag2-0.10.2.dist-info/licenses/NOTICE.md +19 -0
- autogen/__init__.py +88 -0
- autogen/_website/__init__.py +3 -0
- autogen/_website/generate_api_references.py +426 -0
- autogen/_website/generate_mkdocs.py +1216 -0
- autogen/_website/notebook_processor.py +475 -0
- autogen/_website/process_notebooks.py +656 -0
- autogen/_website/utils.py +413 -0
- autogen/a2a/__init__.py +36 -0
- autogen/a2a/agent_executor.py +86 -0
- autogen/a2a/client.py +357 -0
- autogen/a2a/errors.py +18 -0
- autogen/a2a/httpx_client_factory.py +79 -0
- autogen/a2a/server.py +221 -0
- autogen/a2a/utils.py +207 -0
- autogen/agentchat/__init__.py +47 -0
- autogen/agentchat/agent.py +180 -0
- autogen/agentchat/assistant_agent.py +86 -0
- autogen/agentchat/chat.py +325 -0
- autogen/agentchat/contrib/__init__.py +5 -0
- autogen/agentchat/contrib/agent_eval/README.md +7 -0
- autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
- autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
- autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
- autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
- autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
- autogen/agentchat/contrib/agent_eval/task.py +42 -0
- autogen/agentchat/contrib/agent_optimizer.py +432 -0
- autogen/agentchat/contrib/capabilities/__init__.py +5 -0
- autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
- autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
- autogen/agentchat/contrib/capabilities/teachability.py +393 -0
- autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
- autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
- autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
- autogen/agentchat/contrib/capabilities/transforms.py +578 -0
- autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
- autogen/agentchat/contrib/capabilities/vision_capability.py +215 -0
- autogen/agentchat/contrib/captainagent/__init__.py +9 -0
- autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
- autogen/agentchat/contrib/captainagent/captainagent.py +514 -0
- autogen/agentchat/contrib/captainagent/tool_retriever.py +334 -0
- autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
- autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
- autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
- autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
- autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
- autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
- autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
- autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
- autogen/agentchat/contrib/graph_rag/document.py +29 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +167 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
- autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +263 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
- autogen/agentchat/contrib/img_utils.py +397 -0
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
- autogen/agentchat/contrib/llava_agent.py +189 -0
- autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
- autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +325 -0
- autogen/agentchat/contrib/rag/__init__.py +10 -0
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +268 -0
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +195 -0
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +319 -0
- autogen/agentchat/contrib/rag/query_engine.py +76 -0
- autogen/agentchat/contrib/retrieve_assistant_agent.py +59 -0
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +704 -0
- autogen/agentchat/contrib/society_of_mind_agent.py +200 -0
- autogen/agentchat/contrib/swarm_agent.py +1404 -0
- autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
- autogen/agentchat/contrib/vectordb/__init__.py +5 -0
- autogen/agentchat/contrib/vectordb/base.py +224 -0
- autogen/agentchat/contrib/vectordb/chromadb.py +316 -0
- autogen/agentchat/contrib/vectordb/couchbase.py +405 -0
- autogen/agentchat/contrib/vectordb/mongodb.py +551 -0
- autogen/agentchat/contrib/vectordb/pgvectordb.py +927 -0
- autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
- autogen/agentchat/contrib/vectordb/utils.py +126 -0
- autogen/agentchat/contrib/web_surfer.py +304 -0
- autogen/agentchat/conversable_agent.py +4307 -0
- autogen/agentchat/group/__init__.py +67 -0
- autogen/agentchat/group/available_condition.py +91 -0
- autogen/agentchat/group/context_condition.py +77 -0
- autogen/agentchat/group/context_expression.py +238 -0
- autogen/agentchat/group/context_str.py +39 -0
- autogen/agentchat/group/context_variables.py +182 -0
- autogen/agentchat/group/events/transition_events.py +111 -0
- autogen/agentchat/group/group_tool_executor.py +324 -0
- autogen/agentchat/group/group_utils.py +659 -0
- autogen/agentchat/group/guardrails.py +179 -0
- autogen/agentchat/group/handoffs.py +303 -0
- autogen/agentchat/group/llm_condition.py +93 -0
- autogen/agentchat/group/multi_agent_chat.py +291 -0
- autogen/agentchat/group/on_condition.py +55 -0
- autogen/agentchat/group/on_context_condition.py +51 -0
- autogen/agentchat/group/patterns/__init__.py +18 -0
- autogen/agentchat/group/patterns/auto.py +160 -0
- autogen/agentchat/group/patterns/manual.py +177 -0
- autogen/agentchat/group/patterns/pattern.py +295 -0
- autogen/agentchat/group/patterns/random.py +106 -0
- autogen/agentchat/group/patterns/round_robin.py +117 -0
- autogen/agentchat/group/reply_result.py +24 -0
- autogen/agentchat/group/safeguards/__init__.py +21 -0
- autogen/agentchat/group/safeguards/api.py +241 -0
- autogen/agentchat/group/safeguards/enforcer.py +1158 -0
- autogen/agentchat/group/safeguards/events.py +140 -0
- autogen/agentchat/group/safeguards/validator.py +435 -0
- autogen/agentchat/group/speaker_selection_result.py +41 -0
- autogen/agentchat/group/targets/__init__.py +4 -0
- autogen/agentchat/group/targets/function_target.py +245 -0
- autogen/agentchat/group/targets/group_chat_target.py +133 -0
- autogen/agentchat/group/targets/group_manager_target.py +151 -0
- autogen/agentchat/group/targets/transition_target.py +424 -0
- autogen/agentchat/group/targets/transition_utils.py +6 -0
- autogen/agentchat/groupchat.py +1832 -0
- autogen/agentchat/realtime/__init__.py +3 -0
- autogen/agentchat/realtime/experimental/__init__.py +20 -0
- autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
- autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
- autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
- autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
- autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
- autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
- autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
- autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
- autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +191 -0
- autogen/agentchat/realtime/experimental/function_observer.py +84 -0
- autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
- autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
- autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
- autogen/agentchat/realtime/experimental/realtime_swarm.py +533 -0
- autogen/agentchat/realtime/experimental/websockets.py +21 -0
- autogen/agentchat/realtime_agent/__init__.py +21 -0
- autogen/agentchat/user_proxy_agent.py +114 -0
- autogen/agentchat/utils.py +206 -0
- autogen/agents/__init__.py +3 -0
- autogen/agents/contrib/__init__.py +10 -0
- autogen/agents/contrib/time/__init__.py +8 -0
- autogen/agents/contrib/time/time_reply_agent.py +74 -0
- autogen/agents/contrib/time/time_tool_agent.py +52 -0
- autogen/agents/experimental/__init__.py +27 -0
- autogen/agents/experimental/deep_research/__init__.py +7 -0
- autogen/agents/experimental/deep_research/deep_research.py +52 -0
- autogen/agents/experimental/discord/__init__.py +7 -0
- autogen/agents/experimental/discord/discord.py +66 -0
- autogen/agents/experimental/document_agent/__init__.py +19 -0
- autogen/agents/experimental/document_agent/chroma_query_engine.py +301 -0
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +113 -0
- autogen/agents/experimental/document_agent/document_agent.py +643 -0
- autogen/agents/experimental/document_agent/document_conditions.py +50 -0
- autogen/agents/experimental/document_agent/document_utils.py +376 -0
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +214 -0
- autogen/agents/experimental/document_agent/parser_utils.py +134 -0
- autogen/agents/experimental/document_agent/url_utils.py +417 -0
- autogen/agents/experimental/reasoning/__init__.py +7 -0
- autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
- autogen/agents/experimental/slack/__init__.py +7 -0
- autogen/agents/experimental/slack/slack.py +73 -0
- autogen/agents/experimental/telegram/__init__.py +7 -0
- autogen/agents/experimental/telegram/telegram.py +76 -0
- autogen/agents/experimental/websurfer/__init__.py +7 -0
- autogen/agents/experimental/websurfer/websurfer.py +70 -0
- autogen/agents/experimental/wikipedia/__init__.py +7 -0
- autogen/agents/experimental/wikipedia/wikipedia.py +88 -0
- autogen/browser_utils.py +309 -0
- autogen/cache/__init__.py +10 -0
- autogen/cache/abstract_cache_base.py +71 -0
- autogen/cache/cache.py +203 -0
- autogen/cache/cache_factory.py +88 -0
- autogen/cache/cosmos_db_cache.py +144 -0
- autogen/cache/disk_cache.py +97 -0
- autogen/cache/in_memory_cache.py +54 -0
- autogen/cache/redis_cache.py +119 -0
- autogen/code_utils.py +598 -0
- autogen/coding/__init__.py +30 -0
- autogen/coding/base.py +120 -0
- autogen/coding/docker_commandline_code_executor.py +283 -0
- autogen/coding/factory.py +56 -0
- autogen/coding/func_with_reqs.py +203 -0
- autogen/coding/jupyter/__init__.py +23 -0
- autogen/coding/jupyter/base.py +36 -0
- autogen/coding/jupyter/docker_jupyter_server.py +160 -0
- autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
- autogen/coding/jupyter/import_utils.py +82 -0
- autogen/coding/jupyter/jupyter_client.py +224 -0
- autogen/coding/jupyter/jupyter_code_executor.py +154 -0
- autogen/coding/jupyter/local_jupyter_server.py +164 -0
- autogen/coding/local_commandline_code_executor.py +341 -0
- autogen/coding/markdown_code_extractor.py +44 -0
- autogen/coding/utils.py +55 -0
- autogen/coding/yepcode_code_executor.py +197 -0
- autogen/doc_utils.py +35 -0
- autogen/environments/__init__.py +10 -0
- autogen/environments/docker_python_environment.py +365 -0
- autogen/environments/python_environment.py +125 -0
- autogen/environments/system_python_environment.py +85 -0
- autogen/environments/venv_python_environment.py +220 -0
- autogen/environments/working_directory.py +74 -0
- autogen/events/__init__.py +7 -0
- autogen/events/agent_events.py +1016 -0
- autogen/events/base_event.py +100 -0
- autogen/events/client_events.py +168 -0
- autogen/events/helpers.py +44 -0
- autogen/events/print_event.py +45 -0
- autogen/exception_utils.py +73 -0
- autogen/extensions/__init__.py +5 -0
- autogen/fast_depends/__init__.py +16 -0
- autogen/fast_depends/_compat.py +75 -0
- autogen/fast_depends/core/__init__.py +14 -0
- autogen/fast_depends/core/build.py +206 -0
- autogen/fast_depends/core/model.py +527 -0
- autogen/fast_depends/dependencies/__init__.py +15 -0
- autogen/fast_depends/dependencies/model.py +30 -0
- autogen/fast_depends/dependencies/provider.py +40 -0
- autogen/fast_depends/library/__init__.py +10 -0
- autogen/fast_depends/library/model.py +46 -0
- autogen/fast_depends/py.typed +6 -0
- autogen/fast_depends/schema.py +66 -0
- autogen/fast_depends/use.py +272 -0
- autogen/fast_depends/utils.py +177 -0
- autogen/formatting_utils.py +83 -0
- autogen/function_utils.py +13 -0
- autogen/graph_utils.py +173 -0
- autogen/import_utils.py +539 -0
- autogen/interop/__init__.py +22 -0
- autogen/interop/crewai/__init__.py +7 -0
- autogen/interop/crewai/crewai.py +88 -0
- autogen/interop/interoperability.py +71 -0
- autogen/interop/interoperable.py +46 -0
- autogen/interop/langchain/__init__.py +8 -0
- autogen/interop/langchain/langchain_chat_model_factory.py +156 -0
- autogen/interop/langchain/langchain_tool.py +78 -0
- autogen/interop/litellm/__init__.py +7 -0
- autogen/interop/litellm/litellm_config_factory.py +178 -0
- autogen/interop/pydantic_ai/__init__.py +7 -0
- autogen/interop/pydantic_ai/pydantic_ai.py +172 -0
- autogen/interop/registry.py +70 -0
- autogen/io/__init__.py +15 -0
- autogen/io/base.py +151 -0
- autogen/io/console.py +56 -0
- autogen/io/processors/__init__.py +12 -0
- autogen/io/processors/base.py +21 -0
- autogen/io/processors/console_event_processor.py +61 -0
- autogen/io/run_response.py +294 -0
- autogen/io/thread_io_stream.py +63 -0
- autogen/io/websockets.py +214 -0
- autogen/json_utils.py +42 -0
- autogen/llm_clients/MIGRATION_TO_V2.md +782 -0
- autogen/llm_clients/__init__.py +77 -0
- autogen/llm_clients/client_v2.py +122 -0
- autogen/llm_clients/models/__init__.py +55 -0
- autogen/llm_clients/models/content_blocks.py +389 -0
- autogen/llm_clients/models/unified_message.py +145 -0
- autogen/llm_clients/models/unified_response.py +83 -0
- autogen/llm_clients/openai_completions_client.py +444 -0
- autogen/llm_config/__init__.py +11 -0
- autogen/llm_config/client.py +59 -0
- autogen/llm_config/config.py +461 -0
- autogen/llm_config/entry.py +169 -0
- autogen/llm_config/types.py +37 -0
- autogen/llm_config/utils.py +223 -0
- autogen/logger/__init__.py +11 -0
- autogen/logger/base_logger.py +129 -0
- autogen/logger/file_logger.py +262 -0
- autogen/logger/logger_factory.py +42 -0
- autogen/logger/logger_utils.py +57 -0
- autogen/logger/sqlite_logger.py +524 -0
- autogen/math_utils.py +338 -0
- autogen/mcp/__init__.py +7 -0
- autogen/mcp/__main__.py +78 -0
- autogen/mcp/helpers.py +45 -0
- autogen/mcp/mcp_client.py +349 -0
- autogen/mcp/mcp_proxy/__init__.py +19 -0
- autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +62 -0
- autogen/mcp/mcp_proxy/mcp_proxy.py +577 -0
- autogen/mcp/mcp_proxy/operation_grouping.py +166 -0
- autogen/mcp/mcp_proxy/operation_renaming.py +110 -0
- autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
- autogen/mcp/mcp_proxy/security.py +399 -0
- autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
- autogen/messages/__init__.py +7 -0
- autogen/messages/agent_messages.py +946 -0
- autogen/messages/base_message.py +108 -0
- autogen/messages/client_messages.py +172 -0
- autogen/messages/print_message.py +48 -0
- autogen/oai/__init__.py +61 -0
- autogen/oai/anthropic.py +1516 -0
- autogen/oai/bedrock.py +800 -0
- autogen/oai/cerebras.py +302 -0
- autogen/oai/client.py +1658 -0
- autogen/oai/client_utils.py +196 -0
- autogen/oai/cohere.py +494 -0
- autogen/oai/gemini.py +1045 -0
- autogen/oai/gemini_types.py +156 -0
- autogen/oai/groq.py +319 -0
- autogen/oai/mistral.py +311 -0
- autogen/oai/oai_models/__init__.py +23 -0
- autogen/oai/oai_models/_models.py +16 -0
- autogen/oai/oai_models/chat_completion.py +86 -0
- autogen/oai/oai_models/chat_completion_audio.py +32 -0
- autogen/oai/oai_models/chat_completion_message.py +97 -0
- autogen/oai/oai_models/chat_completion_message_tool_call.py +60 -0
- autogen/oai/oai_models/chat_completion_token_logprob.py +62 -0
- autogen/oai/oai_models/completion_usage.py +59 -0
- autogen/oai/ollama.py +657 -0
- autogen/oai/openai_responses.py +451 -0
- autogen/oai/openai_utils.py +897 -0
- autogen/oai/together.py +387 -0
- autogen/remote/__init__.py +18 -0
- autogen/remote/agent.py +199 -0
- autogen/remote/agent_service.py +197 -0
- autogen/remote/errors.py +17 -0
- autogen/remote/httpx_client_factory.py +131 -0
- autogen/remote/protocol.py +37 -0
- autogen/remote/retry.py +102 -0
- autogen/remote/runtime.py +96 -0
- autogen/retrieve_utils.py +490 -0
- autogen/runtime_logging.py +161 -0
- autogen/testing/__init__.py +12 -0
- autogen/testing/messages.py +45 -0
- autogen/testing/test_agent.py +111 -0
- autogen/token_count_utils.py +280 -0
- autogen/tools/__init__.py +20 -0
- autogen/tools/contrib/__init__.py +9 -0
- autogen/tools/contrib/time/__init__.py +7 -0
- autogen/tools/contrib/time/time.py +40 -0
- autogen/tools/dependency_injection.py +249 -0
- autogen/tools/experimental/__init__.py +54 -0
- autogen/tools/experimental/browser_use/__init__.py +7 -0
- autogen/tools/experimental/browser_use/browser_use.py +154 -0
- autogen/tools/experimental/code_execution/__init__.py +7 -0
- autogen/tools/experimental/code_execution/python_code_execution.py +86 -0
- autogen/tools/experimental/crawl4ai/__init__.py +7 -0
- autogen/tools/experimental/crawl4ai/crawl4ai.py +150 -0
- autogen/tools/experimental/deep_research/__init__.py +7 -0
- autogen/tools/experimental/deep_research/deep_research.py +329 -0
- autogen/tools/experimental/duckduckgo/__init__.py +7 -0
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +103 -0
- autogen/tools/experimental/firecrawl/__init__.py +7 -0
- autogen/tools/experimental/firecrawl/firecrawl_tool.py +836 -0
- autogen/tools/experimental/google/__init__.py +14 -0
- autogen/tools/experimental/google/authentication/__init__.py +11 -0
- autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
- autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
- autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
- autogen/tools/experimental/google/drive/__init__.py +9 -0
- autogen/tools/experimental/google/drive/drive_functions.py +124 -0
- autogen/tools/experimental/google/drive/toolkit.py +88 -0
- autogen/tools/experimental/google/model.py +17 -0
- autogen/tools/experimental/google/toolkit_protocol.py +19 -0
- autogen/tools/experimental/google_search/__init__.py +8 -0
- autogen/tools/experimental/google_search/google_search.py +93 -0
- autogen/tools/experimental/google_search/youtube_search.py +181 -0
- autogen/tools/experimental/messageplatform/__init__.py +17 -0
- autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/discord/discord.py +284 -0
- autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/slack/slack.py +385 -0
- autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/telegram/telegram.py +271 -0
- autogen/tools/experimental/perplexity/__init__.py +7 -0
- autogen/tools/experimental/perplexity/perplexity_search.py +249 -0
- autogen/tools/experimental/reliable/__init__.py +10 -0
- autogen/tools/experimental/reliable/reliable.py +1311 -0
- autogen/tools/experimental/searxng/__init__.py +7 -0
- autogen/tools/experimental/searxng/searxng_search.py +142 -0
- autogen/tools/experimental/tavily/__init__.py +7 -0
- autogen/tools/experimental/tavily/tavily_search.py +176 -0
- autogen/tools/experimental/web_search_preview/__init__.py +7 -0
- autogen/tools/experimental/web_search_preview/web_search_preview.py +120 -0
- autogen/tools/experimental/wikipedia/__init__.py +7 -0
- autogen/tools/experimental/wikipedia/wikipedia.py +284 -0
- autogen/tools/function_utils.py +412 -0
- autogen/tools/tool.py +188 -0
- autogen/tools/toolkit.py +86 -0
- autogen/types.py +29 -0
- autogen/version.py +7 -0
- templates/client_template/main.jinja2 +72 -0
- templates/config_template/config.jinja2 +7 -0
- templates/main.jinja2 +61 -0
|
@@ -0,0 +1,349 @@
|
|
|
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 collections.abc import AsyncIterator
|
|
7
|
+
from contextlib import AbstractAsyncContextManager, AsyncExitStack, asynccontextmanager
|
|
8
|
+
from datetime import datetime, timedelta
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Annotated, Any, Literal, Protocol, cast
|
|
11
|
+
|
|
12
|
+
import anyio
|
|
13
|
+
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
|
|
14
|
+
from mcp.client.session import ClientSession
|
|
15
|
+
from mcp.client.sse import sse_client
|
|
16
|
+
from mcp.client.stdio import StdioServerParameters, stdio_client
|
|
17
|
+
from pydantic import AnyUrl, BaseModel, Field
|
|
18
|
+
|
|
19
|
+
from ..doc_utils import export_module
|
|
20
|
+
from ..import_utils import optional_import_block, require_optional_import
|
|
21
|
+
from ..tools import Tool, Toolkit
|
|
22
|
+
|
|
23
|
+
with optional_import_block():
|
|
24
|
+
from mcp.shared.message import SessionMessage
|
|
25
|
+
from mcp.types import CallToolResult, ReadResourceResult, ResourceTemplate, TextContent
|
|
26
|
+
from mcp.types import Tool as MCPTool
|
|
27
|
+
|
|
28
|
+
__all__ = ["ResultSaved", "create_toolkit"]
|
|
29
|
+
|
|
30
|
+
# Type definitions
|
|
31
|
+
EncodingErrorHandlerType = Literal["strict", "ignore", "replace"]
|
|
32
|
+
|
|
33
|
+
# Default constants
|
|
34
|
+
DEFAULT_TEXT_ENCODING = "utf-8"
|
|
35
|
+
DEFAULT_TEXT_ENCODING_ERROR_HANDLER: EncodingErrorHandlerType = "strict"
|
|
36
|
+
DEFAULT_HTTP_REQUEST_TIMEOUT = 5
|
|
37
|
+
DEFAULT_SSE_EVENT_READ_TIMEOUT = 60 * 5
|
|
38
|
+
DEFAULT_STREAMABLE_HTTP_REQUEST_TIMEOUT = timedelta(seconds=30)
|
|
39
|
+
DEFAULT_STREAMABLE_HTTP_SSE_EVENT_READ_TIMEOUT = timedelta(seconds=60 * 5)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SessionConfigProtocol(Protocol):
|
|
43
|
+
"""Protocol for session configuration classes that can create MCP sessions."""
|
|
44
|
+
|
|
45
|
+
server_name: str
|
|
46
|
+
|
|
47
|
+
@asynccontextmanager
|
|
48
|
+
async def create_session(self, exit_stack: AsyncExitStack) -> AsyncIterator[ClientSession]:
|
|
49
|
+
"""Create a session using the given exit stack."""
|
|
50
|
+
try:
|
|
51
|
+
yield cast(ClientSession, None) # placeholder yield to satisfy AsyncIterator type
|
|
52
|
+
except Exception:
|
|
53
|
+
raise NotImplementedError
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class BasicSessionConfig(BaseModel):
|
|
57
|
+
"""Basic session configuration."""
|
|
58
|
+
|
|
59
|
+
server_name: str = Field(..., description="Name of the server")
|
|
60
|
+
|
|
61
|
+
async def initialize(
|
|
62
|
+
self,
|
|
63
|
+
client: AbstractAsyncContextManager[
|
|
64
|
+
tuple[
|
|
65
|
+
MemoryObjectReceiveStream[SessionMessage | Exception],
|
|
66
|
+
MemoryObjectSendStream[SessionMessage],
|
|
67
|
+
]
|
|
68
|
+
],
|
|
69
|
+
exit_stack: AsyncExitStack,
|
|
70
|
+
) -> ClientSession:
|
|
71
|
+
"""Initialize the session."""
|
|
72
|
+
reader, writer = await exit_stack.enter_async_context(client)
|
|
73
|
+
session = cast(
|
|
74
|
+
ClientSession,
|
|
75
|
+
await exit_stack.enter_async_context(ClientSession(reader, writer)),
|
|
76
|
+
)
|
|
77
|
+
return session
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class SseConfig(BasicSessionConfig):
|
|
81
|
+
"""Configuration for a single SSE MCP server."""
|
|
82
|
+
|
|
83
|
+
url: str = Field(..., description="URL of the SSE server")
|
|
84
|
+
headers: dict[str, Any] | None = Field(default=None, description="HTTP headers to send to the SSE endpoint")
|
|
85
|
+
timeout: float = Field(default=DEFAULT_HTTP_REQUEST_TIMEOUT, description="HTTP timeout")
|
|
86
|
+
sse_read_timeout: float = Field(default=DEFAULT_SSE_EVENT_READ_TIMEOUT, description="SSE read timeout")
|
|
87
|
+
|
|
88
|
+
@asynccontextmanager
|
|
89
|
+
async def create_session(self, exit_stack: AsyncExitStack) -> AsyncIterator[ClientSession]:
|
|
90
|
+
"""
|
|
91
|
+
Create a new session to an MCP server using SSE transport.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
exit_stack: AsyncExitStack for managing async resources
|
|
95
|
+
|
|
96
|
+
Yields:
|
|
97
|
+
ClientSession: The MCP client session
|
|
98
|
+
"""
|
|
99
|
+
# Create and store the connection
|
|
100
|
+
client = sse_client(self.url, self.headers, self.timeout, self.sse_read_timeout)
|
|
101
|
+
yield await self.initialize(client, exit_stack)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class StdioConfig(BasicSessionConfig):
|
|
105
|
+
"""Configuration for a single stdio MCP server."""
|
|
106
|
+
|
|
107
|
+
command: str = Field(..., description="Command to execute")
|
|
108
|
+
args: list[str] = Field(..., description="Arguments for the command")
|
|
109
|
+
transport: Literal["stdio"] = Field(default="stdio", description="Transport type")
|
|
110
|
+
environment: dict[str, str] | None = Field(default=None, description="Environment variables")
|
|
111
|
+
working_dir: str | Path | None = Field(default=None, description="Working directory")
|
|
112
|
+
encoding: str = Field(default=DEFAULT_TEXT_ENCODING, description="Character encoding")
|
|
113
|
+
encoding_error_handler: EncodingErrorHandlerType = Field(
|
|
114
|
+
default=DEFAULT_TEXT_ENCODING_ERROR_HANDLER, description="How to handle encoding errors"
|
|
115
|
+
)
|
|
116
|
+
session_options: dict[str, Any] | None = Field(default=None, description="Additional session options")
|
|
117
|
+
|
|
118
|
+
@asynccontextmanager
|
|
119
|
+
async def create_session(self, exit_stack: AsyncExitStack) -> AsyncIterator[ClientSession]:
|
|
120
|
+
"""
|
|
121
|
+
Create a new session to an MCP server using stdio transport.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
exit_stack: AsyncExitStack for managing async resources
|
|
125
|
+
|
|
126
|
+
Yields:
|
|
127
|
+
ClientSession: The MCP client session
|
|
128
|
+
"""
|
|
129
|
+
client = stdio_client(
|
|
130
|
+
StdioServerParameters(
|
|
131
|
+
command=self.command,
|
|
132
|
+
args=self.args,
|
|
133
|
+
env=self.environment,
|
|
134
|
+
encoding=self.encoding,
|
|
135
|
+
encoding_error_handler=self.encoding_error_handler,
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
yield await self.initialize(client, exit_stack)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class MCPConfig(BaseModel):
|
|
142
|
+
"""Configuration for multiple MCP sessions using stdio transport."""
|
|
143
|
+
|
|
144
|
+
# we should use final classes to allow pydantic to validate the type
|
|
145
|
+
servers: list[SseConfig | StdioConfig] = Field(..., description="List of stdio & sse server configurations")
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class MCPClient:
|
|
149
|
+
@staticmethod
|
|
150
|
+
def _convert_call_tool_result( # type: ignore[no-any-unimported]
|
|
151
|
+
call_tool_result: "CallToolResult", # type: ignore[no-any-unimported]
|
|
152
|
+
) -> tuple[str | list[str], Any]:
|
|
153
|
+
text_contents: list[TextContent] = [] # type: ignore[no-any-unimported]
|
|
154
|
+
non_text_contents = []
|
|
155
|
+
for content in call_tool_result.content:
|
|
156
|
+
if isinstance(content, TextContent):
|
|
157
|
+
text_contents.append(content)
|
|
158
|
+
else:
|
|
159
|
+
non_text_contents.append(content)
|
|
160
|
+
|
|
161
|
+
tool_content: str | list[str] = [content.text for content in text_contents]
|
|
162
|
+
if len(text_contents) == 1:
|
|
163
|
+
tool_content = tool_content[0]
|
|
164
|
+
|
|
165
|
+
if call_tool_result.isError:
|
|
166
|
+
raise ValueError(f"Tool call failed: {tool_content}")
|
|
167
|
+
|
|
168
|
+
return tool_content, non_text_contents or None
|
|
169
|
+
|
|
170
|
+
@classmethod
|
|
171
|
+
@require_optional_import("mcp", "mcp")
|
|
172
|
+
def convert_tool( # type: ignore[no-any-unimported]
|
|
173
|
+
cls, tool: Any, session: "ClientSession", **kwargs: Any
|
|
174
|
+
) -> Tool:
|
|
175
|
+
if not isinstance(tool, MCPTool):
|
|
176
|
+
raise ValueError(f"Expected an instance of `mcp.types.Tool`, got {type(tool)}")
|
|
177
|
+
|
|
178
|
+
# needed for type checking
|
|
179
|
+
mcp_tool: MCPTool = tool # type: ignore[no-any-unimported]
|
|
180
|
+
|
|
181
|
+
async def call_tool( # type: ignore[no-any-unimported]
|
|
182
|
+
**arguments: dict[str, Any],
|
|
183
|
+
) -> tuple[str | list[str], Any]:
|
|
184
|
+
call_tool_result = await session.call_tool(tool.name, arguments)
|
|
185
|
+
return MCPClient._convert_call_tool_result(call_tool_result)
|
|
186
|
+
|
|
187
|
+
ag2_tool = Tool(
|
|
188
|
+
name=mcp_tool.name,
|
|
189
|
+
description=mcp_tool.description,
|
|
190
|
+
func_or_tool=call_tool,
|
|
191
|
+
parameters_json_schema=mcp_tool.inputSchema,
|
|
192
|
+
)
|
|
193
|
+
return ag2_tool
|
|
194
|
+
|
|
195
|
+
@classmethod
|
|
196
|
+
@require_optional_import("mcp", "mcp")
|
|
197
|
+
def convert_resource( # type: ignore[no-any-unimported]
|
|
198
|
+
cls,
|
|
199
|
+
resource_template: Any,
|
|
200
|
+
session: "ClientSession",
|
|
201
|
+
resource_download_folder: Path | None,
|
|
202
|
+
**kwargs: Any,
|
|
203
|
+
) -> Tool:
|
|
204
|
+
if not isinstance(resource_template, ResourceTemplate):
|
|
205
|
+
raise ValueError(f"Expected an instance of `mcp.types.ResourceTemplate`, got {type(resource_template)}")
|
|
206
|
+
|
|
207
|
+
# needed for type checking
|
|
208
|
+
mcp_resource: ResourceTemplate = resource_template # type: ignore[no-any-unimported]
|
|
209
|
+
|
|
210
|
+
uri_description = f"""A URI template (according to RFC 6570) that can be used to construct resource URIs.
|
|
211
|
+
Here is the correct format for the URI template:
|
|
212
|
+
{mcp_resource.uriTemplate}
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
async def call_resource(uri: Annotated[str, uri_description]) -> ReadResourceResult | ResultSaved: # type: ignore[no-any-unimported]
|
|
216
|
+
result = await session.read_resource(AnyUrl(uri))
|
|
217
|
+
|
|
218
|
+
if not resource_download_folder:
|
|
219
|
+
return result
|
|
220
|
+
|
|
221
|
+
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
|
|
222
|
+
filename = uri.split("://")[-1] + f"_{timestamp}"
|
|
223
|
+
file_path = resource_download_folder / filename
|
|
224
|
+
|
|
225
|
+
async with await anyio.open_file(file_path, "w") as f:
|
|
226
|
+
await f.write(result.model_dump_json(indent=4))
|
|
227
|
+
|
|
228
|
+
return ResultSaved(
|
|
229
|
+
explanation=f"Request for uri {uri} was saved to {file_path}",
|
|
230
|
+
file_path=file_path,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Wrap resource as AG2 tool
|
|
234
|
+
ag2_tool = Tool(
|
|
235
|
+
name=mcp_resource.name,
|
|
236
|
+
description=mcp_resource.description,
|
|
237
|
+
func_or_tool=call_resource,
|
|
238
|
+
)
|
|
239
|
+
return ag2_tool
|
|
240
|
+
|
|
241
|
+
@classmethod
|
|
242
|
+
@require_optional_import("mcp", "mcp")
|
|
243
|
+
async def load_mcp_toolkit(
|
|
244
|
+
cls,
|
|
245
|
+
session: "ClientSession",
|
|
246
|
+
*,
|
|
247
|
+
use_mcp_tools: bool,
|
|
248
|
+
use_mcp_resources: bool,
|
|
249
|
+
resource_download_folder: Path | None,
|
|
250
|
+
) -> Toolkit: # type: ignore[no-any-unimported]
|
|
251
|
+
"""Load all available MCP tools and convert them to AG2 Toolkit."""
|
|
252
|
+
all_ag2_tools: list[Tool] = []
|
|
253
|
+
|
|
254
|
+
if use_mcp_tools:
|
|
255
|
+
tools = await session.list_tools()
|
|
256
|
+
ag2_tools: list[Tool] = [cls.convert_tool(tool=tool, session=session) for tool in tools.tools]
|
|
257
|
+
all_ag2_tools.extend(ag2_tools)
|
|
258
|
+
|
|
259
|
+
if use_mcp_resources:
|
|
260
|
+
resource_templates = await session.list_resource_templates()
|
|
261
|
+
ag2_resources: list[Tool] = [
|
|
262
|
+
cls.convert_resource(
|
|
263
|
+
resource_template=resource_template,
|
|
264
|
+
session=session,
|
|
265
|
+
resource_download_folder=resource_download_folder,
|
|
266
|
+
)
|
|
267
|
+
for resource_template in resource_templates.resourceTemplates
|
|
268
|
+
]
|
|
269
|
+
all_ag2_tools.extend(ag2_resources)
|
|
270
|
+
|
|
271
|
+
return Toolkit(tools=all_ag2_tools)
|
|
272
|
+
|
|
273
|
+
@classmethod
|
|
274
|
+
def get_unsupported_reason(cls) -> str | None:
|
|
275
|
+
with optional_import_block() as result:
|
|
276
|
+
import mcp # noqa: F401
|
|
277
|
+
|
|
278
|
+
if not result.is_successful:
|
|
279
|
+
return "Please install `mcp` extra to use this module:\n\n\tpip install ag2[mcp]"
|
|
280
|
+
|
|
281
|
+
return None
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class MCPClientSessionManager:
|
|
285
|
+
"""
|
|
286
|
+
A class to manage MCP client sessions.
|
|
287
|
+
"""
|
|
288
|
+
|
|
289
|
+
def __init__(self) -> None:
|
|
290
|
+
"""Initialize the MCP client session manager."""
|
|
291
|
+
self.exit_stack = AsyncExitStack()
|
|
292
|
+
self.sessions: dict[str, ClientSession] = {}
|
|
293
|
+
|
|
294
|
+
@asynccontextmanager
|
|
295
|
+
async def open_session(
|
|
296
|
+
self,
|
|
297
|
+
config: SessionConfigProtocol,
|
|
298
|
+
) -> AsyncIterator[ClientSession]:
|
|
299
|
+
"""Open a new session to an MCP server based on configuration.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
config: SessionConfigProtocol object containing session configuration
|
|
303
|
+
|
|
304
|
+
Yields:
|
|
305
|
+
ClientSession: The MCP client session
|
|
306
|
+
"""
|
|
307
|
+
async with config.create_session(self.exit_stack) as session:
|
|
308
|
+
await session.initialize()
|
|
309
|
+
self.sessions[config.server_name] = session
|
|
310
|
+
yield session
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@export_module("autogen.mcp")
|
|
314
|
+
async def create_toolkit(
|
|
315
|
+
session: "ClientSession",
|
|
316
|
+
*,
|
|
317
|
+
use_mcp_tools: bool = True,
|
|
318
|
+
use_mcp_resources: bool = True,
|
|
319
|
+
resource_download_folder: Path | str | None = None,
|
|
320
|
+
) -> Toolkit: # type: ignore[no-any-unimported]
|
|
321
|
+
"""Create a toolkit from the MCP client session.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
session (ClientSession): The MCP client session.
|
|
325
|
+
use_mcp_tools (bool): Whether to include MCP tools in the toolkit.
|
|
326
|
+
use_mcp_resources (bool): Whether to include MCP resources in the toolkit.
|
|
327
|
+
resource_download_folder (Optional[Union[Path, str]]): The folder to download files to.
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
Toolkit: The toolkit containing the converted tools.
|
|
331
|
+
"""
|
|
332
|
+
if resource_download_folder is not None:
|
|
333
|
+
resource_download_folder = Path(resource_download_folder)
|
|
334
|
+
await anyio.to_thread.run_sync(lambda: resource_download_folder.mkdir(parents=True, exist_ok=True))
|
|
335
|
+
|
|
336
|
+
return await MCPClient.load_mcp_toolkit(
|
|
337
|
+
session=session,
|
|
338
|
+
use_mcp_tools=use_mcp_tools,
|
|
339
|
+
use_mcp_resources=use_mcp_resources,
|
|
340
|
+
resource_download_folder=resource_download_folder,
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
@export_module("autogen.mcp.mcp_client")
|
|
345
|
+
class ResultSaved(BaseModel):
|
|
346
|
+
"""Result saved to a file"""
|
|
347
|
+
|
|
348
|
+
explanation: str
|
|
349
|
+
file_path: Path
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from autogen.import_utils import optional_import_block
|
|
6
|
+
|
|
7
|
+
from .patch_fastapi_code_generator import ( # noqa: E402
|
|
8
|
+
SUCCESFUL_IMPORT,
|
|
9
|
+
patch_function_name_parsing,
|
|
10
|
+
patch_generate_code,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
if SUCCESFUL_IMPORT:
|
|
14
|
+
patch_function_name_parsing()
|
|
15
|
+
patch_generate_code()
|
|
16
|
+
|
|
17
|
+
from .mcp_proxy import MCPProxy # noqa: E402
|
|
18
|
+
|
|
19
|
+
__all__ = ["MCPProxy", "optional_import_block"]
|
|
@@ -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
|
+
from collections.abc import Iterator
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
from functools import cached_property
|
|
7
|
+
|
|
8
|
+
from ...import_utils import optional_import_block
|
|
9
|
+
|
|
10
|
+
with optional_import_block() as result:
|
|
11
|
+
from fastapi_code_generator.parser import (
|
|
12
|
+
Argument,
|
|
13
|
+
OpenAPIParser,
|
|
14
|
+
ParameterObject,
|
|
15
|
+
ReferenceObject,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
SUCCESFUL_IMPORT = result.is_successful
|
|
19
|
+
|
|
20
|
+
__all__ = ["SUCCESFUL_IMPORT", "patch_get_parameter_type"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@contextmanager
|
|
24
|
+
def patch_get_parameter_type() -> Iterator[None]:
|
|
25
|
+
class ArgumentWithDescription(Argument): # type: ignore[misc]
|
|
26
|
+
description: str | None = None
|
|
27
|
+
|
|
28
|
+
@cached_property
|
|
29
|
+
def argument(self) -> str:
|
|
30
|
+
if self.description:
|
|
31
|
+
description = self.description.replace('"""', '"""')
|
|
32
|
+
type_hint = f'Annotated[{self.type_hint}, """{description}"""]'
|
|
33
|
+
else:
|
|
34
|
+
type_hint = self.type_hint
|
|
35
|
+
|
|
36
|
+
if self.default is None and self.required:
|
|
37
|
+
return f"{self.name}: {type_hint}"
|
|
38
|
+
|
|
39
|
+
return f"{self.name}: {type_hint} = {self.default}"
|
|
40
|
+
|
|
41
|
+
original_get_parameter_type = OpenAPIParser.get_parameter_type
|
|
42
|
+
|
|
43
|
+
def get_parameter_type(
|
|
44
|
+
self: OpenAPIParser,
|
|
45
|
+
parameters: ReferenceObject | ParameterObject,
|
|
46
|
+
snake_case: bool,
|
|
47
|
+
path: list[str],
|
|
48
|
+
) -> Argument | None:
|
|
49
|
+
# get the original argument
|
|
50
|
+
argument = original_get_parameter_type(self, parameters, snake_case, path)
|
|
51
|
+
|
|
52
|
+
# add description to the argument
|
|
53
|
+
parameters = self.resolve_object(parameters, ParameterObject)
|
|
54
|
+
argument_with_description = ArgumentWithDescription(description=parameters.description, **argument.model_dump())
|
|
55
|
+
return argument_with_description
|
|
56
|
+
|
|
57
|
+
OpenAPIParser.get_parameter_type = get_parameter_type
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
yield
|
|
61
|
+
finally:
|
|
62
|
+
OpenAPIParser.get_parameter_type = original_get_parameter_type
|