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,411 @@
|
|
|
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 functools
|
|
8
|
+
import inspect
|
|
9
|
+
import json
|
|
10
|
+
from logging import getLogger
|
|
11
|
+
from typing import Annotated, Any, Callable, ForwardRef, Optional, TypeVar, Union
|
|
12
|
+
|
|
13
|
+
from packaging.version import parse
|
|
14
|
+
from pydantic import BaseModel, Field, TypeAdapter
|
|
15
|
+
from pydantic import __version__ as pydantic_version
|
|
16
|
+
from pydantic.json_schema import JsonSchemaValue
|
|
17
|
+
from typing_extensions import Literal, get_args, get_origin
|
|
18
|
+
|
|
19
|
+
from ..doc_utils import export_module
|
|
20
|
+
from .dependency_injection import Field as AG2Field
|
|
21
|
+
|
|
22
|
+
if parse(pydantic_version) < parse("2.10.2"):
|
|
23
|
+
from pydantic._internal._typing_extra import eval_type_lenient as try_eval_type
|
|
24
|
+
else:
|
|
25
|
+
from pydantic._internal._typing_extra import try_eval_type
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = ["get_function_schema", "load_basemodels_if_needed", "serialize_to_str"]
|
|
29
|
+
|
|
30
|
+
logger = getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
T = TypeVar("T")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any:
|
|
36
|
+
"""Get the type annotation of a parameter.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
annotation: The annotation of the parameter
|
|
40
|
+
globalns: The global namespace of the function
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The type annotation of the parameter
|
|
44
|
+
"""
|
|
45
|
+
if isinstance(annotation, AG2Field):
|
|
46
|
+
annotation = annotation.description
|
|
47
|
+
if isinstance(annotation, str):
|
|
48
|
+
annotation = ForwardRef(annotation)
|
|
49
|
+
annotation, _ = try_eval_type(annotation, globalns, globalns)
|
|
50
|
+
return annotation
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
|
|
54
|
+
"""Get the signature of a function with type annotations.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
call: The function to get the signature for
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
The signature of the function with type annotations
|
|
61
|
+
"""
|
|
62
|
+
signature = inspect.signature(call)
|
|
63
|
+
globalns = getattr(call, "__globals__", {})
|
|
64
|
+
typed_params = [
|
|
65
|
+
inspect.Parameter(
|
|
66
|
+
name=param.name,
|
|
67
|
+
kind=param.kind,
|
|
68
|
+
default=param.default,
|
|
69
|
+
annotation=get_typed_annotation(param.annotation, globalns),
|
|
70
|
+
)
|
|
71
|
+
for param in signature.parameters.values()
|
|
72
|
+
]
|
|
73
|
+
typed_signature = inspect.Signature(typed_params)
|
|
74
|
+
return typed_signature
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_typed_return_annotation(call: Callable[..., Any]) -> Any:
|
|
78
|
+
"""Get the return annotation of a function.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
call: The function to get the return annotation for
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
The return annotation of the function
|
|
85
|
+
"""
|
|
86
|
+
signature = inspect.signature(call)
|
|
87
|
+
annotation = signature.return_annotation
|
|
88
|
+
|
|
89
|
+
if annotation is inspect.Signature.empty:
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
globalns = getattr(call, "__globals__", {})
|
|
93
|
+
return get_typed_annotation(annotation, globalns)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def get_param_annotations(typed_signature: inspect.Signature) -> dict[str, Union[Annotated[type[Any], str], type[Any]]]:
|
|
97
|
+
"""Get the type annotations of the parameters of a function
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
typed_signature: The signature of the function with type annotations
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
A dictionary of the type annotations of the parameters of the function
|
|
104
|
+
"""
|
|
105
|
+
return {
|
|
106
|
+
k: v.annotation for k, v in typed_signature.parameters.items() if v.annotation is not inspect.Signature.empty
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class Parameters(BaseModel):
|
|
111
|
+
"""Parameters of a function as defined by the OpenAI API"""
|
|
112
|
+
|
|
113
|
+
type: Literal["object"] = "object"
|
|
114
|
+
properties: dict[str, JsonSchemaValue]
|
|
115
|
+
required: list[str]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class Function(BaseModel):
|
|
119
|
+
"""A function as defined by the OpenAI API"""
|
|
120
|
+
|
|
121
|
+
description: Annotated[str, Field(description="Description of the function")]
|
|
122
|
+
name: Annotated[str, Field(description="Name of the function")]
|
|
123
|
+
parameters: Annotated[Parameters, Field(description="Parameters of the function")]
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class ToolFunction(BaseModel):
|
|
127
|
+
"""A function under tool as defined by the OpenAI API."""
|
|
128
|
+
|
|
129
|
+
type: Literal["function"] = "function"
|
|
130
|
+
function: Annotated[Function, Field(description="Function under tool")]
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def get_parameter_json_schema(k: str, v: Any, default_values: dict[str, Any]) -> JsonSchemaValue:
|
|
134
|
+
"""Get a JSON schema for a parameter as defined by the OpenAI API
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
k: The name of the parameter
|
|
138
|
+
v: The type of the parameter
|
|
139
|
+
default_values: The default values of the parameters of the function
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
A Pydanitc model for the parameter
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def type2description(k: str, v: Union[Annotated[type[Any], str], type[Any]]) -> str:
|
|
146
|
+
if not hasattr(v, "__metadata__"):
|
|
147
|
+
return k
|
|
148
|
+
|
|
149
|
+
# handles Annotated
|
|
150
|
+
retval = v.__metadata__[0]
|
|
151
|
+
if isinstance(retval, AG2Field):
|
|
152
|
+
return retval.description # type: ignore[return-value]
|
|
153
|
+
else:
|
|
154
|
+
raise ValueError(f"Invalid {retval} for parameter {k}, should be a DescriptionField, got {type(retval)}")
|
|
155
|
+
|
|
156
|
+
schema = TypeAdapter(v).json_schema()
|
|
157
|
+
if k in default_values:
|
|
158
|
+
dv = default_values[k]
|
|
159
|
+
schema["default"] = dv
|
|
160
|
+
|
|
161
|
+
schema["description"] = type2description(k, v)
|
|
162
|
+
|
|
163
|
+
return schema
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def get_required_params(typed_signature: inspect.Signature) -> list[str]:
|
|
167
|
+
"""Get the required parameters of a function
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
typed_signature: The signature of the function as returned by inspect.signature
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
A list of the required parameters of the function
|
|
174
|
+
"""
|
|
175
|
+
return [k for k, v in typed_signature.parameters.items() if v.default == inspect.Signature.empty]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def get_default_values(typed_signature: inspect.Signature) -> dict[str, Any]:
|
|
179
|
+
"""Get default values of parameters of a function
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
typed_signature: The signature of the function as returned by inspect.signature
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
A dictionary of the default values of the parameters of the function
|
|
186
|
+
"""
|
|
187
|
+
return {k: v.default for k, v in typed_signature.parameters.items() if v.default != inspect.Signature.empty}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def get_parameters(
|
|
191
|
+
required: list[str],
|
|
192
|
+
param_annotations: dict[str, Union[Annotated[type[Any], str], type[Any]]],
|
|
193
|
+
default_values: dict[str, Any],
|
|
194
|
+
) -> Parameters:
|
|
195
|
+
"""Get the parameters of a function as defined by the OpenAI API
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
required: The required parameters of the function
|
|
199
|
+
param_annotations: The type annotations of the parameters of the function
|
|
200
|
+
default_values: The default values of the parameters of the function
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
A Pydantic model for the parameters of the function
|
|
204
|
+
"""
|
|
205
|
+
return Parameters(
|
|
206
|
+
properties={
|
|
207
|
+
k: get_parameter_json_schema(k, v, default_values)
|
|
208
|
+
for k, v in param_annotations.items()
|
|
209
|
+
if v is not inspect.Signature.empty
|
|
210
|
+
},
|
|
211
|
+
required=required,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def get_missing_annotations(typed_signature: inspect.Signature, required: list[str]) -> tuple[set[str], set[str]]:
|
|
216
|
+
"""Get the missing annotations of a function
|
|
217
|
+
|
|
218
|
+
Ignores the parameters with default values as they are not required to be annotated, but logs a warning.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
typed_signature: The signature of the function with type annotations
|
|
222
|
+
required: The required parameters of the function
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
A set of the missing annotations of the function
|
|
226
|
+
"""
|
|
227
|
+
all_missing = {k for k, v in typed_signature.parameters.items() if v.annotation is inspect.Signature.empty}
|
|
228
|
+
missing = all_missing.intersection(set(required))
|
|
229
|
+
unannotated_with_default = all_missing.difference(missing)
|
|
230
|
+
return missing, unannotated_with_default
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@export_module("autogen.tools")
|
|
234
|
+
def get_function_schema(f: Callable[..., Any], *, name: Optional[str] = None, description: str) -> dict[str, Any]:
|
|
235
|
+
"""Get a JSON schema for a function as defined by the OpenAI API
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
f: The function to get the JSON schema for
|
|
239
|
+
name: The name of the function
|
|
240
|
+
description: The description of the function
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
A JSON schema for the function
|
|
244
|
+
|
|
245
|
+
Raises:
|
|
246
|
+
TypeError: If the function is not annotated
|
|
247
|
+
|
|
248
|
+
Examples:
|
|
249
|
+
```python
|
|
250
|
+
def f(a: Annotated[str, "Parameter a"], b: int = 2, c: Annotated[float, "Parameter c"] = 0.1) -> None:
|
|
251
|
+
pass
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
get_function_schema(f, description="function f")
|
|
255
|
+
|
|
256
|
+
# {'type': 'function',
|
|
257
|
+
# 'function': {'description': 'function f',
|
|
258
|
+
# 'name': 'f',
|
|
259
|
+
# 'parameters': {'type': 'object',
|
|
260
|
+
# 'properties': {'a': {'type': 'str', 'description': 'Parameter a'},
|
|
261
|
+
# 'b': {'type': 'int', 'description': 'b'},
|
|
262
|
+
# 'c': {'type': 'float', 'description': 'Parameter c'}},
|
|
263
|
+
# 'required': ['a']}}}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
"""
|
|
267
|
+
typed_signature = get_typed_signature(f)
|
|
268
|
+
required = get_required_params(typed_signature)
|
|
269
|
+
default_values = get_default_values(typed_signature)
|
|
270
|
+
param_annotations = get_param_annotations(typed_signature)
|
|
271
|
+
return_annotation = get_typed_return_annotation(f)
|
|
272
|
+
missing, unannotated_with_default = get_missing_annotations(typed_signature, required)
|
|
273
|
+
|
|
274
|
+
if return_annotation is None:
|
|
275
|
+
logger.warning(
|
|
276
|
+
f"The return type of the function '{f.__name__}' is not annotated. Although annotating it is "
|
|
277
|
+
+ "optional, the function should return either a string, a subclass of 'pydantic.BaseModel'."
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
if unannotated_with_default != set():
|
|
281
|
+
unannotated_with_default_s = [f"'{k}'" for k in sorted(unannotated_with_default)]
|
|
282
|
+
logger.warning(
|
|
283
|
+
f"The following parameters of the function '{f.__name__}' with default values are not annotated: "
|
|
284
|
+
+ f"{', '.join(unannotated_with_default_s)}."
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
if missing != set():
|
|
288
|
+
missing_s = [f"'{k}'" for k in sorted(missing)]
|
|
289
|
+
raise TypeError(
|
|
290
|
+
f"All parameters of the function '{f.__name__}' without default values must be annotated. "
|
|
291
|
+
+ f"The annotations are missing for the following parameters: {', '.join(missing_s)}"
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
fname = name if name else f.__name__
|
|
295
|
+
|
|
296
|
+
parameters = get_parameters(required, param_annotations, default_values=default_values)
|
|
297
|
+
|
|
298
|
+
function = ToolFunction(
|
|
299
|
+
function=Function(
|
|
300
|
+
description=description,
|
|
301
|
+
name=fname,
|
|
302
|
+
parameters=parameters,
|
|
303
|
+
)
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
return function.model_dump()
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def get_load_param_if_needed_function(t: Any) -> Optional[Callable[[dict[str, Any], type[BaseModel]], BaseModel]]:
|
|
310
|
+
"""Get a function to load a parameter if it is a Pydantic model
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
t: The type annotation of the parameter
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
A function to load the parameter if it is a Pydantic model, otherwise None
|
|
317
|
+
|
|
318
|
+
"""
|
|
319
|
+
origin = get_origin(t)
|
|
320
|
+
|
|
321
|
+
if origin is Annotated:
|
|
322
|
+
args = get_args(t)
|
|
323
|
+
if args:
|
|
324
|
+
return get_load_param_if_needed_function(args[0])
|
|
325
|
+
else:
|
|
326
|
+
# Invalid Annotated usage
|
|
327
|
+
return None
|
|
328
|
+
|
|
329
|
+
# Handle generic types (list[str], dict[str,Any], Union[...], etc.) or where t is not a type at all
|
|
330
|
+
# This means it's not a BaseModel subclass
|
|
331
|
+
if origin is not None or not isinstance(t, type):
|
|
332
|
+
return None
|
|
333
|
+
|
|
334
|
+
def load_base_model(v: dict[str, Any], model_type: type[BaseModel]) -> BaseModel:
|
|
335
|
+
return model_type(**v)
|
|
336
|
+
|
|
337
|
+
# Check if it's a class and a subclass of BaseModel
|
|
338
|
+
if issubclass(t, BaseModel):
|
|
339
|
+
return load_base_model
|
|
340
|
+
else:
|
|
341
|
+
return None
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
@export_module("autogen.tools")
|
|
345
|
+
def load_basemodels_if_needed(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
346
|
+
"""A decorator to load the parameters of a function if they are Pydantic models
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
func: The function with annotated parameters
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
A function that loads the parameters before calling the original function
|
|
353
|
+
|
|
354
|
+
"""
|
|
355
|
+
# get the type annotations of the parameters
|
|
356
|
+
typed_signature = get_typed_signature(func)
|
|
357
|
+
param_annotations = get_param_annotations(typed_signature)
|
|
358
|
+
|
|
359
|
+
# get functions for loading BaseModels when needed based on the type annotations
|
|
360
|
+
kwargs_mapping_with_nones = {k: get_load_param_if_needed_function(t) for k, t in param_annotations.items()}
|
|
361
|
+
|
|
362
|
+
# remove the None values
|
|
363
|
+
kwargs_mapping = {k: f for k, f in kwargs_mapping_with_nones.items() if f is not None}
|
|
364
|
+
|
|
365
|
+
# a function that loads the parameters before calling the original function
|
|
366
|
+
@functools.wraps(func)
|
|
367
|
+
def _load_parameters_if_needed(*args: Any, **kwargs: Any) -> Any:
|
|
368
|
+
# load the BaseModels if needed
|
|
369
|
+
for k, f in kwargs_mapping.items():
|
|
370
|
+
kwargs[k] = f(kwargs[k], param_annotations[k])
|
|
371
|
+
|
|
372
|
+
# call the original function
|
|
373
|
+
return func(*args, **kwargs)
|
|
374
|
+
|
|
375
|
+
@functools.wraps(func)
|
|
376
|
+
async def _a_load_parameters_if_needed(*args: Any, **kwargs: Any) -> Any:
|
|
377
|
+
# load the BaseModels if needed
|
|
378
|
+
for k, f in kwargs_mapping.items():
|
|
379
|
+
kwargs[k] = f(kwargs[k], param_annotations[k])
|
|
380
|
+
|
|
381
|
+
# call the original function
|
|
382
|
+
return await func(*args, **kwargs)
|
|
383
|
+
|
|
384
|
+
if inspect.iscoroutinefunction(func):
|
|
385
|
+
return _a_load_parameters_if_needed
|
|
386
|
+
else:
|
|
387
|
+
return _load_parameters_if_needed
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
class _SerializableResult(BaseModel):
|
|
391
|
+
result: Any
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
@export_module("autogen.tools")
|
|
395
|
+
def serialize_to_str(x: Any) -> str:
|
|
396
|
+
if isinstance(x, str):
|
|
397
|
+
return x
|
|
398
|
+
if isinstance(x, BaseModel):
|
|
399
|
+
return x.model_dump_json()
|
|
400
|
+
|
|
401
|
+
retval_model = _SerializableResult(result=x)
|
|
402
|
+
try:
|
|
403
|
+
return str(retval_model.model_dump()["result"])
|
|
404
|
+
except Exception:
|
|
405
|
+
pass
|
|
406
|
+
|
|
407
|
+
# try json.dumps() and then just return str(x) if that fails too
|
|
408
|
+
try:
|
|
409
|
+
return json.dumps(x, ensure_ascii=False)
|
|
410
|
+
except Exception:
|
|
411
|
+
return str(x)
|
autogen/tools/tool.py
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
|
|
7
|
+
|
|
8
|
+
from ..doc_utils import export_module
|
|
9
|
+
from ..tools.function_utils import get_function_schema
|
|
10
|
+
from .dependency_injection import ChatContext, get_context_params, inject_params
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ..agentchat.conversable_agent import ConversableAgent
|
|
14
|
+
|
|
15
|
+
__all__ = ["Tool", "tool"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@export_module("autogen.tools")
|
|
19
|
+
class Tool:
|
|
20
|
+
"""A class representing a Tool that can be used by an agent for various tasks.
|
|
21
|
+
|
|
22
|
+
This class encapsulates a tool with a name, description, and an executable function.
|
|
23
|
+
The tool can be registered with a ConversableAgent for use either with an LLM or for direct execution.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
name (str): The name of the tool.
|
|
27
|
+
description (str): The description of the tool.
|
|
28
|
+
func_or_tool (Union[Tool, Callable[..., Any]]): The function or Tool instance to create a Tool from.
|
|
29
|
+
parameters_json_schema (Optional[ict[str, Any]]): A schema describing the parameters that the function accepts. If None, the schema will be generated from the function signature.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
*,
|
|
35
|
+
name: Optional[str] = None,
|
|
36
|
+
description: Optional[str] = None,
|
|
37
|
+
func_or_tool: Union["Tool", Callable[..., Any]],
|
|
38
|
+
parameters_json_schema: Optional[dict[str, Any]] = None,
|
|
39
|
+
) -> None:
|
|
40
|
+
"""Create a new Tool object.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
name (str): The name of the tool.
|
|
44
|
+
description (str): The description of the tool.
|
|
45
|
+
func_or_tool (Union[Tool, Callable[..., Any]]): The function or Tool instance to create a Tool from.
|
|
46
|
+
parameters_json_schema (Optional[dict[str, Any]]): A schema describing the parameters that the function accepts. If None, the schema will be generated from the function signature.
|
|
47
|
+
"""
|
|
48
|
+
if isinstance(func_or_tool, Tool):
|
|
49
|
+
self._name: str = name or func_or_tool.name
|
|
50
|
+
self._description: str = description or func_or_tool.description
|
|
51
|
+
self._func: Callable[..., Any] = func_or_tool.func
|
|
52
|
+
self._chat_context_param_names: list[str] = func_or_tool._chat_context_param_names
|
|
53
|
+
elif inspect.isfunction(func_or_tool) or inspect.ismethod(func_or_tool):
|
|
54
|
+
self._chat_context_param_names = get_context_params(func_or_tool, subclass=ChatContext)
|
|
55
|
+
self._func = inject_params(func_or_tool)
|
|
56
|
+
self._name = name or func_or_tool.__name__
|
|
57
|
+
self._description = description or func_or_tool.__doc__ or ""
|
|
58
|
+
else:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f"Parameter 'func_or_tool' must be a function, method or a Tool instance, it is '{type(func_or_tool)}' instead."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
self._func_schema = (
|
|
64
|
+
{
|
|
65
|
+
"type": "function",
|
|
66
|
+
"function": {
|
|
67
|
+
"name": name,
|
|
68
|
+
"description": description,
|
|
69
|
+
"parameters": parameters_json_schema,
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
if parameters_json_schema
|
|
73
|
+
else None
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def name(self) -> str:
|
|
78
|
+
return self._name
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def description(self) -> str:
|
|
82
|
+
return self._description
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def func(self) -> Callable[..., Any]:
|
|
86
|
+
return self._func
|
|
87
|
+
|
|
88
|
+
def register_for_llm(self, agent: "ConversableAgent") -> None:
|
|
89
|
+
"""Registers the tool for use with a ConversableAgent's language model (LLM).
|
|
90
|
+
|
|
91
|
+
This method registers the tool so that it can be invoked by the agent during
|
|
92
|
+
interactions with the language model.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
agent (ConversableAgent): The agent to which the tool will be registered.
|
|
96
|
+
"""
|
|
97
|
+
if self._func_schema:
|
|
98
|
+
agent.update_tool_signature(self._func_schema, is_remove=False)
|
|
99
|
+
else:
|
|
100
|
+
agent.register_for_llm()(self)
|
|
101
|
+
|
|
102
|
+
def register_for_execution(self, agent: "ConversableAgent") -> None:
|
|
103
|
+
"""Registers the tool for direct execution by a ConversableAgent.
|
|
104
|
+
|
|
105
|
+
This method registers the tool so that it can be executed by the agent,
|
|
106
|
+
typically outside of the context of an LLM interaction.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
agent (ConversableAgent): The agent to which the tool will be registered.
|
|
110
|
+
"""
|
|
111
|
+
agent.register_for_execution()(self)
|
|
112
|
+
|
|
113
|
+
def register_tool(self, agent: "ConversableAgent") -> None:
|
|
114
|
+
"""Register a tool to be both proposed and executed by an agent.
|
|
115
|
+
|
|
116
|
+
Equivalent to calling both `register_for_llm` and `register_for_execution` with the same agent.
|
|
117
|
+
|
|
118
|
+
Note: This will not make the agent recommend and execute the call in the one step. If the agent
|
|
119
|
+
recommends the tool, it will need to be the next agent to speak in order to execute the tool.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
agent (ConversableAgent): The agent to which the tool will be registered.
|
|
123
|
+
"""
|
|
124
|
+
self.register_for_llm(agent)
|
|
125
|
+
self.register_for_execution(agent)
|
|
126
|
+
|
|
127
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
128
|
+
"""Execute the tool by calling its underlying function with the provided arguments.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
*args: Positional arguments to pass to the tool
|
|
132
|
+
**kwargs: Keyword arguments to pass to the tool
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
The result of executing the tool's function.
|
|
136
|
+
"""
|
|
137
|
+
return self._func(*args, **kwargs)
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def tool_schema(self) -> dict[str, Any]:
|
|
141
|
+
"""Get the schema for the tool.
|
|
142
|
+
|
|
143
|
+
This is the preferred way of handling function calls with OpeaAI and compatible frameworks.
|
|
144
|
+
|
|
145
|
+
"""
|
|
146
|
+
return get_function_schema(self.func, name=self.name, description=self.description)
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def function_schema(self) -> dict[str, Any]:
|
|
150
|
+
"""Get the schema for the function.
|
|
151
|
+
|
|
152
|
+
This is the old way of handling function calls with OpenAI and compatible frameworks.
|
|
153
|
+
It is provided for backward compatibility.
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
schema = get_function_schema(self.func, name=self.name, description=self.description)
|
|
157
|
+
return schema["function"] # type: ignore[no-any-return]
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def realtime_tool_schema(self) -> dict[str, Any]:
|
|
161
|
+
"""Get the schema for the tool.
|
|
162
|
+
|
|
163
|
+
This is the preferred way of handling function calls with OpeaAI and compatible frameworks.
|
|
164
|
+
|
|
165
|
+
"""
|
|
166
|
+
schema = get_function_schema(self.func, name=self.name, description=self.description)
|
|
167
|
+
schema = {"type": schema["type"], **schema["function"]}
|
|
168
|
+
|
|
169
|
+
return schema
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@export_module("autogen.tools")
|
|
173
|
+
def tool(name: Optional[str] = None, description: Optional[str] = None) -> Callable[[Callable[..., Any]], Tool]:
|
|
174
|
+
"""Decorator to create a Tool from a function.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
name (str): The name of the tool.
|
|
178
|
+
description (str): The description of the tool.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
Callable[[Callable[..., Any]], Tool]: A decorator that creates a Tool from a function.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
def decorator(func: Callable[..., Any]) -> Tool:
|
|
185
|
+
return Tool(name=name, description=description, func_or_tool=func)
|
|
186
|
+
|
|
187
|
+
return decorator
|
autogen/tools/toolkit.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from ..doc_utils import export_module
|
|
8
|
+
from .tool import Tool
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..agentchat.conversable_agent import ConversableAgent
|
|
12
|
+
|
|
13
|
+
__all__ = ["Toolkit"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@export_module("autogen.tools")
|
|
17
|
+
class Toolkit:
|
|
18
|
+
"""A class representing a set of tools that can be used by an agent for various tasks."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, tools: list[Tool]) -> None:
|
|
21
|
+
"""Create a new Toolkit object.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
tools (list[Tool]): The list of tools in the
|
|
25
|
+
"""
|
|
26
|
+
self.toolkit = {tool.name: tool for tool in tools}
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def tools(self) -> list[Tool]:
|
|
30
|
+
"""Get the list of tools in the set."""
|
|
31
|
+
return list(self.toolkit.values())
|
|
32
|
+
|
|
33
|
+
def register_for_llm(self, agent: "ConversableAgent") -> None:
|
|
34
|
+
"""Register the tools in the set with an LLM agent.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
agent (ConversableAgent): The LLM agent to register the tools with.
|
|
38
|
+
"""
|
|
39
|
+
for tool in self.toolkit.values():
|
|
40
|
+
tool.register_for_llm(agent)
|
|
41
|
+
|
|
42
|
+
def register_for_execution(self, agent: "ConversableAgent") -> None:
|
|
43
|
+
"""Register the tools in the set with an agent for
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
agent (ConversableAgent): The agent to register the tools with.
|
|
47
|
+
"""
|
|
48
|
+
for tool in self.toolkit.values():
|
|
49
|
+
tool.register_for_execution(agent)
|
|
50
|
+
|
|
51
|
+
def get_tool(self, tool_name: str) -> Tool:
|
|
52
|
+
"""Get a tool from the set by name.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
tool_name (str): The name of the tool to get.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Tool: The tool with the given name.
|
|
59
|
+
"""
|
|
60
|
+
if tool_name in self.toolkit:
|
|
61
|
+
return self.toolkit[tool_name]
|
|
62
|
+
|
|
63
|
+
raise ValueError(f"Tool '{tool_name}' not found in Toolkit.")
|
|
64
|
+
|
|
65
|
+
def set_tool(self, tool: Tool) -> None:
|
|
66
|
+
"""Set a tool in the set.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
tool (Tool): The tool to set.
|
|
70
|
+
"""
|
|
71
|
+
self.toolkit[tool.name] = tool
|
|
72
|
+
|
|
73
|
+
def remove_tool(self, tool_name: str) -> None:
|
|
74
|
+
"""Remove a tool from the set by name.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
tool_name (str): The name of the tool to remove.
|
|
78
|
+
"""
|
|
79
|
+
if tool_name in self.toolkit:
|
|
80
|
+
del self.toolkit[tool_name]
|
|
81
|
+
else:
|
|
82
|
+
raise ValueError(f"Tool '{tool_name}' not found in Toolkit.")
|
|
83
|
+
|
|
84
|
+
def __len__(self) -> int:
|
|
85
|
+
"""Get the number of tools in the map."""
|
|
86
|
+
return len(self.toolkit)
|