ag2 0.9.1a1__py3-none-any.whl → 0.9.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.
Potentially problematic release.
This version of ag2 might be problematic. Click here for more details.
- {ag2-0.9.1a1.dist-info → ag2-0.9.2.dist-info}/METADATA +272 -75
- ag2-0.9.2.dist-info/RECORD +406 -0
- {ag2-0.9.1a1.dist-info → ag2-0.9.2.dist-info}/WHEEL +1 -2
- autogen/__init__.py +89 -0
- autogen/_website/__init__.py +3 -0
- autogen/_website/generate_api_references.py +427 -0
- autogen/_website/generate_mkdocs.py +1174 -0
- autogen/_website/notebook_processor.py +476 -0
- autogen/_website/process_notebooks.py +656 -0
- autogen/_website/utils.py +412 -0
- autogen/agentchat/__init__.py +44 -0
- autogen/agentchat/agent.py +182 -0
- autogen/agentchat/assistant_agent.py +85 -0
- autogen/agentchat/chat.py +309 -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 +429 -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 +566 -0
- autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
- autogen/agentchat/contrib/capabilities/vision_capability.py +214 -0
- autogen/agentchat/contrib/captainagent/__init__.py +9 -0
- autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
- autogen/agentchat/contrib/captainagent/captainagent.py +512 -0
- autogen/agentchat/contrib/captainagent/tool_retriever.py +335 -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 +170 -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 +268 -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 +187 -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 +324 -0
- autogen/agentchat/contrib/rag/__init__.py +10 -0
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +272 -0
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +198 -0
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +329 -0
- autogen/agentchat/contrib/rag/query_engine.py +74 -0
- autogen/agentchat/contrib/retrieve_assistant_agent.py +56 -0
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +703 -0
- autogen/agentchat/contrib/society_of_mind_agent.py +199 -0
- autogen/agentchat/contrib/swarm_agent.py +1425 -0
- autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
- autogen/agentchat/contrib/vectordb/__init__.py +5 -0
- autogen/agentchat/contrib/vectordb/base.py +232 -0
- autogen/agentchat/contrib/vectordb/chromadb.py +315 -0
- autogen/agentchat/contrib/vectordb/couchbase.py +407 -0
- autogen/agentchat/contrib/vectordb/mongodb.py +550 -0
- autogen/agentchat/contrib/vectordb/pgvectordb.py +928 -0
- autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
- autogen/agentchat/contrib/vectordb/utils.py +126 -0
- autogen/agentchat/contrib/web_surfer.py +303 -0
- autogen/agentchat/conversable_agent.py +4023 -0
- autogen/agentchat/group/__init__.py +64 -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 +41 -0
- autogen/agentchat/group/context_variables.py +192 -0
- autogen/agentchat/group/group_tool_executor.py +202 -0
- autogen/agentchat/group/group_utils.py +591 -0
- autogen/agentchat/group/handoffs.py +244 -0
- autogen/agentchat/group/llm_condition.py +93 -0
- autogen/agentchat/group/multi_agent_chat.py +237 -0
- autogen/agentchat/group/on_condition.py +58 -0
- autogen/agentchat/group/on_context_condition.py +54 -0
- autogen/agentchat/group/patterns/__init__.py +18 -0
- autogen/agentchat/group/patterns/auto.py +159 -0
- autogen/agentchat/group/patterns/manual.py +176 -0
- autogen/agentchat/group/patterns/pattern.py +288 -0
- autogen/agentchat/group/patterns/random.py +106 -0
- autogen/agentchat/group/patterns/round_robin.py +117 -0
- autogen/agentchat/group/reply_result.py +26 -0
- autogen/agentchat/group/speaker_selection_result.py +41 -0
- autogen/agentchat/group/targets/__init__.py +4 -0
- autogen/agentchat/group/targets/group_chat_target.py +132 -0
- autogen/agentchat/group/targets/group_manager_target.py +151 -0
- autogen/agentchat/group/targets/transition_target.py +413 -0
- autogen/agentchat/group/targets/transition_utils.py +6 -0
- autogen/agentchat/groupchat.py +1694 -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 +190 -0
- autogen/agentchat/realtime/experimental/function_observer.py +85 -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 +475 -0
- autogen/agentchat/realtime/experimental/websockets.py +21 -0
- autogen/agentchat/realtime_agent/__init__.py +21 -0
- autogen/agentchat/user_proxy_agent.py +111 -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 +73 -0
- autogen/agents/contrib/time/time_tool_agent.py +51 -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 +316 -0
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +118 -0
- autogen/agents/experimental/document_agent/document_agent.py +461 -0
- autogen/agents/experimental/document_agent/document_conditions.py +50 -0
- autogen/agents/experimental/document_agent/document_utils.py +380 -0
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +220 -0
- autogen/agents/experimental/document_agent/parser_utils.py +130 -0
- autogen/agents/experimental/document_agent/url_utils.py +426 -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 +77 -0
- autogen/agents/experimental/websurfer/__init__.py +7 -0
- autogen/agents/experimental/websurfer/websurfer.py +62 -0
- autogen/agents/experimental/wikipedia/__init__.py +7 -0
- autogen/agents/experimental/wikipedia/wikipedia.py +90 -0
- autogen/browser_utils.py +309 -0
- autogen/cache/__init__.py +10 -0
- autogen/cache/abstract_cache_base.py +75 -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 +102 -0
- autogen/cache/in_memory_cache.py +58 -0
- autogen/cache/redis_cache.py +123 -0
- autogen/code_utils.py +596 -0
- autogen/coding/__init__.py +22 -0
- autogen/coding/base.py +119 -0
- autogen/coding/docker_commandline_code_executor.py +268 -0
- autogen/coding/factory.py +47 -0
- autogen/coding/func_with_reqs.py +202 -0
- autogen/coding/jupyter/__init__.py +23 -0
- autogen/coding/jupyter/base.py +36 -0
- autogen/coding/jupyter/docker_jupyter_server.py +167 -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 +231 -0
- autogen/coding/jupyter/jupyter_code_executor.py +160 -0
- autogen/coding/jupyter/local_jupyter_server.py +172 -0
- autogen/coding/local_commandline_code_executor.py +405 -0
- autogen/coding/markdown_code_extractor.py +45 -0
- autogen/coding/utils.py +56 -0
- autogen/doc_utils.py +34 -0
- autogen/events/__init__.py +7 -0
- autogen/events/agent_events.py +1013 -0
- autogen/events/base_event.py +99 -0
- autogen/events/client_events.py +167 -0
- autogen/events/helpers.py +36 -0
- autogen/events/print_event.py +46 -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 +80 -0
- autogen/fast_depends/core/__init__.py +14 -0
- autogen/fast_depends/core/build.py +225 -0
- autogen/fast_depends/core/model.py +576 -0
- autogen/fast_depends/dependencies/__init__.py +15 -0
- autogen/fast_depends/dependencies/model.py +29 -0
- autogen/fast_depends/dependencies/provider.py +39 -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 +280 -0
- autogen/fast_depends/utils.py +187 -0
- autogen/formatting_utils.py +83 -0
- autogen/function_utils.py +13 -0
- autogen/graph_utils.py +178 -0
- autogen/import_utils.py +526 -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 +155 -0
- autogen/interop/langchain/langchain_tool.py +82 -0
- autogen/interop/litellm/__init__.py +7 -0
- autogen/interop/litellm/litellm_config_factory.py +179 -0
- autogen/interop/pydantic_ai/__init__.py +7 -0
- autogen/interop/pydantic_ai/pydantic_ai.py +168 -0
- autogen/interop/registry.py +69 -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 +56 -0
- autogen/io/run_response.py +293 -0
- autogen/io/thread_io_stream.py +63 -0
- autogen/io/websockets.py +213 -0
- autogen/json_utils.py +43 -0
- autogen/llm_config.py +382 -0
- autogen/logger/__init__.py +11 -0
- autogen/logger/base_logger.py +128 -0
- autogen/logger/file_logger.py +261 -0
- autogen/logger/logger_factory.py +42 -0
- autogen/logger/logger_utils.py +57 -0
- autogen/logger/sqlite_logger.py +523 -0
- autogen/math_utils.py +339 -0
- autogen/mcp/__init__.py +7 -0
- autogen/mcp/__main__.py +78 -0
- autogen/mcp/mcp_client.py +208 -0
- autogen/mcp/mcp_proxy/__init__.py +19 -0
- autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +63 -0
- autogen/mcp/mcp_proxy/mcp_proxy.py +581 -0
- autogen/mcp/mcp_proxy/operation_grouping.py +158 -0
- autogen/mcp/mcp_proxy/operation_renaming.py +114 -0
- autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
- autogen/mcp/mcp_proxy/security.py +400 -0
- autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
- autogen/messages/__init__.py +7 -0
- autogen/messages/agent_messages.py +948 -0
- autogen/messages/base_message.py +107 -0
- autogen/messages/client_messages.py +171 -0
- autogen/messages/print_message.py +49 -0
- autogen/oai/__init__.py +53 -0
- autogen/oai/anthropic.py +714 -0
- autogen/oai/bedrock.py +628 -0
- autogen/oai/cerebras.py +299 -0
- autogen/oai/client.py +1444 -0
- autogen/oai/client_utils.py +169 -0
- autogen/oai/cohere.py +479 -0
- autogen/oai/gemini.py +998 -0
- autogen/oai/gemini_types.py +155 -0
- autogen/oai/groq.py +305 -0
- autogen/oai/mistral.py +303 -0
- autogen/oai/oai_models/__init__.py +11 -0
- autogen/oai/oai_models/_models.py +16 -0
- autogen/oai/oai_models/chat_completion.py +87 -0
- autogen/oai/oai_models/chat_completion_audio.py +32 -0
- autogen/oai/oai_models/chat_completion_message.py +86 -0
- autogen/oai/oai_models/chat_completion_message_tool_call.py +37 -0
- autogen/oai/oai_models/chat_completion_token_logprob.py +63 -0
- autogen/oai/oai_models/completion_usage.py +60 -0
- autogen/oai/ollama.py +643 -0
- autogen/oai/openai_utils.py +881 -0
- autogen/oai/together.py +370 -0
- autogen/retrieve_utils.py +491 -0
- autogen/runtime_logging.py +160 -0
- autogen/token_count_utils.py +267 -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 +41 -0
- autogen/tools/dependency_injection.py +254 -0
- autogen/tools/experimental/__init__.py +48 -0
- autogen/tools/experimental/browser_use/__init__.py +7 -0
- autogen/tools/experimental/browser_use/browser_use.py +161 -0
- autogen/tools/experimental/crawl4ai/__init__.py +7 -0
- autogen/tools/experimental/crawl4ai/crawl4ai.py +153 -0
- autogen/tools/experimental/deep_research/__init__.py +7 -0
- autogen/tools/experimental/deep_research/deep_research.py +328 -0
- autogen/tools/experimental/duckduckgo/__init__.py +7 -0
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +109 -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 +288 -0
- autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/slack/slack.py +391 -0
- autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/telegram/telegram.py +275 -0
- autogen/tools/experimental/perplexity/__init__.py +7 -0
- autogen/tools/experimental/perplexity/perplexity_search.py +260 -0
- autogen/tools/experimental/reliable/__init__.py +10 -0
- autogen/tools/experimental/reliable/reliable.py +1316 -0
- autogen/tools/experimental/tavily/__init__.py +7 -0
- autogen/tools/experimental/tavily/tavily_search.py +183 -0
- autogen/tools/experimental/web_search_preview/__init__.py +7 -0
- autogen/tools/experimental/web_search_preview/web_search_preview.py +114 -0
- autogen/tools/experimental/wikipedia/__init__.py +7 -0
- autogen/tools/experimental/wikipedia/wikipedia.py +287 -0
- autogen/tools/function_utils.py +411 -0
- autogen/tools/tool.py +187 -0
- autogen/tools/toolkit.py +86 -0
- autogen/types.py +29 -0
- autogen/version.py +7 -0
- templates/client_template/main.jinja2 +69 -0
- templates/config_template/config.jinja2 +7 -0
- templates/main.jinja2 +61 -0
- ag2-0.9.1a1.dist-info/RECORD +0 -6
- ag2-0.9.1a1.dist-info/top_level.txt +0 -1
- {ag2-0.9.1a1.dist-info → ag2-0.9.2.dist-info/licenses}/LICENSE +0 -0
- {ag2-0.9.1a1.dist-info → ag2-0.9.2.dist-info/licenses}/NOTICE.md +0 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import base64
|
|
5
|
+
import json
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Any, ClassVar, Literal, Optional
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
from pydantic import BaseModel, model_validator
|
|
11
|
+
from typing_extensions import TypeAlias
|
|
12
|
+
|
|
13
|
+
# Get the logger
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
logger.setLevel(logging.DEBUG)
|
|
16
|
+
|
|
17
|
+
BaseSecurityType: TypeAlias = type["BaseSecurity"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BaseSecurity(BaseModel):
|
|
21
|
+
"""Base class for security classes."""
|
|
22
|
+
|
|
23
|
+
type: ClassVar[Literal["apiKey", "http", "mutualTLS", "oauth2", "openIdConnect", "unsupported"]]
|
|
24
|
+
in_value: ClassVar[Literal["header", "query", "cookie", "bearer", "basic", "tls", "unsupported"]]
|
|
25
|
+
name: str
|
|
26
|
+
|
|
27
|
+
@model_validator(mode="after") # type: ignore[misc]
|
|
28
|
+
def __post_init__(
|
|
29
|
+
self,
|
|
30
|
+
) -> "BaseSecurity": # dataclasses uses __post_init__ instead of model_validator
|
|
31
|
+
"""Validate the in_value based on the type."""
|
|
32
|
+
valid_in_values = {
|
|
33
|
+
"apiKey": ["header", "query", "cookie"],
|
|
34
|
+
"http": ["bearer", "basic"],
|
|
35
|
+
"oauth2": ["bearer"],
|
|
36
|
+
"openIdConnect": ["bearer"],
|
|
37
|
+
"mutualTLS": ["tls"],
|
|
38
|
+
"unsupported": ["unsupported"],
|
|
39
|
+
}
|
|
40
|
+
if self.in_value not in valid_in_values[self.type]:
|
|
41
|
+
raise ValueError(f"Invalid in_value '{self.in_value}' for type '{self.type}'")
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def accept(self, security_params: "BaseSecurityParameters") -> bool:
|
|
45
|
+
return isinstance(self, security_params.get_security_class())
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def is_supported(cls, type: str, schema_parameters: dict[str, Any]) -> bool:
|
|
49
|
+
return cls.type == type and cls.in_value == schema_parameters.get("in")
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def get_security_class(cls, type: str, schema_parameters: dict[str, Any]) -> BaseSecurityType:
|
|
53
|
+
sub_classes = cls.__subclasses__()
|
|
54
|
+
|
|
55
|
+
for sub_class in sub_classes:
|
|
56
|
+
if sub_class.is_supported(type, schema_parameters):
|
|
57
|
+
return sub_class
|
|
58
|
+
|
|
59
|
+
logger.error(f"Unsupported type '{type}' and schema_parameters '{schema_parameters}' combination")
|
|
60
|
+
return UnsuportedSecurityStub
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def get_security_parameters(cls, schema_parameters: dict[str, Any]) -> str:
|
|
64
|
+
return f'{cls.__name__}(name="{schema_parameters.get("name")}")'
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
def parse_security_parameters(cls, unparsed_params: dict[str, Any]) -> "BaseSecurityParameters":
|
|
68
|
+
type = unparsed_params.pop("type")
|
|
69
|
+
schema_parameters = unparsed_params.pop("schema_parameters")
|
|
70
|
+
security_class = cls.get_security_class(type, schema_parameters)
|
|
71
|
+
return security_class.Parameters.model_validate(unparsed_params)
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def parse_security_parameters_from_env(cls, env: dict[str, str]) -> "BaseSecurityParameters":
|
|
75
|
+
"""Parse security parameters from environment variables."""
|
|
76
|
+
security_str = env.get("SECURITY")
|
|
77
|
+
if not security_str:
|
|
78
|
+
logger.warning("No security parameters found in environment variables.")
|
|
79
|
+
|
|
80
|
+
return cls.parse_security_parameters(json.loads(security_str))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class BaseSecurityParameters(BaseModel):
|
|
84
|
+
"""Base class for security parameters."""
|
|
85
|
+
|
|
86
|
+
def apply(
|
|
87
|
+
self,
|
|
88
|
+
q_params: dict[str, Any],
|
|
89
|
+
body_dict: dict[str, Any],
|
|
90
|
+
security: BaseSecurity,
|
|
91
|
+
) -> None: ...
|
|
92
|
+
|
|
93
|
+
def get_security_class(self) -> type[BaseSecurity]: ...
|
|
94
|
+
|
|
95
|
+
def dump(self) -> dict[str, Any]:
|
|
96
|
+
raise NotImplementedError("Subclasses must implement the dump method")
|
|
97
|
+
|
|
98
|
+
def to_env(self) -> dict[str, Any]:
|
|
99
|
+
"""Convert the security parameters to a dictionary."""
|
|
100
|
+
return {
|
|
101
|
+
"SECURITY": json.dumps(self.dump()),
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class UnsuportedSecurityStub(BaseSecurity):
|
|
106
|
+
"""Unsupported security stub class."""
|
|
107
|
+
|
|
108
|
+
type: ClassVar[Literal["unsupported"]] = "unsupported"
|
|
109
|
+
in_value: ClassVar[Literal["unsupported"]] = "unsupported"
|
|
110
|
+
|
|
111
|
+
@classmethod
|
|
112
|
+
def is_supported(cls, type: str, schema_parameters: dict[str, Any]) -> bool:
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
def accept(self, security_params: "BaseSecurityParameters") -> bool:
|
|
116
|
+
if isinstance(self, security_params.get_security_class()):
|
|
117
|
+
raise RuntimeError("Trying to set UnsuportedSecurityStub params")
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
121
|
+
"""API Key Header security parameters class."""
|
|
122
|
+
|
|
123
|
+
def apply(
|
|
124
|
+
self,
|
|
125
|
+
q_params: dict[str, Any],
|
|
126
|
+
body_dict: dict[str, Any],
|
|
127
|
+
security: BaseSecurity,
|
|
128
|
+
) -> None:
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
132
|
+
return UnsuportedSecurityStub
|
|
133
|
+
|
|
134
|
+
def dump(self) -> dict[str, Any]:
|
|
135
|
+
return {
|
|
136
|
+
"type": "unsupported",
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class APIKeyHeader(BaseSecurity):
|
|
141
|
+
"""API Key Header security class."""
|
|
142
|
+
|
|
143
|
+
type: ClassVar[Literal["apiKey"]] = "apiKey"
|
|
144
|
+
in_value: ClassVar[Literal["header"]] = "header"
|
|
145
|
+
|
|
146
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
147
|
+
"""API Key Header security parameters class."""
|
|
148
|
+
|
|
149
|
+
value: str = "API_KEY"
|
|
150
|
+
|
|
151
|
+
def apply(
|
|
152
|
+
self,
|
|
153
|
+
q_params: dict[str, Any],
|
|
154
|
+
body_dict: dict[str, Any],
|
|
155
|
+
security: BaseSecurity,
|
|
156
|
+
) -> None:
|
|
157
|
+
api_key_header: APIKeyHeader = security # type: ignore[assignment]
|
|
158
|
+
|
|
159
|
+
if "headers" not in body_dict:
|
|
160
|
+
body_dict["headers"] = {}
|
|
161
|
+
|
|
162
|
+
body_dict["headers"][api_key_header.name] = self.value
|
|
163
|
+
|
|
164
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
165
|
+
return APIKeyHeader
|
|
166
|
+
|
|
167
|
+
def dump(self) -> dict[str, Any]:
|
|
168
|
+
return {
|
|
169
|
+
"type": "apiKey",
|
|
170
|
+
"schema_parameters": {"in": "header"},
|
|
171
|
+
**self.model_dump(),
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class APIKeyQuery(BaseSecurity):
|
|
176
|
+
"""API Key Query security class."""
|
|
177
|
+
|
|
178
|
+
type: ClassVar[Literal["apiKey"]] = "apiKey"
|
|
179
|
+
in_value: ClassVar[Literal["query"]] = "query"
|
|
180
|
+
|
|
181
|
+
@classmethod
|
|
182
|
+
def is_supported(cls, type: str, schema_parameters: dict[str, Any]) -> bool:
|
|
183
|
+
return super().is_supported(type, schema_parameters)
|
|
184
|
+
|
|
185
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
186
|
+
"""API Key Query security parameters class."""
|
|
187
|
+
|
|
188
|
+
value: str = "API_KEY"
|
|
189
|
+
|
|
190
|
+
def apply(
|
|
191
|
+
self,
|
|
192
|
+
q_params: dict[str, Any],
|
|
193
|
+
body_dict: dict[str, Any],
|
|
194
|
+
security: BaseSecurity,
|
|
195
|
+
) -> None:
|
|
196
|
+
api_key_query: APIKeyQuery = security # type: ignore[assignment]
|
|
197
|
+
|
|
198
|
+
q_params[api_key_query.name] = self.value
|
|
199
|
+
|
|
200
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
201
|
+
return APIKeyQuery
|
|
202
|
+
|
|
203
|
+
def dump(self) -> dict[str, Any]:
|
|
204
|
+
return {
|
|
205
|
+
"type": "apiKey",
|
|
206
|
+
"schema_parameters": {"in": "query"},
|
|
207
|
+
**self.model_dump(),
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class APIKeyCookie(BaseSecurity):
|
|
212
|
+
"""API Key Cookie security class."""
|
|
213
|
+
|
|
214
|
+
type: ClassVar[Literal["apiKey"]] = "apiKey"
|
|
215
|
+
in_value: ClassVar[Literal["cookie"]] = "cookie"
|
|
216
|
+
|
|
217
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
218
|
+
"""API Key Cookie security parameters class."""
|
|
219
|
+
|
|
220
|
+
value: str = "API_KEY"
|
|
221
|
+
|
|
222
|
+
def apply(
|
|
223
|
+
self,
|
|
224
|
+
q_params: dict[str, Any],
|
|
225
|
+
body_dict: dict[str, Any],
|
|
226
|
+
security: BaseSecurity,
|
|
227
|
+
) -> None:
|
|
228
|
+
api_key_cookie: APIKeyCookie = security # type: ignore[assignment]
|
|
229
|
+
|
|
230
|
+
if "cookies" not in body_dict:
|
|
231
|
+
body_dict["cookies"] = {}
|
|
232
|
+
|
|
233
|
+
body_dict["cookies"][api_key_cookie.name] = self.value
|
|
234
|
+
|
|
235
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
236
|
+
return APIKeyCookie
|
|
237
|
+
|
|
238
|
+
def dump(self) -> dict[str, Any]:
|
|
239
|
+
return {
|
|
240
|
+
"type": "apiKey",
|
|
241
|
+
"schema_parameters": {"in": "cookie"},
|
|
242
|
+
**self.model_dump(),
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class HTTPBearer(BaseSecurity):
|
|
247
|
+
"""HTTP Bearer security class."""
|
|
248
|
+
|
|
249
|
+
type: ClassVar[Literal["http"]] = "http"
|
|
250
|
+
in_value: ClassVar[Literal["bearer"]] = "bearer"
|
|
251
|
+
|
|
252
|
+
@classmethod
|
|
253
|
+
def is_supported(cls, type: str, schema_parameters: dict[str, Any]) -> bool:
|
|
254
|
+
return cls.type == type and cls.in_value == schema_parameters.get("scheme")
|
|
255
|
+
|
|
256
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
257
|
+
"""HTTP Bearer security parameters class."""
|
|
258
|
+
|
|
259
|
+
value: str = "BEARER_TOKEN"
|
|
260
|
+
|
|
261
|
+
def apply(
|
|
262
|
+
self,
|
|
263
|
+
q_params: dict[str, Any],
|
|
264
|
+
body_dict: dict[str, Any],
|
|
265
|
+
security: BaseSecurity,
|
|
266
|
+
) -> None:
|
|
267
|
+
if "headers" not in body_dict:
|
|
268
|
+
body_dict["headers"] = {}
|
|
269
|
+
|
|
270
|
+
body_dict["headers"]["Authorization"] = f"Bearer {self.value}"
|
|
271
|
+
|
|
272
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
273
|
+
return HTTPBearer
|
|
274
|
+
|
|
275
|
+
def dump(self) -> dict[str, Any]:
|
|
276
|
+
return {
|
|
277
|
+
"type": "http",
|
|
278
|
+
"schema_parameters": {"scheme": "bearer"},
|
|
279
|
+
**self.model_dump(),
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class HTTPBasic(BaseSecurity):
|
|
284
|
+
"""HTTP Bearer security class."""
|
|
285
|
+
|
|
286
|
+
type: ClassVar[Literal["http"]] = "http"
|
|
287
|
+
in_value: ClassVar[Literal["basic"]] = "basic"
|
|
288
|
+
|
|
289
|
+
@classmethod
|
|
290
|
+
def is_supported(cls, type: str, schema_parameters: dict[str, Any]) -> bool:
|
|
291
|
+
return cls.type == type and cls.in_value == schema_parameters.get("scheme")
|
|
292
|
+
|
|
293
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
294
|
+
"""HTTP Basic security parameters class."""
|
|
295
|
+
|
|
296
|
+
username: str = "USERNAME"
|
|
297
|
+
password: str = "PASSWORD"
|
|
298
|
+
|
|
299
|
+
def apply(
|
|
300
|
+
self,
|
|
301
|
+
q_params: dict[str, Any],
|
|
302
|
+
body_dict: dict[str, Any],
|
|
303
|
+
security: BaseSecurity,
|
|
304
|
+
) -> None:
|
|
305
|
+
if "headers" not in body_dict:
|
|
306
|
+
body_dict["headers"] = {}
|
|
307
|
+
|
|
308
|
+
credentials = f"{self.username}:{self.password}"
|
|
309
|
+
encoded_credentials = base64.b64encode(credentials.encode("utf-8")).decode("utf-8")
|
|
310
|
+
|
|
311
|
+
body_dict["headers"]["Authorization"] = f"Basic {encoded_credentials}"
|
|
312
|
+
|
|
313
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
314
|
+
return HTTPBasic
|
|
315
|
+
|
|
316
|
+
def dump(self) -> dict[str, Any]:
|
|
317
|
+
return {
|
|
318
|
+
"type": "http",
|
|
319
|
+
"schema_parameters": {"scheme": "basic"},
|
|
320
|
+
**self.model_dump(),
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class OAuth2PasswordBearer(BaseSecurity):
|
|
325
|
+
"""OAuth2 Password Bearer security class."""
|
|
326
|
+
|
|
327
|
+
type: ClassVar[Literal["oauth2"]] = "oauth2"
|
|
328
|
+
in_value: ClassVar[Literal["bearer"]] = "bearer"
|
|
329
|
+
token_url: str
|
|
330
|
+
|
|
331
|
+
@classmethod
|
|
332
|
+
def is_supported(cls, type: str, schema_parameters: dict[str, Any]) -> bool:
|
|
333
|
+
return type == cls.type and "password" in schema_parameters.get("flows", {})
|
|
334
|
+
|
|
335
|
+
@classmethod
|
|
336
|
+
def get_security_parameters(cls, schema_parameters: dict[str, Any]) -> str:
|
|
337
|
+
name = schema_parameters.get("name")
|
|
338
|
+
token_url = f"{schema_parameters.get('server_url')}/{schema_parameters['flows']['password']['tokenUrl']}"
|
|
339
|
+
return f'{cls.__name__}(name="{name}", token_url="{token_url}")'
|
|
340
|
+
|
|
341
|
+
class Parameters(BaseSecurityParameters): # BaseSecurityParameters
|
|
342
|
+
"""OAuth2 Password Bearer security class."""
|
|
343
|
+
|
|
344
|
+
username: str = "USERNAME"
|
|
345
|
+
password: str = "PASSWORD"
|
|
346
|
+
bearer_token: Optional[str] = None
|
|
347
|
+
token_url: str = "TOKEN_URL"
|
|
348
|
+
|
|
349
|
+
# @model_validator(mode="before")
|
|
350
|
+
# def check_credentials(cls, values: dict[str, Any]) -> Any: # noqa
|
|
351
|
+
# username = values.get("username")
|
|
352
|
+
# password = values.get("password")
|
|
353
|
+
# bearer_token = values.get("bearer_token")
|
|
354
|
+
|
|
355
|
+
# if not bearer_token and (not username or not password):
|
|
356
|
+
# # If bearer_token is not provided, both username and password must be defined
|
|
357
|
+
# raise ValueError("Both username and password are required if bearer_token is not provided.")
|
|
358
|
+
|
|
359
|
+
# return values
|
|
360
|
+
|
|
361
|
+
def get_token(self, token_url: str) -> str:
|
|
362
|
+
# Get the token
|
|
363
|
+
request = requests.post(
|
|
364
|
+
token_url,
|
|
365
|
+
data={
|
|
366
|
+
"username": self.username,
|
|
367
|
+
"password": self.password,
|
|
368
|
+
},
|
|
369
|
+
timeout=5,
|
|
370
|
+
)
|
|
371
|
+
request.raise_for_status()
|
|
372
|
+
return request.json()["access_token"] # type: ignore
|
|
373
|
+
|
|
374
|
+
def apply(
|
|
375
|
+
self,
|
|
376
|
+
q_params: dict[str, Any],
|
|
377
|
+
body_dict: dict[str, Any],
|
|
378
|
+
security: BaseSecurity,
|
|
379
|
+
) -> None:
|
|
380
|
+
if not self.bearer_token:
|
|
381
|
+
if security.token_url is None: # type: ignore
|
|
382
|
+
raise ValueError("Token URL is not defined")
|
|
383
|
+
self.bearer_token = self.get_token(security.token_url) # type: ignore
|
|
384
|
+
|
|
385
|
+
if "headers" not in body_dict:
|
|
386
|
+
body_dict["headers"] = {}
|
|
387
|
+
|
|
388
|
+
body_dict["headers"]["Authorization"] = f"Bearer {self.bearer_token}"
|
|
389
|
+
|
|
390
|
+
def get_security_class(self) -> type[BaseSecurity]:
|
|
391
|
+
return OAuth2PasswordBearer
|
|
392
|
+
|
|
393
|
+
def dump(self) -> dict[str, Any]:
|
|
394
|
+
return {
|
|
395
|
+
"type": "oauth2",
|
|
396
|
+
"schema_parameters": {"flows": {"password": {"tokenUrl": self.token_url or ""}}},
|
|
397
|
+
"username": self.username,
|
|
398
|
+
"password": self.password,
|
|
399
|
+
"bearer_token": self.bearer_token,
|
|
400
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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 pathlib import Path
|
|
5
|
+
|
|
6
|
+
from autogen.import_utils import optional_import_block
|
|
7
|
+
from autogen.mcp.mcp_proxy.security import BaseSecurity
|
|
8
|
+
|
|
9
|
+
with optional_import_block() as result:
|
|
10
|
+
from fastapi_code_generator.parser import OpenAPIParser
|
|
11
|
+
from fastapi_code_generator.visitor import Visitor
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def custom_visitor(parser: "OpenAPIParser", model_path: Path) -> dict[str, object]:
|
|
15
|
+
if "components" not in parser.raw_obj or "securitySchemes" not in parser.raw_obj["components"]:
|
|
16
|
+
return {}
|
|
17
|
+
security_schemes = parser.raw_obj["components"]["securitySchemes"]
|
|
18
|
+
server_url = parser.raw_obj["servers"][0]["url"]
|
|
19
|
+
|
|
20
|
+
security_classes = []
|
|
21
|
+
security_parameters = {}
|
|
22
|
+
for k, v in security_schemes.items():
|
|
23
|
+
v["server_url"] = server_url
|
|
24
|
+
security_class = BaseSecurity.get_security_class(type=v["type"], schema_parameters=v)
|
|
25
|
+
|
|
26
|
+
security_classes.append(security_class.__name__)
|
|
27
|
+
|
|
28
|
+
security_parameters[k] = security_class.get_security_parameters(schema_parameters=v)
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
"security_schemes": security_schemes,
|
|
32
|
+
"security_classes": security_classes,
|
|
33
|
+
"security_parameters": security_parameters,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
visit: "Visitor" = custom_visitor
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from .base_message import BaseMessage, get_annotated_type_for_message_classes, wrap_message
|
|
6
|
+
|
|
7
|
+
__all__ = ["BaseMessage", "get_annotated_type_for_message_classes", "wrap_message"]
|