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,405 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
+
# SPDX-License-Identifier: MIT
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
import warnings
|
|
13
|
+
from hashlib import md5
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from string import Template
|
|
16
|
+
from types import SimpleNamespace
|
|
17
|
+
from typing import Any, Callable, ClassVar, Optional, Union
|
|
18
|
+
|
|
19
|
+
from typing_extensions import ParamSpec
|
|
20
|
+
|
|
21
|
+
from ..code_utils import PYTHON_VARIANTS, TIMEOUT_MSG, WIN32, _cmd
|
|
22
|
+
from ..doc_utils import export_module
|
|
23
|
+
from .base import CodeBlock, CodeExecutor, CodeExtractor, CommandLineCodeResult
|
|
24
|
+
from .func_with_reqs import (
|
|
25
|
+
FunctionWithRequirements,
|
|
26
|
+
FunctionWithRequirementsStr,
|
|
27
|
+
_build_python_functions_file,
|
|
28
|
+
to_stub,
|
|
29
|
+
)
|
|
30
|
+
from .markdown_code_extractor import MarkdownCodeExtractor
|
|
31
|
+
from .utils import _get_file_name_from_content, silence_pip
|
|
32
|
+
|
|
33
|
+
__all__ = ("LocalCommandLineCodeExecutor",)
|
|
34
|
+
|
|
35
|
+
A = ParamSpec("A")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@export_module("autogen.coding")
|
|
39
|
+
class LocalCommandLineCodeExecutor(CodeExecutor):
|
|
40
|
+
SUPPORTED_LANGUAGES: ClassVar[list[str]] = [
|
|
41
|
+
"bash",
|
|
42
|
+
"shell",
|
|
43
|
+
"sh",
|
|
44
|
+
"pwsh",
|
|
45
|
+
"powershell",
|
|
46
|
+
"ps1",
|
|
47
|
+
"python",
|
|
48
|
+
"javascript",
|
|
49
|
+
"html",
|
|
50
|
+
"css",
|
|
51
|
+
]
|
|
52
|
+
DEFAULT_EXECUTION_POLICY: ClassVar[dict[str, bool]] = {
|
|
53
|
+
"bash": True,
|
|
54
|
+
"shell": True,
|
|
55
|
+
"sh": True,
|
|
56
|
+
"pwsh": True,
|
|
57
|
+
"powershell": True,
|
|
58
|
+
"ps1": True,
|
|
59
|
+
"python": True,
|
|
60
|
+
"javascript": False,
|
|
61
|
+
"html": False,
|
|
62
|
+
"css": False,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
FUNCTION_PROMPT_TEMPLATE: ClassVar[
|
|
66
|
+
str
|
|
67
|
+
] = """You have access to the following user defined functions. They can be accessed from the module called `$module_name` by their function names.
|
|
68
|
+
|
|
69
|
+
For example, if there was a function called `foo` you could import it by writing `from $module_name import foo`
|
|
70
|
+
|
|
71
|
+
$functions"""
|
|
72
|
+
|
|
73
|
+
def __init__(
|
|
74
|
+
self,
|
|
75
|
+
timeout: int = 60,
|
|
76
|
+
virtual_env_context: Optional[SimpleNamespace] = None,
|
|
77
|
+
work_dir: Union[Path, str] = Path(),
|
|
78
|
+
functions: list[Union[FunctionWithRequirements[Any, A], Callable[..., Any], FunctionWithRequirementsStr]] = [],
|
|
79
|
+
functions_module: str = "functions",
|
|
80
|
+
execution_policies: Optional[dict[str, bool]] = None,
|
|
81
|
+
):
|
|
82
|
+
"""(Experimental) A code executor class that executes or saves LLM generated code a local command line
|
|
83
|
+
environment.
|
|
84
|
+
|
|
85
|
+
**This will execute or save LLM generated code on the local machine.**
|
|
86
|
+
|
|
87
|
+
Each code block is saved as a file in the working directory. Depending on the execution policy,
|
|
88
|
+
the code may be executed in a separate process.
|
|
89
|
+
The code blocks are executed or save in the order they are received.
|
|
90
|
+
Command line code is sanitized against a list of dangerous commands to prevent self-destructive commands from being executed,
|
|
91
|
+
which could potentially affect the user's environment. Supported languages include Python, shell scripts (bash, shell, sh),
|
|
92
|
+
PowerShell (pwsh, powershell, ps1), HTML, CSS, and JavaScript.
|
|
93
|
+
Execution policies determine whether each language's code blocks are executed or saved only.
|
|
94
|
+
|
|
95
|
+
## Execution with a Python virtual environment
|
|
96
|
+
A python virtual env can be used to execute code and install dependencies. This has the added benefit of not polluting the
|
|
97
|
+
base environment with unwanted modules.
|
|
98
|
+
```python
|
|
99
|
+
from autogen.code_utils import create_virtual_env
|
|
100
|
+
from autogen.coding import LocalCommandLineCodeExecutor
|
|
101
|
+
|
|
102
|
+
venv_dir = ".venv"
|
|
103
|
+
venv_context = create_virtual_env(venv_dir)
|
|
104
|
+
|
|
105
|
+
executor = LocalCommandLineCodeExecutor(virtual_env_context=venv_context)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
timeout (int): The timeout for code execution, default is 60 seconds.
|
|
110
|
+
virtual_env_context (Optional[SimpleNamespace]): The virtual environment context to use.
|
|
111
|
+
work_dir (Union[Path, str]): The working directory for code execution, defaults to the current directory.
|
|
112
|
+
functions (List[Union[FunctionWithRequirements[Any, A], Callable[..., Any], FunctionWithRequirementsStr]]): A list of callable functions available to the executor.
|
|
113
|
+
functions_module (str): The module name under which functions are accessible.
|
|
114
|
+
execution_policies (Optional[Dict[str, bool]]): A dictionary mapping languages to execution policies (True for execution, False for saving only). Defaults to class-wide DEFAULT_EXECUTION_POLICY.
|
|
115
|
+
"""
|
|
116
|
+
if timeout < 1:
|
|
117
|
+
raise ValueError("Timeout must be greater than or equal to 1.")
|
|
118
|
+
|
|
119
|
+
if isinstance(work_dir, str):
|
|
120
|
+
work_dir = Path(work_dir)
|
|
121
|
+
|
|
122
|
+
if not functions_module.isidentifier():
|
|
123
|
+
raise ValueError("Module name must be a valid Python identifier")
|
|
124
|
+
|
|
125
|
+
self._functions_module = functions_module
|
|
126
|
+
|
|
127
|
+
work_dir.mkdir(exist_ok=True)
|
|
128
|
+
|
|
129
|
+
self._timeout = timeout
|
|
130
|
+
self._work_dir: Path = work_dir
|
|
131
|
+
self._virtual_env_context: Optional[SimpleNamespace] = virtual_env_context
|
|
132
|
+
|
|
133
|
+
self._functions = functions
|
|
134
|
+
# Setup could take some time so we intentionally wait for the first code block to do it.
|
|
135
|
+
if len(functions) > 0:
|
|
136
|
+
self._setup_functions_complete = False
|
|
137
|
+
else:
|
|
138
|
+
self._setup_functions_complete = True
|
|
139
|
+
|
|
140
|
+
self.execution_policies = self.DEFAULT_EXECUTION_POLICY.copy()
|
|
141
|
+
if execution_policies is not None:
|
|
142
|
+
self.execution_policies.update(execution_policies)
|
|
143
|
+
|
|
144
|
+
def format_functions_for_prompt(self, prompt_template: str = FUNCTION_PROMPT_TEMPLATE) -> str:
|
|
145
|
+
"""(Experimental) Format the functions for a prompt.
|
|
146
|
+
|
|
147
|
+
The template includes two variables:
|
|
148
|
+
- `$module_name`: The module name.
|
|
149
|
+
- `$functions`: The functions formatted as stubs with two newlines between each function.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
prompt_template (str): The prompt template. Default is the class default.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
str: The formatted prompt.
|
|
156
|
+
"""
|
|
157
|
+
template = Template(prompt_template)
|
|
158
|
+
return template.substitute(
|
|
159
|
+
module_name=self._functions_module,
|
|
160
|
+
functions="\n\n".join([to_stub(func) for func in self._functions]),
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def functions_module(self) -> str:
|
|
165
|
+
"""(Experimental) The module name for the functions."""
|
|
166
|
+
return self._functions_module
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def functions(
|
|
170
|
+
self,
|
|
171
|
+
) -> list[Union[FunctionWithRequirements[Any, A], Callable[..., Any], FunctionWithRequirementsStr]]:
|
|
172
|
+
"""(Experimental) The functions that are available to the code executor."""
|
|
173
|
+
return self._functions
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def timeout(self) -> int:
|
|
177
|
+
"""(Experimental) The timeout for code execution."""
|
|
178
|
+
return self._timeout
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def work_dir(self) -> Path:
|
|
182
|
+
"""(Experimental) The working directory for the code execution."""
|
|
183
|
+
return self._work_dir
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def code_extractor(self) -> CodeExtractor:
|
|
187
|
+
"""(Experimental) Export a code extractor that can be used by an agent."""
|
|
188
|
+
return MarkdownCodeExtractor()
|
|
189
|
+
|
|
190
|
+
@staticmethod
|
|
191
|
+
def sanitize_command(lang: str, code: str) -> None:
|
|
192
|
+
"""Sanitize the code block to prevent dangerous commands.
|
|
193
|
+
This approach acknowledges that while Docker or similar
|
|
194
|
+
containerization/sandboxing technologies provide a robust layer of security,
|
|
195
|
+
not all users may have Docker installed or may choose not to use it.
|
|
196
|
+
Therefore, having a baseline level of protection helps mitigate risks for users who,
|
|
197
|
+
either out of choice or necessity, run code outside of a sandboxed environment.
|
|
198
|
+
"""
|
|
199
|
+
dangerous_patterns = [
|
|
200
|
+
(r"\brm\s+-rf\b", "Use of 'rm -rf' command is not allowed."),
|
|
201
|
+
(r"\bmv\b.*?\s+/dev/null", "Moving files to /dev/null is not allowed."),
|
|
202
|
+
(r"\bdd\b", "Use of 'dd' command is not allowed."),
|
|
203
|
+
(r">\s*/dev/sd[a-z][1-9]?", "Overwriting disk blocks directly is not allowed."),
|
|
204
|
+
(r":\(\)\{\s*:\|\:&\s*\};:", "Fork bombs are not allowed."),
|
|
205
|
+
]
|
|
206
|
+
if lang in ["bash", "shell", "sh"]:
|
|
207
|
+
for pattern, message in dangerous_patterns:
|
|
208
|
+
if re.search(pattern, code):
|
|
209
|
+
raise ValueError(f"Potentially dangerous command detected: {message}")
|
|
210
|
+
|
|
211
|
+
def _setup_functions(self) -> None:
|
|
212
|
+
func_file_content = _build_python_functions_file(self._functions)
|
|
213
|
+
func_file = self._work_dir / f"{self._functions_module}.py"
|
|
214
|
+
func_file.write_text(func_file_content)
|
|
215
|
+
|
|
216
|
+
# Collect requirements
|
|
217
|
+
lists_of_packages = [x.python_packages for x in self._functions if isinstance(x, FunctionWithRequirements)]
|
|
218
|
+
flattened_packages = [item for sublist in lists_of_packages for item in sublist]
|
|
219
|
+
required_packages = list(set(flattened_packages))
|
|
220
|
+
if len(required_packages) > 0:
|
|
221
|
+
logging.info("Ensuring packages are installed in executor.")
|
|
222
|
+
py_executable = self._virtual_env_context.env_exe if self._virtual_env_context else sys.executable
|
|
223
|
+
cmd = [py_executable, "-m", "pip", "install"] + required_packages
|
|
224
|
+
try:
|
|
225
|
+
result = subprocess.run(
|
|
226
|
+
cmd,
|
|
227
|
+
cwd=self._work_dir,
|
|
228
|
+
capture_output=True,
|
|
229
|
+
text=True,
|
|
230
|
+
timeout=float(self._timeout),
|
|
231
|
+
encoding="utf-8",
|
|
232
|
+
)
|
|
233
|
+
except subprocess.TimeoutExpired as e:
|
|
234
|
+
raise ValueError("Pip install timed out") from e
|
|
235
|
+
if result.returncode != 0:
|
|
236
|
+
raise ValueError(f"Pip install failed. {result.stdout}, {result.stderr}")
|
|
237
|
+
# Attempt to load the function file to check for syntax errors, imports etc.
|
|
238
|
+
exec_result = self._execute_code_dont_check_setup([CodeBlock(code=func_file_content, language="python")])
|
|
239
|
+
if exec_result.exit_code != 0:
|
|
240
|
+
raise ValueError(f"Functions failed to load: {exec_result.output}")
|
|
241
|
+
self._setup_functions_complete = True
|
|
242
|
+
|
|
243
|
+
def execute_code_blocks(self, code_blocks: list[CodeBlock]) -> CommandLineCodeResult:
|
|
244
|
+
"""(Experimental) Execute the code blocks and return the result.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
code_blocks (List[CodeBlock]): The code blocks to execute.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
CommandLineCodeResult: The result of the code execution.
|
|
251
|
+
"""
|
|
252
|
+
if not self._setup_functions_complete:
|
|
253
|
+
self._setup_functions()
|
|
254
|
+
return self._execute_code_dont_check_setup(code_blocks)
|
|
255
|
+
|
|
256
|
+
def _execute_code_dont_check_setup(self, code_blocks: list[CodeBlock]) -> CommandLineCodeResult:
|
|
257
|
+
logs_all = ""
|
|
258
|
+
file_names = []
|
|
259
|
+
for code_block in code_blocks:
|
|
260
|
+
lang, code = code_block.language, code_block.code
|
|
261
|
+
lang = lang.lower()
|
|
262
|
+
|
|
263
|
+
LocalCommandLineCodeExecutor.sanitize_command(lang, code)
|
|
264
|
+
code = silence_pip(code, lang)
|
|
265
|
+
|
|
266
|
+
if lang in PYTHON_VARIANTS:
|
|
267
|
+
lang = "python"
|
|
268
|
+
|
|
269
|
+
if WIN32 and lang in ["sh", "shell"]:
|
|
270
|
+
lang = "ps1"
|
|
271
|
+
|
|
272
|
+
if lang not in self.SUPPORTED_LANGUAGES:
|
|
273
|
+
# In case the language is not supported, we return an error message.
|
|
274
|
+
exitcode = 1
|
|
275
|
+
logs_all += "\n" + f"unknown language {lang}"
|
|
276
|
+
break
|
|
277
|
+
|
|
278
|
+
execute_code = self.execution_policies.get(lang, False)
|
|
279
|
+
try:
|
|
280
|
+
# Check if there is a filename comment
|
|
281
|
+
filename = _get_file_name_from_content(code, self._work_dir)
|
|
282
|
+
except ValueError:
|
|
283
|
+
return CommandLineCodeResult(exit_code=1, output="Filename is not in the workspace")
|
|
284
|
+
|
|
285
|
+
if filename is None:
|
|
286
|
+
# create a file with an automatically generated name
|
|
287
|
+
code_hash = md5(code.encode()).hexdigest()
|
|
288
|
+
filename = f"tmp_code_{code_hash}.{'py' if lang.startswith('python') else lang}"
|
|
289
|
+
written_file = (self._work_dir / filename).resolve()
|
|
290
|
+
with written_file.open("w", encoding="utf-8") as f:
|
|
291
|
+
f.write(code)
|
|
292
|
+
file_names.append(written_file)
|
|
293
|
+
|
|
294
|
+
if not execute_code:
|
|
295
|
+
# Just return a message that the file is saved.
|
|
296
|
+
logs_all += f"Code saved to {written_file!s}\n"
|
|
297
|
+
exitcode = 0
|
|
298
|
+
continue
|
|
299
|
+
|
|
300
|
+
program = _cmd(lang)
|
|
301
|
+
cmd = [program, str(written_file.absolute())]
|
|
302
|
+
env = os.environ.copy()
|
|
303
|
+
|
|
304
|
+
if self._virtual_env_context:
|
|
305
|
+
virtual_env_abs_path = os.path.abspath(self._virtual_env_context.bin_path)
|
|
306
|
+
path_with_virtualenv = rf"{virtual_env_abs_path}{os.pathsep}{env['PATH']}"
|
|
307
|
+
env["PATH"] = path_with_virtualenv
|
|
308
|
+
if WIN32:
|
|
309
|
+
activation_script = os.path.join(virtual_env_abs_path, "activate.bat")
|
|
310
|
+
cmd = [activation_script, "&&", *cmd]
|
|
311
|
+
|
|
312
|
+
try:
|
|
313
|
+
result = subprocess.run(
|
|
314
|
+
cmd,
|
|
315
|
+
cwd=self._work_dir,
|
|
316
|
+
capture_output=True,
|
|
317
|
+
text=True,
|
|
318
|
+
timeout=float(self._timeout),
|
|
319
|
+
env=env,
|
|
320
|
+
encoding="utf-8",
|
|
321
|
+
)
|
|
322
|
+
except subprocess.TimeoutExpired:
|
|
323
|
+
logs_all += "\n" + TIMEOUT_MSG
|
|
324
|
+
# Same exit code as the timeout command on linux.
|
|
325
|
+
exitcode = 124
|
|
326
|
+
break
|
|
327
|
+
|
|
328
|
+
logs_all += result.stderr
|
|
329
|
+
logs_all += result.stdout
|
|
330
|
+
exitcode = result.returncode
|
|
331
|
+
|
|
332
|
+
if exitcode != 0:
|
|
333
|
+
break
|
|
334
|
+
|
|
335
|
+
code_file = str(file_names[0]) if len(file_names) > 0 else None
|
|
336
|
+
return CommandLineCodeResult(exit_code=exitcode, output=logs_all, code_file=code_file)
|
|
337
|
+
|
|
338
|
+
def restart(self) -> None:
|
|
339
|
+
"""(Experimental) Restart the code executor."""
|
|
340
|
+
warnings.warn("Restarting local command line code executor is not supported. No action is taken.")
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
# From stack overflow: https://stackoverflow.com/a/52087847/2214524
|
|
344
|
+
class _DeprecatedClassMeta(type):
|
|
345
|
+
def __new__(cls, name, bases, classdict, *args, **kwargs): # type: ignore[no-untyped-def]
|
|
346
|
+
alias = classdict.get("_DeprecatedClassMeta__alias")
|
|
347
|
+
|
|
348
|
+
if alias is not None:
|
|
349
|
+
|
|
350
|
+
def new(cls, *args, **kwargs): # type: ignore[no-untyped-def]
|
|
351
|
+
alias = cls._DeprecatedClassMeta__alias
|
|
352
|
+
|
|
353
|
+
if alias is not None:
|
|
354
|
+
warnings.warn(
|
|
355
|
+
f"{cls.__name__} has been renamed to {alias.__name__}, the alias will be removed in the future",
|
|
356
|
+
DeprecationWarning,
|
|
357
|
+
stacklevel=2,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
return alias(*args, **kwargs)
|
|
361
|
+
|
|
362
|
+
classdict["__new__"] = new
|
|
363
|
+
classdict["_DeprecatedClassMeta__alias"] = alias
|
|
364
|
+
|
|
365
|
+
fixed_bases = []
|
|
366
|
+
|
|
367
|
+
for b in bases:
|
|
368
|
+
alias = getattr(b, "_DeprecatedClassMeta__alias", None)
|
|
369
|
+
|
|
370
|
+
if alias is not None:
|
|
371
|
+
warnings.warn(
|
|
372
|
+
f"{b.__name__} has been renamed to {alias.__name__}, the alias will be removed in the future",
|
|
373
|
+
DeprecationWarning,
|
|
374
|
+
stacklevel=2,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
# Avoid duplicate base classes.
|
|
378
|
+
b = alias or b
|
|
379
|
+
if b not in fixed_bases:
|
|
380
|
+
fixed_bases.append(b)
|
|
381
|
+
|
|
382
|
+
fixed_bases = tuple(fixed_bases) # type: ignore[assignment]
|
|
383
|
+
|
|
384
|
+
return super().__new__(cls, name, fixed_bases, classdict, *args, **kwargs) # type: ignore[call-overload]
|
|
385
|
+
|
|
386
|
+
def __instancecheck__(cls, instance): # type: ignore[no-untyped-def]
|
|
387
|
+
return any(cls.__subclasscheck__(c) for c in {type(instance), instance.__class__}) # type: ignore[no-untyped-call]
|
|
388
|
+
|
|
389
|
+
def __subclasscheck__(cls, subclass): # type: ignore[no-untyped-def]
|
|
390
|
+
if subclass is cls:
|
|
391
|
+
return True
|
|
392
|
+
else:
|
|
393
|
+
return issubclass(subclass, cls._DeprecatedClassMeta__alias) # type: ignore[attr-defined]
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
class LocalCommandlineCodeExecutor(metaclass=_DeprecatedClassMeta):
|
|
397
|
+
"""LocalCommandlineCodeExecutor renamed to LocalCommandLineCodeExecutor"""
|
|
398
|
+
|
|
399
|
+
_DeprecatedClassMeta__alias = LocalCommandLineCodeExecutor
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
class CommandlineCodeResult(metaclass=_DeprecatedClassMeta):
|
|
403
|
+
"""CommandlineCodeResult renamed to CommandLineCodeResult"""
|
|
404
|
+
|
|
405
|
+
_DeprecatedClassMeta__alias = CommandLineCodeResult
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
+
# SPDX-License-Identifier: MIT
|
|
7
|
+
import re
|
|
8
|
+
from typing import Union
|
|
9
|
+
|
|
10
|
+
from ..code_utils import CODE_BLOCK_PATTERN, UNKNOWN, content_str, infer_lang
|
|
11
|
+
from ..doc_utils import export_module
|
|
12
|
+
from ..types import UserMessageImageContentPart, UserMessageTextContentPart
|
|
13
|
+
from .base import CodeBlock, CodeExtractor
|
|
14
|
+
|
|
15
|
+
__all__ = ("MarkdownCodeExtractor",)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@export_module("autogen.coding")
|
|
19
|
+
class MarkdownCodeExtractor(CodeExtractor):
|
|
20
|
+
"""(Experimental) A class that extracts code blocks from a message using Markdown syntax."""
|
|
21
|
+
|
|
22
|
+
def extract_code_blocks(
|
|
23
|
+
self, message: Union[str, list[Union[UserMessageTextContentPart, UserMessageImageContentPart]], None]
|
|
24
|
+
) -> list[CodeBlock]:
|
|
25
|
+
"""(Experimental) Extract code blocks from a message. If no code blocks are found,
|
|
26
|
+
return an empty list.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
message (str): The message to extract code blocks from.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
List[CodeBlock]: The extracted code blocks or an empty list.
|
|
33
|
+
"""
|
|
34
|
+
text = content_str(message)
|
|
35
|
+
match = re.findall(CODE_BLOCK_PATTERN, text, flags=re.DOTALL)
|
|
36
|
+
if not match:
|
|
37
|
+
return []
|
|
38
|
+
code_blocks = []
|
|
39
|
+
for lang, code in match:
|
|
40
|
+
if lang == "":
|
|
41
|
+
lang = infer_lang(code)
|
|
42
|
+
if lang == UNKNOWN:
|
|
43
|
+
lang = ""
|
|
44
|
+
code_blocks.append(CodeBlock(code=code, language=lang))
|
|
45
|
+
return code_blocks
|
autogen/coding/utils.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Portions derived from https://github.com/ag2ai/ag2 are under the MIT License.
|
|
6
|
+
# SPDX-License-Identifier: MIT
|
|
7
|
+
# Will return the filename relative to the workspace path
|
|
8
|
+
import re
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
filename_patterns = [
|
|
13
|
+
re.compile(r"^<!-- (filename:)?(.+?) -->", re.DOTALL),
|
|
14
|
+
re.compile(r"^/\* (filename:)?(.+?) \*/", re.DOTALL),
|
|
15
|
+
re.compile(r"^// (filename:)?(.+?)$", re.DOTALL),
|
|
16
|
+
re.compile(r"^# (filename:)?(.+?)$", re.DOTALL),
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Raises ValueError if the file is not in the workspace
|
|
21
|
+
def _get_file_name_from_content(code: str, workspace_path: Path) -> Optional[str]:
|
|
22
|
+
first_line = code.split("\n")[0].strip()
|
|
23
|
+
# TODO - support other languages
|
|
24
|
+
for pattern in filename_patterns:
|
|
25
|
+
matches = pattern.match(first_line)
|
|
26
|
+
if matches is not None:
|
|
27
|
+
filename = matches.group(2).strip()
|
|
28
|
+
|
|
29
|
+
# Handle relative paths in the filename
|
|
30
|
+
path = Path(filename)
|
|
31
|
+
if not path.is_absolute():
|
|
32
|
+
path = workspace_path / path
|
|
33
|
+
path = path.resolve()
|
|
34
|
+
# Throws an error if the file is not in the workspace
|
|
35
|
+
relative = path.relative_to(workspace_path.resolve())
|
|
36
|
+
return str(relative)
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def silence_pip(code: str, lang: str) -> str:
|
|
41
|
+
"""Apply -qqq flag to pip install commands."""
|
|
42
|
+
if lang == "python":
|
|
43
|
+
regex = r"^! ?pip install"
|
|
44
|
+
elif lang in ["bash", "shell", "sh", "pwsh", "powershell", "ps1"]:
|
|
45
|
+
regex = r"^pip install"
|
|
46
|
+
else:
|
|
47
|
+
return code
|
|
48
|
+
|
|
49
|
+
# Find lines that start with pip install and make sure "-qqq" flag is added.
|
|
50
|
+
lines = code.split("\n")
|
|
51
|
+
for i, line in enumerate(lines):
|
|
52
|
+
# use regex to find lines that start with pip install.
|
|
53
|
+
match = re.search(regex, line)
|
|
54
|
+
if match is not None and "-qqq" not in line:
|
|
55
|
+
lines[i] = line.replace(match.group(0), match.group(0) + " -qqq")
|
|
56
|
+
return "\n".join(lines)
|
autogen/doc_utils.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
__all__ = ["export_module"]
|
|
6
|
+
|
|
7
|
+
from typing import Callable, Optional, TypeVar
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T")
|
|
10
|
+
|
|
11
|
+
# Global dictionary to store export module mappings
|
|
12
|
+
# Key: original symbol name (qualified by module)
|
|
13
|
+
# Value: target module where it should be documented
|
|
14
|
+
_PDOC_MODULE_EXPORT_MAPPINGS: dict[str, str] = {}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def export_module(module: str) -> Callable[[T], T]:
|
|
18
|
+
def decorator(cls: T) -> T:
|
|
19
|
+
original_module = getattr(cls, "__module__", None)
|
|
20
|
+
if original_module:
|
|
21
|
+
fqn = f"{original_module}.{cls.__name__}"
|
|
22
|
+
_PDOC_MODULE_EXPORT_MAPPINGS[fqn] = module
|
|
23
|
+
return cls
|
|
24
|
+
|
|
25
|
+
return decorator
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_target_module(obj: object) -> Optional[str]:
|
|
29
|
+
"""Get the target module where an object should be documented."""
|
|
30
|
+
if not hasattr(obj, "__module__"):
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
fqn = f"{obj.__module__}.{obj.__name__}"
|
|
34
|
+
return _PDOC_MODULE_EXPORT_MAPPINGS.get(fqn)
|
|
@@ -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
|
+
from .base_event import BaseEvent, get_annotated_type_for_event_classes, wrap_event
|
|
5
|
+
from .helpers import deprecated_by
|
|
6
|
+
|
|
7
|
+
__all__ = ["BaseEvent", "deprecated_by", "get_annotated_type_for_event_classes", "wrap_event"]
|