ag2 0.10.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ag2-0.10.2.dist-info/METADATA +819 -0
- ag2-0.10.2.dist-info/RECORD +423 -0
- ag2-0.10.2.dist-info/WHEEL +4 -0
- ag2-0.10.2.dist-info/licenses/LICENSE +201 -0
- ag2-0.10.2.dist-info/licenses/NOTICE.md +19 -0
- autogen/__init__.py +88 -0
- autogen/_website/__init__.py +3 -0
- autogen/_website/generate_api_references.py +426 -0
- autogen/_website/generate_mkdocs.py +1216 -0
- autogen/_website/notebook_processor.py +475 -0
- autogen/_website/process_notebooks.py +656 -0
- autogen/_website/utils.py +413 -0
- autogen/a2a/__init__.py +36 -0
- autogen/a2a/agent_executor.py +86 -0
- autogen/a2a/client.py +357 -0
- autogen/a2a/errors.py +18 -0
- autogen/a2a/httpx_client_factory.py +79 -0
- autogen/a2a/server.py +221 -0
- autogen/a2a/utils.py +207 -0
- autogen/agentchat/__init__.py +47 -0
- autogen/agentchat/agent.py +180 -0
- autogen/agentchat/assistant_agent.py +86 -0
- autogen/agentchat/chat.py +325 -0
- autogen/agentchat/contrib/__init__.py +5 -0
- autogen/agentchat/contrib/agent_eval/README.md +7 -0
- autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
- autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
- autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
- autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
- autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
- autogen/agentchat/contrib/agent_eval/task.py +42 -0
- autogen/agentchat/contrib/agent_optimizer.py +432 -0
- autogen/agentchat/contrib/capabilities/__init__.py +5 -0
- autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
- autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
- autogen/agentchat/contrib/capabilities/teachability.py +393 -0
- autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
- autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
- autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
- autogen/agentchat/contrib/capabilities/transforms.py +578 -0
- autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
- autogen/agentchat/contrib/capabilities/vision_capability.py +215 -0
- autogen/agentchat/contrib/captainagent/__init__.py +9 -0
- autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
- autogen/agentchat/contrib/captainagent/captainagent.py +514 -0
- autogen/agentchat/contrib/captainagent/tool_retriever.py +334 -0
- autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
- autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
- autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
- autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
- autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
- autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
- autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
- autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
- autogen/agentchat/contrib/graph_rag/document.py +29 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +167 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
- autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +263 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
- autogen/agentchat/contrib/img_utils.py +397 -0
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
- autogen/agentchat/contrib/llava_agent.py +189 -0
- autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
- autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +325 -0
- autogen/agentchat/contrib/rag/__init__.py +10 -0
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +268 -0
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +195 -0
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +319 -0
- autogen/agentchat/contrib/rag/query_engine.py +76 -0
- autogen/agentchat/contrib/retrieve_assistant_agent.py +59 -0
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +704 -0
- autogen/agentchat/contrib/society_of_mind_agent.py +200 -0
- autogen/agentchat/contrib/swarm_agent.py +1404 -0
- autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
- autogen/agentchat/contrib/vectordb/__init__.py +5 -0
- autogen/agentchat/contrib/vectordb/base.py +224 -0
- autogen/agentchat/contrib/vectordb/chromadb.py +316 -0
- autogen/agentchat/contrib/vectordb/couchbase.py +405 -0
- autogen/agentchat/contrib/vectordb/mongodb.py +551 -0
- autogen/agentchat/contrib/vectordb/pgvectordb.py +927 -0
- autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
- autogen/agentchat/contrib/vectordb/utils.py +126 -0
- autogen/agentchat/contrib/web_surfer.py +304 -0
- autogen/agentchat/conversable_agent.py +4307 -0
- autogen/agentchat/group/__init__.py +67 -0
- autogen/agentchat/group/available_condition.py +91 -0
- autogen/agentchat/group/context_condition.py +77 -0
- autogen/agentchat/group/context_expression.py +238 -0
- autogen/agentchat/group/context_str.py +39 -0
- autogen/agentchat/group/context_variables.py +182 -0
- autogen/agentchat/group/events/transition_events.py +111 -0
- autogen/agentchat/group/group_tool_executor.py +324 -0
- autogen/agentchat/group/group_utils.py +659 -0
- autogen/agentchat/group/guardrails.py +179 -0
- autogen/agentchat/group/handoffs.py +303 -0
- autogen/agentchat/group/llm_condition.py +93 -0
- autogen/agentchat/group/multi_agent_chat.py +291 -0
- autogen/agentchat/group/on_condition.py +55 -0
- autogen/agentchat/group/on_context_condition.py +51 -0
- autogen/agentchat/group/patterns/__init__.py +18 -0
- autogen/agentchat/group/patterns/auto.py +160 -0
- autogen/agentchat/group/patterns/manual.py +177 -0
- autogen/agentchat/group/patterns/pattern.py +295 -0
- autogen/agentchat/group/patterns/random.py +106 -0
- autogen/agentchat/group/patterns/round_robin.py +117 -0
- autogen/agentchat/group/reply_result.py +24 -0
- autogen/agentchat/group/safeguards/__init__.py +21 -0
- autogen/agentchat/group/safeguards/api.py +241 -0
- autogen/agentchat/group/safeguards/enforcer.py +1158 -0
- autogen/agentchat/group/safeguards/events.py +140 -0
- autogen/agentchat/group/safeguards/validator.py +435 -0
- autogen/agentchat/group/speaker_selection_result.py +41 -0
- autogen/agentchat/group/targets/__init__.py +4 -0
- autogen/agentchat/group/targets/function_target.py +245 -0
- autogen/agentchat/group/targets/group_chat_target.py +133 -0
- autogen/agentchat/group/targets/group_manager_target.py +151 -0
- autogen/agentchat/group/targets/transition_target.py +424 -0
- autogen/agentchat/group/targets/transition_utils.py +6 -0
- autogen/agentchat/groupchat.py +1832 -0
- autogen/agentchat/realtime/__init__.py +3 -0
- autogen/agentchat/realtime/experimental/__init__.py +20 -0
- autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
- autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
- autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
- autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
- autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
- autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
- autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
- autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
- autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +191 -0
- autogen/agentchat/realtime/experimental/function_observer.py +84 -0
- autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
- autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
- autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
- autogen/agentchat/realtime/experimental/realtime_swarm.py +533 -0
- autogen/agentchat/realtime/experimental/websockets.py +21 -0
- autogen/agentchat/realtime_agent/__init__.py +21 -0
- autogen/agentchat/user_proxy_agent.py +114 -0
- autogen/agentchat/utils.py +206 -0
- autogen/agents/__init__.py +3 -0
- autogen/agents/contrib/__init__.py +10 -0
- autogen/agents/contrib/time/__init__.py +8 -0
- autogen/agents/contrib/time/time_reply_agent.py +74 -0
- autogen/agents/contrib/time/time_tool_agent.py +52 -0
- autogen/agents/experimental/__init__.py +27 -0
- autogen/agents/experimental/deep_research/__init__.py +7 -0
- autogen/agents/experimental/deep_research/deep_research.py +52 -0
- autogen/agents/experimental/discord/__init__.py +7 -0
- autogen/agents/experimental/discord/discord.py +66 -0
- autogen/agents/experimental/document_agent/__init__.py +19 -0
- autogen/agents/experimental/document_agent/chroma_query_engine.py +301 -0
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +113 -0
- autogen/agents/experimental/document_agent/document_agent.py +643 -0
- autogen/agents/experimental/document_agent/document_conditions.py +50 -0
- autogen/agents/experimental/document_agent/document_utils.py +376 -0
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +214 -0
- autogen/agents/experimental/document_agent/parser_utils.py +134 -0
- autogen/agents/experimental/document_agent/url_utils.py +417 -0
- autogen/agents/experimental/reasoning/__init__.py +7 -0
- autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
- autogen/agents/experimental/slack/__init__.py +7 -0
- autogen/agents/experimental/slack/slack.py +73 -0
- autogen/agents/experimental/telegram/__init__.py +7 -0
- autogen/agents/experimental/telegram/telegram.py +76 -0
- autogen/agents/experimental/websurfer/__init__.py +7 -0
- autogen/agents/experimental/websurfer/websurfer.py +70 -0
- autogen/agents/experimental/wikipedia/__init__.py +7 -0
- autogen/agents/experimental/wikipedia/wikipedia.py +88 -0
- autogen/browser_utils.py +309 -0
- autogen/cache/__init__.py +10 -0
- autogen/cache/abstract_cache_base.py +71 -0
- autogen/cache/cache.py +203 -0
- autogen/cache/cache_factory.py +88 -0
- autogen/cache/cosmos_db_cache.py +144 -0
- autogen/cache/disk_cache.py +97 -0
- autogen/cache/in_memory_cache.py +54 -0
- autogen/cache/redis_cache.py +119 -0
- autogen/code_utils.py +598 -0
- autogen/coding/__init__.py +30 -0
- autogen/coding/base.py +120 -0
- autogen/coding/docker_commandline_code_executor.py +283 -0
- autogen/coding/factory.py +56 -0
- autogen/coding/func_with_reqs.py +203 -0
- autogen/coding/jupyter/__init__.py +23 -0
- autogen/coding/jupyter/base.py +36 -0
- autogen/coding/jupyter/docker_jupyter_server.py +160 -0
- autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
- autogen/coding/jupyter/import_utils.py +82 -0
- autogen/coding/jupyter/jupyter_client.py +224 -0
- autogen/coding/jupyter/jupyter_code_executor.py +154 -0
- autogen/coding/jupyter/local_jupyter_server.py +164 -0
- autogen/coding/local_commandline_code_executor.py +341 -0
- autogen/coding/markdown_code_extractor.py +44 -0
- autogen/coding/utils.py +55 -0
- autogen/coding/yepcode_code_executor.py +197 -0
- autogen/doc_utils.py +35 -0
- autogen/environments/__init__.py +10 -0
- autogen/environments/docker_python_environment.py +365 -0
- autogen/environments/python_environment.py +125 -0
- autogen/environments/system_python_environment.py +85 -0
- autogen/environments/venv_python_environment.py +220 -0
- autogen/environments/working_directory.py +74 -0
- autogen/events/__init__.py +7 -0
- autogen/events/agent_events.py +1016 -0
- autogen/events/base_event.py +100 -0
- autogen/events/client_events.py +168 -0
- autogen/events/helpers.py +44 -0
- autogen/events/print_event.py +45 -0
- autogen/exception_utils.py +73 -0
- autogen/extensions/__init__.py +5 -0
- autogen/fast_depends/__init__.py +16 -0
- autogen/fast_depends/_compat.py +75 -0
- autogen/fast_depends/core/__init__.py +14 -0
- autogen/fast_depends/core/build.py +206 -0
- autogen/fast_depends/core/model.py +527 -0
- autogen/fast_depends/dependencies/__init__.py +15 -0
- autogen/fast_depends/dependencies/model.py +30 -0
- autogen/fast_depends/dependencies/provider.py +40 -0
- autogen/fast_depends/library/__init__.py +10 -0
- autogen/fast_depends/library/model.py +46 -0
- autogen/fast_depends/py.typed +6 -0
- autogen/fast_depends/schema.py +66 -0
- autogen/fast_depends/use.py +272 -0
- autogen/fast_depends/utils.py +177 -0
- autogen/formatting_utils.py +83 -0
- autogen/function_utils.py +13 -0
- autogen/graph_utils.py +173 -0
- autogen/import_utils.py +539 -0
- autogen/interop/__init__.py +22 -0
- autogen/interop/crewai/__init__.py +7 -0
- autogen/interop/crewai/crewai.py +88 -0
- autogen/interop/interoperability.py +71 -0
- autogen/interop/interoperable.py +46 -0
- autogen/interop/langchain/__init__.py +8 -0
- autogen/interop/langchain/langchain_chat_model_factory.py +156 -0
- autogen/interop/langchain/langchain_tool.py +78 -0
- autogen/interop/litellm/__init__.py +7 -0
- autogen/interop/litellm/litellm_config_factory.py +178 -0
- autogen/interop/pydantic_ai/__init__.py +7 -0
- autogen/interop/pydantic_ai/pydantic_ai.py +172 -0
- autogen/interop/registry.py +70 -0
- autogen/io/__init__.py +15 -0
- autogen/io/base.py +151 -0
- autogen/io/console.py +56 -0
- autogen/io/processors/__init__.py +12 -0
- autogen/io/processors/base.py +21 -0
- autogen/io/processors/console_event_processor.py +61 -0
- autogen/io/run_response.py +294 -0
- autogen/io/thread_io_stream.py +63 -0
- autogen/io/websockets.py +214 -0
- autogen/json_utils.py +42 -0
- autogen/llm_clients/MIGRATION_TO_V2.md +782 -0
- autogen/llm_clients/__init__.py +77 -0
- autogen/llm_clients/client_v2.py +122 -0
- autogen/llm_clients/models/__init__.py +55 -0
- autogen/llm_clients/models/content_blocks.py +389 -0
- autogen/llm_clients/models/unified_message.py +145 -0
- autogen/llm_clients/models/unified_response.py +83 -0
- autogen/llm_clients/openai_completions_client.py +444 -0
- autogen/llm_config/__init__.py +11 -0
- autogen/llm_config/client.py +59 -0
- autogen/llm_config/config.py +461 -0
- autogen/llm_config/entry.py +169 -0
- autogen/llm_config/types.py +37 -0
- autogen/llm_config/utils.py +223 -0
- autogen/logger/__init__.py +11 -0
- autogen/logger/base_logger.py +129 -0
- autogen/logger/file_logger.py +262 -0
- autogen/logger/logger_factory.py +42 -0
- autogen/logger/logger_utils.py +57 -0
- autogen/logger/sqlite_logger.py +524 -0
- autogen/math_utils.py +338 -0
- autogen/mcp/__init__.py +7 -0
- autogen/mcp/__main__.py +78 -0
- autogen/mcp/helpers.py +45 -0
- autogen/mcp/mcp_client.py +349 -0
- autogen/mcp/mcp_proxy/__init__.py +19 -0
- autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +62 -0
- autogen/mcp/mcp_proxy/mcp_proxy.py +577 -0
- autogen/mcp/mcp_proxy/operation_grouping.py +166 -0
- autogen/mcp/mcp_proxy/operation_renaming.py +110 -0
- autogen/mcp/mcp_proxy/patch_fastapi_code_generator.py +98 -0
- autogen/mcp/mcp_proxy/security.py +399 -0
- autogen/mcp/mcp_proxy/security_schema_visitor.py +37 -0
- autogen/messages/__init__.py +7 -0
- autogen/messages/agent_messages.py +946 -0
- autogen/messages/base_message.py +108 -0
- autogen/messages/client_messages.py +172 -0
- autogen/messages/print_message.py +48 -0
- autogen/oai/__init__.py +61 -0
- autogen/oai/anthropic.py +1516 -0
- autogen/oai/bedrock.py +800 -0
- autogen/oai/cerebras.py +302 -0
- autogen/oai/client.py +1658 -0
- autogen/oai/client_utils.py +196 -0
- autogen/oai/cohere.py +494 -0
- autogen/oai/gemini.py +1045 -0
- autogen/oai/gemini_types.py +156 -0
- autogen/oai/groq.py +319 -0
- autogen/oai/mistral.py +311 -0
- autogen/oai/oai_models/__init__.py +23 -0
- autogen/oai/oai_models/_models.py +16 -0
- autogen/oai/oai_models/chat_completion.py +86 -0
- autogen/oai/oai_models/chat_completion_audio.py +32 -0
- autogen/oai/oai_models/chat_completion_message.py +97 -0
- autogen/oai/oai_models/chat_completion_message_tool_call.py +60 -0
- autogen/oai/oai_models/chat_completion_token_logprob.py +62 -0
- autogen/oai/oai_models/completion_usage.py +59 -0
- autogen/oai/ollama.py +657 -0
- autogen/oai/openai_responses.py +451 -0
- autogen/oai/openai_utils.py +897 -0
- autogen/oai/together.py +387 -0
- autogen/remote/__init__.py +18 -0
- autogen/remote/agent.py +199 -0
- autogen/remote/agent_service.py +197 -0
- autogen/remote/errors.py +17 -0
- autogen/remote/httpx_client_factory.py +131 -0
- autogen/remote/protocol.py +37 -0
- autogen/remote/retry.py +102 -0
- autogen/remote/runtime.py +96 -0
- autogen/retrieve_utils.py +490 -0
- autogen/runtime_logging.py +161 -0
- autogen/testing/__init__.py +12 -0
- autogen/testing/messages.py +45 -0
- autogen/testing/test_agent.py +111 -0
- autogen/token_count_utils.py +280 -0
- autogen/tools/__init__.py +20 -0
- autogen/tools/contrib/__init__.py +9 -0
- autogen/tools/contrib/time/__init__.py +7 -0
- autogen/tools/contrib/time/time.py +40 -0
- autogen/tools/dependency_injection.py +249 -0
- autogen/tools/experimental/__init__.py +54 -0
- autogen/tools/experimental/browser_use/__init__.py +7 -0
- autogen/tools/experimental/browser_use/browser_use.py +154 -0
- autogen/tools/experimental/code_execution/__init__.py +7 -0
- autogen/tools/experimental/code_execution/python_code_execution.py +86 -0
- autogen/tools/experimental/crawl4ai/__init__.py +7 -0
- autogen/tools/experimental/crawl4ai/crawl4ai.py +150 -0
- autogen/tools/experimental/deep_research/__init__.py +7 -0
- autogen/tools/experimental/deep_research/deep_research.py +329 -0
- autogen/tools/experimental/duckduckgo/__init__.py +7 -0
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +103 -0
- autogen/tools/experimental/firecrawl/__init__.py +7 -0
- autogen/tools/experimental/firecrawl/firecrawl_tool.py +836 -0
- autogen/tools/experimental/google/__init__.py +14 -0
- autogen/tools/experimental/google/authentication/__init__.py +11 -0
- autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
- autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
- autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
- autogen/tools/experimental/google/drive/__init__.py +9 -0
- autogen/tools/experimental/google/drive/drive_functions.py +124 -0
- autogen/tools/experimental/google/drive/toolkit.py +88 -0
- autogen/tools/experimental/google/model.py +17 -0
- autogen/tools/experimental/google/toolkit_protocol.py +19 -0
- autogen/tools/experimental/google_search/__init__.py +8 -0
- autogen/tools/experimental/google_search/google_search.py +93 -0
- autogen/tools/experimental/google_search/youtube_search.py +181 -0
- autogen/tools/experimental/messageplatform/__init__.py +17 -0
- autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/discord/discord.py +284 -0
- autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/slack/slack.py +385 -0
- autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/telegram/telegram.py +271 -0
- autogen/tools/experimental/perplexity/__init__.py +7 -0
- autogen/tools/experimental/perplexity/perplexity_search.py +249 -0
- autogen/tools/experimental/reliable/__init__.py +10 -0
- autogen/tools/experimental/reliable/reliable.py +1311 -0
- autogen/tools/experimental/searxng/__init__.py +7 -0
- autogen/tools/experimental/searxng/searxng_search.py +142 -0
- autogen/tools/experimental/tavily/__init__.py +7 -0
- autogen/tools/experimental/tavily/tavily_search.py +176 -0
- autogen/tools/experimental/web_search_preview/__init__.py +7 -0
- autogen/tools/experimental/web_search_preview/web_search_preview.py +120 -0
- autogen/tools/experimental/wikipedia/__init__.py +7 -0
- autogen/tools/experimental/wikipedia/wikipedia.py +284 -0
- autogen/tools/function_utils.py +412 -0
- autogen/tools/tool.py +188 -0
- autogen/tools/toolkit.py +86 -0
- autogen/types.py +29 -0
- autogen/version.py +7 -0
- templates/client_template/main.jinja2 +72 -0
- templates/config_template/config.jinja2 +7 -0
- templates/main.jinja2 +61 -0
|
@@ -0,0 +1,179 @@
|
|
|
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 json
|
|
6
|
+
import re
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
11
|
+
|
|
12
|
+
from ...oai.client import OpenAIWrapper
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from ...llm_config import LLMConfig
|
|
16
|
+
from .targets.transition_target import TransitionTarget
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Guardrail(ABC):
|
|
20
|
+
"""Abstract base class for guardrails."""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self, name: str, condition: str, target: "TransitionTarget", activation_message: str | None = None
|
|
24
|
+
) -> None:
|
|
25
|
+
self.name = name
|
|
26
|
+
self.condition = condition
|
|
27
|
+
self.target = target
|
|
28
|
+
self.activation_message = (
|
|
29
|
+
activation_message if activation_message else f"Guardrail '{name}' has been activated."
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def check(
|
|
34
|
+
self,
|
|
35
|
+
context: str | list[dict[str, Any]],
|
|
36
|
+
) -> "GuardrailResult":
|
|
37
|
+
"""Checks the text against the guardrail and returns a GuardrailResult.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
context (Union[str, list[dict[str, Any]]]): The context to check against the guardrail.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
GuardrailResult: The result of the guardrail check.
|
|
44
|
+
"""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class LLMGuardrail(Guardrail):
|
|
49
|
+
"""Guardrail that uses an LLM to check the context."""
|
|
50
|
+
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
name: str,
|
|
54
|
+
condition: str,
|
|
55
|
+
target: "TransitionTarget",
|
|
56
|
+
llm_config: "LLMConfig",
|
|
57
|
+
activation_message: str | None = None,
|
|
58
|
+
) -> None:
|
|
59
|
+
super().__init__(name, condition, target, activation_message)
|
|
60
|
+
|
|
61
|
+
if not llm_config:
|
|
62
|
+
raise ValueError("LLMConfig is required.")
|
|
63
|
+
|
|
64
|
+
self.llm_config = llm_config.deepcopy()
|
|
65
|
+
setattr(self.llm_config, "response_format", GuardrailResult)
|
|
66
|
+
self.client = OpenAIWrapper(**self.llm_config.model_dump())
|
|
67
|
+
|
|
68
|
+
self.check_prompt = f"""You are a guardrail that checks if a condition is met in the conversation you are given.
|
|
69
|
+
You will activate the guardrail only if the condition is met.
|
|
70
|
+
|
|
71
|
+
**Condition: {self.condition}**"""
|
|
72
|
+
|
|
73
|
+
def check(
|
|
74
|
+
self,
|
|
75
|
+
context: str | list[dict[str, Any]],
|
|
76
|
+
) -> "GuardrailResult":
|
|
77
|
+
"""Checks the context against the guardrail using an LLM.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
context (Union[str, list[dict[str, Any]]]): The context to check against the guardrail.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
GuardrailResult: The result of the guardrail check.
|
|
84
|
+
"""
|
|
85
|
+
# Set the check prompt as the system message
|
|
86
|
+
check_messages = [{"role": "system", "content": self.check_prompt}]
|
|
87
|
+
# If context is a string, wrap it in a user message and append it
|
|
88
|
+
if isinstance(context, str):
|
|
89
|
+
check_messages.append({"role": "user", "content": context})
|
|
90
|
+
# If context is a list of messages, append them
|
|
91
|
+
elif isinstance(context, list):
|
|
92
|
+
check_messages.extend(context)
|
|
93
|
+
else:
|
|
94
|
+
raise ValueError("Context must be a string or a list of messages.")
|
|
95
|
+
# Call the LLM with the check messages
|
|
96
|
+
response = self.client.create(messages=check_messages)
|
|
97
|
+
return GuardrailResult.parse(response.choices[0].message.content, guardrail=self) # type: ignore
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class RegexGuardrail(Guardrail):
|
|
101
|
+
"""Guardrail that checks the context against a regular expression."""
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self,
|
|
105
|
+
name: str,
|
|
106
|
+
condition: str,
|
|
107
|
+
target: "TransitionTarget",
|
|
108
|
+
activation_message: str | None = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
super().__init__(name, condition, target, activation_message)
|
|
111
|
+
# Compile the regular expression condition
|
|
112
|
+
try:
|
|
113
|
+
self.regex = re.compile(condition)
|
|
114
|
+
except re.error as e:
|
|
115
|
+
raise ValueError(f"Invalid regex pattern '{condition}': {str(e)}")
|
|
116
|
+
|
|
117
|
+
def check(
|
|
118
|
+
self,
|
|
119
|
+
context: str | list[dict[str, Any]],
|
|
120
|
+
) -> "GuardrailResult":
|
|
121
|
+
"""Checks the context against the guardrail using a regular expression.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
context (Union[str, list[dict[str, Any]]]): The context to check against the guardrail.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
GuardrailResult: The result of the guardrail check.
|
|
128
|
+
"""
|
|
129
|
+
# Create a list of the messages to check
|
|
130
|
+
if isinstance(context, str):
|
|
131
|
+
messages = [context]
|
|
132
|
+
elif isinstance(context, list):
|
|
133
|
+
messages = [message.get("content", "") for message in context]
|
|
134
|
+
else:
|
|
135
|
+
raise ValueError("Context must be a string or a list of messages.")
|
|
136
|
+
|
|
137
|
+
# Check each message against the regex
|
|
138
|
+
for message in messages:
|
|
139
|
+
match = self.regex.search(message)
|
|
140
|
+
# If a match is found, activate the guardrail and return the result
|
|
141
|
+
if match:
|
|
142
|
+
activated = True
|
|
143
|
+
justification = f"Match found -> {match.group(0)}"
|
|
144
|
+
return GuardrailResult(activated=activated, justification=justification, guardrail=self)
|
|
145
|
+
return GuardrailResult(activated=False, justification="No match found in the context.", guardrail=self)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class GuardrailResult(BaseModel):
|
|
149
|
+
"""Represents the outcome of a guardrail check."""
|
|
150
|
+
|
|
151
|
+
activated: bool
|
|
152
|
+
guardrail: Guardrail
|
|
153
|
+
justification: str = Field(default="No justification provided")
|
|
154
|
+
|
|
155
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
156
|
+
|
|
157
|
+
def __str__(self) -> str:
|
|
158
|
+
return f"Guardrail Result: {self.activated}\nJustification: {self.justification}"
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def reply(self) -> str:
|
|
162
|
+
return f"{self.guardrail.activation_message}\nJustification: {self.justification}"
|
|
163
|
+
|
|
164
|
+
@staticmethod
|
|
165
|
+
def parse(text: str, guardrail: "Guardrail") -> "GuardrailResult":
|
|
166
|
+
"""Parses a JSON string into a GuardrailResult object.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
text (str): The JSON string to parse.
|
|
170
|
+
guardrail (Guardrail): The guardrail that the result is for.
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
GuardrailResult: The parsed GuardrailResult object.
|
|
174
|
+
"""
|
|
175
|
+
try:
|
|
176
|
+
data = json.loads(text)
|
|
177
|
+
return GuardrailResult(**data, guardrail=guardrail)
|
|
178
|
+
except (json.JSONDecodeError, ValueError) as e:
|
|
179
|
+
raise ValueError(f"Failed to parse GuardrailResult from text: {text}") from e
|
|
@@ -0,0 +1,303 @@
|
|
|
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 overload
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
from .on_condition import OnCondition
|
|
10
|
+
from .on_context_condition import OnContextCondition
|
|
11
|
+
from .targets.transition_target import TransitionTarget
|
|
12
|
+
|
|
13
|
+
__all__ = ["Handoffs"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Handoffs(BaseModel):
|
|
17
|
+
"""Container for all handoff transition conditions of a ConversableAgent.\n
|
|
18
|
+
\n
|
|
19
|
+
Three types of conditions can be added, each with a different order and time of use:\n
|
|
20
|
+
1. OnContextConditions (evaluated without an LLM)\n
|
|
21
|
+
2. OnConditions (evaluated with an LLM)\n
|
|
22
|
+
3. After work TransitionTarget (if no other transition is triggered)\n
|
|
23
|
+
\n
|
|
24
|
+
Supports method chaining:\n
|
|
25
|
+
agent.handoffs.add_context_conditions([condition1])\n
|
|
26
|
+
.add_llm_condition(condition2)\n
|
|
27
|
+
.set_after_work(after_work)\n
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
context_conditions: list[OnContextCondition] = Field(default_factory=list)
|
|
31
|
+
llm_conditions: list[OnCondition] = Field(default_factory=list)
|
|
32
|
+
after_works: list[OnContextCondition] = Field(default_factory=list)
|
|
33
|
+
|
|
34
|
+
def add_context_condition(self, condition: OnContextCondition) -> "Handoffs":
|
|
35
|
+
"""Add a single context condition.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
condition: The OnContextCondition to add
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Self for method chaining
|
|
42
|
+
"""
|
|
43
|
+
# Validate that it is an OnContextCondition
|
|
44
|
+
if not isinstance(condition, OnContextCondition):
|
|
45
|
+
raise TypeError(f"Expected an OnContextCondition instance, got {type(condition).__name__}")
|
|
46
|
+
|
|
47
|
+
self.context_conditions.append(condition)
|
|
48
|
+
return self
|
|
49
|
+
|
|
50
|
+
def add_context_conditions(self, conditions: list[OnContextCondition]) -> "Handoffs":
|
|
51
|
+
"""Add multiple context conditions.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
conditions: List of OnContextConditions to add
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Self for method chaining
|
|
58
|
+
"""
|
|
59
|
+
# Validate that it is a list of OnContextConditions
|
|
60
|
+
if not all(isinstance(condition, OnContextCondition) for condition in conditions):
|
|
61
|
+
raise TypeError("All conditions must be of type OnContextCondition")
|
|
62
|
+
|
|
63
|
+
self.context_conditions.extend(conditions)
|
|
64
|
+
return self
|
|
65
|
+
|
|
66
|
+
def add_llm_condition(self, condition: OnCondition) -> "Handoffs":
|
|
67
|
+
"""Add a single LLM condition.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
condition: The OnCondition to add
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Self for method chaining
|
|
74
|
+
"""
|
|
75
|
+
# Validate that it is an OnCondition
|
|
76
|
+
if not isinstance(condition, OnCondition):
|
|
77
|
+
raise TypeError(f"Expected an OnCondition instance, got {type(condition).__name__}")
|
|
78
|
+
|
|
79
|
+
self.llm_conditions.append(condition)
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def add_llm_conditions(self, conditions: list[OnCondition]) -> "Handoffs":
|
|
83
|
+
"""Add multiple LLM conditions.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
conditions: List of OnConditions to add
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Self for method chaining
|
|
90
|
+
"""
|
|
91
|
+
# Validate that it is a list of OnConditions
|
|
92
|
+
if not all(isinstance(condition, OnCondition) for condition in conditions):
|
|
93
|
+
raise TypeError("All conditions must be of type OnCondition")
|
|
94
|
+
|
|
95
|
+
self.llm_conditions.extend(conditions)
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
def set_after_work(self, target: TransitionTarget) -> "Handoffs":
|
|
99
|
+
"""Set the after work target (replaces all after_works with single entry).
|
|
100
|
+
|
|
101
|
+
For backward compatibility, this creates an OnContextCondition with no condition (always true).
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
target: The after work TransitionTarget to set
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Self for method chaining
|
|
108
|
+
"""
|
|
109
|
+
if not isinstance(target, TransitionTarget):
|
|
110
|
+
raise TypeError(f"Expected a TransitionTarget instance, got {type(target).__name__}")
|
|
111
|
+
|
|
112
|
+
# Create OnContextCondition with no condition (always true)
|
|
113
|
+
after_work_condition = OnContextCondition(target=target, condition=None)
|
|
114
|
+
self.after_works = [after_work_condition]
|
|
115
|
+
return self
|
|
116
|
+
|
|
117
|
+
def add_after_work(self, condition: OnContextCondition) -> "Handoffs":
|
|
118
|
+
"""Add a single after-work condition.
|
|
119
|
+
|
|
120
|
+
If the condition has condition=None, it will replace any existing
|
|
121
|
+
condition=None entry and be placed at the end.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
condition: The OnContextCondition to add
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Self for method chaining
|
|
128
|
+
"""
|
|
129
|
+
if not isinstance(condition, OnContextCondition):
|
|
130
|
+
raise TypeError(f"Expected an OnContextCondition instance, got {type(condition).__name__}")
|
|
131
|
+
|
|
132
|
+
if condition.condition is None:
|
|
133
|
+
# Remove any existing condition=None entries
|
|
134
|
+
self.after_works = [c for c in self.after_works if c.condition is not None]
|
|
135
|
+
# Add the new one at the end
|
|
136
|
+
self.after_works.append(condition)
|
|
137
|
+
else:
|
|
138
|
+
# For regular conditions, check if we need to move condition=None to the end
|
|
139
|
+
none_conditions = [c for c in self.after_works if c.condition is None]
|
|
140
|
+
if none_conditions:
|
|
141
|
+
# Remove the None condition temporarily
|
|
142
|
+
self.after_works = [c for c in self.after_works if c.condition is not None]
|
|
143
|
+
# Add the new regular condition
|
|
144
|
+
self.after_works.append(condition)
|
|
145
|
+
# Re-add the None condition at the end
|
|
146
|
+
self.after_works.append(none_conditions[0])
|
|
147
|
+
else:
|
|
148
|
+
# No None condition exists, just append
|
|
149
|
+
self.after_works.append(condition)
|
|
150
|
+
|
|
151
|
+
return self
|
|
152
|
+
|
|
153
|
+
def add_after_works(self, conditions: list[OnContextCondition]) -> "Handoffs":
|
|
154
|
+
"""Add multiple after-work conditions.
|
|
155
|
+
|
|
156
|
+
Special handling for condition=None entries:
|
|
157
|
+
- Only one condition=None entry is allowed (the fallback)
|
|
158
|
+
- It will always be placed at the end of the list
|
|
159
|
+
- If multiple condition=None entries are provided, only the last one is kept
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
conditions: List of OnContextConditions to add
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Self for method chaining
|
|
166
|
+
"""
|
|
167
|
+
# Validate that it is a list of OnContextConditions
|
|
168
|
+
if not all(isinstance(condition, OnContextCondition) for condition in conditions):
|
|
169
|
+
raise TypeError("All conditions must be of type OnContextCondition")
|
|
170
|
+
|
|
171
|
+
# Separate conditions with None and without None
|
|
172
|
+
none_conditions = [c for c in conditions if c.condition is None]
|
|
173
|
+
regular_conditions = [c for c in conditions if c.condition is not None]
|
|
174
|
+
|
|
175
|
+
# Remove any existing condition=None entries
|
|
176
|
+
self.after_works = [c for c in self.after_works if c.condition is not None]
|
|
177
|
+
|
|
178
|
+
# Add regular conditions
|
|
179
|
+
self.after_works.extend(regular_conditions)
|
|
180
|
+
|
|
181
|
+
# Add at most one None condition at the end
|
|
182
|
+
if none_conditions:
|
|
183
|
+
self.after_works.append(none_conditions[-1]) # Use the last one if multiple provided
|
|
184
|
+
|
|
185
|
+
return self
|
|
186
|
+
|
|
187
|
+
@overload
|
|
188
|
+
def add(self, condition: OnContextCondition) -> "Handoffs": ...
|
|
189
|
+
|
|
190
|
+
@overload
|
|
191
|
+
def add(self, condition: OnCondition) -> "Handoffs": ...
|
|
192
|
+
|
|
193
|
+
def add(self, condition: OnContextCondition | OnCondition) -> "Handoffs":
|
|
194
|
+
"""Add a single condition (OnContextCondition or OnCondition).
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
condition: The condition to add (OnContextCondition or OnCondition)
|
|
198
|
+
|
|
199
|
+
Raises:
|
|
200
|
+
TypeError: If the condition type is not supported
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Self for method chaining
|
|
204
|
+
"""
|
|
205
|
+
# This add method is a helper method designed to make it easier for
|
|
206
|
+
# adding handoffs without worrying about the specific type.
|
|
207
|
+
if isinstance(condition, OnContextCondition):
|
|
208
|
+
return self.add_context_condition(condition)
|
|
209
|
+
elif isinstance(condition, OnCondition):
|
|
210
|
+
return self.add_llm_condition(condition)
|
|
211
|
+
else:
|
|
212
|
+
raise TypeError(f"Unsupported condition type: {type(condition).__name__}")
|
|
213
|
+
|
|
214
|
+
def add_many(self, conditions: list[OnContextCondition | OnCondition]) -> "Handoffs":
|
|
215
|
+
"""Add multiple conditions of any supported types (OnContextCondition and OnCondition).
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
conditions: List of conditions to add
|
|
219
|
+
|
|
220
|
+
Raises:
|
|
221
|
+
TypeError: If an unsupported condition type is provided
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
Self for method chaining
|
|
225
|
+
"""
|
|
226
|
+
# This add_many method is a helper method designed to make it easier for
|
|
227
|
+
# adding handoffs without worrying about the specific type.
|
|
228
|
+
context_conditions = []
|
|
229
|
+
llm_conditions = []
|
|
230
|
+
|
|
231
|
+
for condition in conditions:
|
|
232
|
+
if isinstance(condition, OnContextCondition):
|
|
233
|
+
context_conditions.append(condition)
|
|
234
|
+
elif isinstance(condition, OnCondition):
|
|
235
|
+
llm_conditions.append(condition)
|
|
236
|
+
else:
|
|
237
|
+
raise TypeError(f"Unsupported condition type: {type(condition).__name__}")
|
|
238
|
+
|
|
239
|
+
if context_conditions:
|
|
240
|
+
self.add_context_conditions(context_conditions)
|
|
241
|
+
if llm_conditions:
|
|
242
|
+
self.add_llm_conditions(llm_conditions)
|
|
243
|
+
|
|
244
|
+
return self
|
|
245
|
+
|
|
246
|
+
def clear(self) -> "Handoffs":
|
|
247
|
+
"""Clear all handoff conditions.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
Self for method chaining
|
|
251
|
+
"""
|
|
252
|
+
self.context_conditions.clear()
|
|
253
|
+
self.llm_conditions.clear()
|
|
254
|
+
self.after_works.clear()
|
|
255
|
+
return self
|
|
256
|
+
|
|
257
|
+
def get_llm_conditions_by_target_type(self, target_type: type) -> list[OnCondition]:
|
|
258
|
+
"""Get OnConditions for a specific target type.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
target_type: The type of condition to retrieve
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
List of conditions of the specified type, or None if none exist
|
|
265
|
+
"""
|
|
266
|
+
return [on_condition for on_condition in self.llm_conditions if on_condition.has_target_type(target_type)]
|
|
267
|
+
|
|
268
|
+
def get_context_conditions_by_target_type(self, target_type: type) -> list[OnContextCondition]:
|
|
269
|
+
"""Get OnContextConditions for a specific target type.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
target_type: The type of condition to retrieve
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
List of conditions of the specified type, or None if none exist
|
|
276
|
+
"""
|
|
277
|
+
return [
|
|
278
|
+
on_context_condition
|
|
279
|
+
for on_context_condition in self.context_conditions
|
|
280
|
+
if on_context_condition.has_target_type(target_type)
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
def get_llm_conditions_requiring_wrapping(self) -> list[OnCondition]:
|
|
284
|
+
"""Get LLM conditions that have targets that require wrapping.
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
List of LLM conditions that require wrapping
|
|
288
|
+
"""
|
|
289
|
+
return [condition for condition in self.llm_conditions if condition.target_requires_wrapping()]
|
|
290
|
+
|
|
291
|
+
def get_context_conditions_requiring_wrapping(self) -> list[OnContextCondition]:
|
|
292
|
+
"""Get context conditions that have targets that require wrapping.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
List of context conditions that require wrapping
|
|
296
|
+
"""
|
|
297
|
+
return [condition for condition in self.context_conditions if condition.target_requires_wrapping()]
|
|
298
|
+
|
|
299
|
+
def set_llm_function_names(self) -> None:
|
|
300
|
+
"""Set the LLM function names for all LLM conditions, creating unique names for each function."""
|
|
301
|
+
for i, condition in enumerate(self.llm_conditions):
|
|
302
|
+
# Function names are made unique and allow multiple OnCondition's to the same agent
|
|
303
|
+
condition.llm_function_name = f"transfer_to_{condition.target.normalized_name()}_{i + 1}"
|
|
@@ -0,0 +1,93 @@
|
|
|
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, Any
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from .context_str import ContextStr
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
# Avoid circular import
|
|
13
|
+
from ..conversable_agent import ConversableAgent
|
|
14
|
+
|
|
15
|
+
__all__ = ["ContextStrLLMCondition", "LLMCondition", "StringLLMCondition"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LLMCondition(BaseModel):
|
|
19
|
+
"""Protocol for conditions evaluated by an LLM."""
|
|
20
|
+
|
|
21
|
+
def get_prompt(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> str:
|
|
22
|
+
"""Get the prompt text for LLM evaluation.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
agent: The agent evaluating the condition
|
|
26
|
+
messages: The conversation history
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
The prompt text to be evaluated by the LLM
|
|
30
|
+
"""
|
|
31
|
+
raise NotImplementedError("Requires subclasses to implement.")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class StringLLMCondition(LLMCondition):
|
|
35
|
+
"""Simple string-based LLM condition.
|
|
36
|
+
|
|
37
|
+
This condition provides a static string prompt to be evaluated by an LLM.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
prompt: str
|
|
41
|
+
|
|
42
|
+
def __init__(self, prompt: str, **data: Any) -> None:
|
|
43
|
+
"""Initialize with a prompt string as a positional parameter.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
prompt: The static prompt string to evaluate
|
|
47
|
+
data: Additional data for the parent class
|
|
48
|
+
"""
|
|
49
|
+
super().__init__(prompt=prompt, **data)
|
|
50
|
+
|
|
51
|
+
def get_prompt(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> str:
|
|
52
|
+
"""Return the static prompt string.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
agent: The agent evaluating the condition (not used)
|
|
56
|
+
messages: The conversation history (not used)
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
The static prompt string
|
|
60
|
+
"""
|
|
61
|
+
return self.prompt
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ContextStrLLMCondition(LLMCondition):
|
|
65
|
+
"""Context variable-based LLM condition.
|
|
66
|
+
|
|
67
|
+
This condition uses a ContextStr object with context variable placeholders that
|
|
68
|
+
will be substituted before being evaluated by an LLM.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
context_str: ContextStr
|
|
72
|
+
|
|
73
|
+
def __init__(self, context_str: ContextStr, **data: Any) -> None:
|
|
74
|
+
"""Initialize with a context string as a positional parameter.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
context_str: The ContextStr object with variable placeholders
|
|
78
|
+
data: Additional data for the parent class
|
|
79
|
+
"""
|
|
80
|
+
super().__init__(context_str=context_str, **data)
|
|
81
|
+
|
|
82
|
+
def get_prompt(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> str:
|
|
83
|
+
"""Return the prompt with context variables substituted.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
agent: The agent evaluating the condition (provides context variables)
|
|
87
|
+
messages: The conversation history (not used)
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
The prompt with context variables substituted
|
|
91
|
+
"""
|
|
92
|
+
result = self.context_str.format(agent.context_variables)
|
|
93
|
+
return result if result is not None else ""
|