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,67 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
__all__: list[str] = []
|
|
6
|
+
|
|
7
|
+
from .available_condition import ExpressionAvailableCondition, StringAvailableCondition
|
|
8
|
+
from .context_condition import ExpressionContextCondition, StringContextCondition
|
|
9
|
+
from .context_expression import ContextExpression
|
|
10
|
+
from .context_str import ContextStr
|
|
11
|
+
from .context_variables import ContextVariables
|
|
12
|
+
from .handoffs import Handoffs
|
|
13
|
+
from .llm_condition import ContextStrLLMCondition, StringLLMCondition
|
|
14
|
+
from .on_condition import OnCondition
|
|
15
|
+
from .on_context_condition import OnContextCondition
|
|
16
|
+
from .reply_result import ReplyResult
|
|
17
|
+
from .speaker_selection_result import SpeakerSelectionResult
|
|
18
|
+
from .targets.group_chat_target import GroupChatConfig, GroupChatTarget
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
from .targets.group_manager_target import (
|
|
22
|
+
GroupManagerSelectionMessageContextStr,
|
|
23
|
+
GroupManagerSelectionMessageString,
|
|
24
|
+
GroupManagerTarget,
|
|
25
|
+
)
|
|
26
|
+
"""
|
|
27
|
+
from .targets.function_target import FunctionTarget, FunctionTargetResult
|
|
28
|
+
from .targets.transition_target import (
|
|
29
|
+
AgentNameTarget,
|
|
30
|
+
AgentTarget,
|
|
31
|
+
AskUserTarget,
|
|
32
|
+
NestedChatTarget,
|
|
33
|
+
RevertToUserTarget,
|
|
34
|
+
StayTarget,
|
|
35
|
+
TerminateTarget,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"AgentNameTarget",
|
|
40
|
+
"AgentTarget",
|
|
41
|
+
"AskUserTarget",
|
|
42
|
+
"ContextExpression",
|
|
43
|
+
"ContextStr",
|
|
44
|
+
"ContextStrLLMCondition",
|
|
45
|
+
"ContextVariables",
|
|
46
|
+
"ExpressionAvailableCondition",
|
|
47
|
+
"ExpressionContextCondition",
|
|
48
|
+
"FunctionTarget",
|
|
49
|
+
"FunctionTargetResult",
|
|
50
|
+
"GroupChatConfig",
|
|
51
|
+
"GroupChatTarget",
|
|
52
|
+
# "GroupManagerSelectionMessageContextStr",
|
|
53
|
+
# "GroupManagerSelectionMessageString",
|
|
54
|
+
# "GroupManagerTarget",
|
|
55
|
+
"Handoffs",
|
|
56
|
+
"NestedChatTarget",
|
|
57
|
+
"OnCondition",
|
|
58
|
+
"OnContextCondition",
|
|
59
|
+
"ReplyResult",
|
|
60
|
+
"RevertToUserTarget",
|
|
61
|
+
"SpeakerSelectionResult",
|
|
62
|
+
"StayTarget",
|
|
63
|
+
"StringAvailableCondition",
|
|
64
|
+
"StringContextCondition",
|
|
65
|
+
"StringLLMCondition",
|
|
66
|
+
"TerminateTarget",
|
|
67
|
+
]
|
|
@@ -0,0 +1,91 @@
|
|
|
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_expression import ContextExpression
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
# Avoid circular import
|
|
13
|
+
from ..conversable_agent import ConversableAgent
|
|
14
|
+
|
|
15
|
+
__all__ = ["AvailableCondition", "ExpressionAvailableCondition", "StringAvailableCondition"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AvailableCondition(BaseModel):
|
|
19
|
+
"""Protocol for determining if a condition is available to be evaluated."""
|
|
20
|
+
|
|
21
|
+
def is_available(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> bool:
|
|
22
|
+
"""Determine if the condition should be considered for evaluation.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
agent: The agent evaluating the condition
|
|
26
|
+
messages: The conversation history
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
True if the condition should be evaluated, False otherwise
|
|
30
|
+
"""
|
|
31
|
+
raise NotImplementedError("Requires subclasses to implement.")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class StringAvailableCondition(AvailableCondition):
|
|
35
|
+
"""String-based available condition.
|
|
36
|
+
|
|
37
|
+
This condition checks if a named context variable exists and is truthy.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
context_variable: str
|
|
41
|
+
|
|
42
|
+
def __init__(self, context_variable: str, **data: Any) -> None:
|
|
43
|
+
"""Initialize with a context variable name as a positional parameter.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
context_variable: The name of the context variable to check
|
|
47
|
+
data: Additional data for the parent class
|
|
48
|
+
"""
|
|
49
|
+
super().__init__(context_variable=context_variable, **data)
|
|
50
|
+
|
|
51
|
+
def is_available(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> bool:
|
|
52
|
+
"""Check if the named context variable is truthy.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
agent: The agent with context variables
|
|
56
|
+
messages: The conversation history (not used)
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
True if the variable exists and is truthy, False otherwise
|
|
60
|
+
"""
|
|
61
|
+
return bool(agent.context_variables.get(self.context_variable, False))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ExpressionAvailableCondition(AvailableCondition):
|
|
65
|
+
"""Expression-based available condition.
|
|
66
|
+
|
|
67
|
+
This condition evaluates a ContextExpression against the context variables.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
expression: ContextExpression
|
|
71
|
+
|
|
72
|
+
def __init__(self, expression: ContextExpression, **data: Any) -> None:
|
|
73
|
+
"""Initialize with an expression as a positional parameter.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
expression: The context expression to evaluate
|
|
77
|
+
data: Additional data for the parent class
|
|
78
|
+
"""
|
|
79
|
+
super().__init__(expression=expression, **data)
|
|
80
|
+
|
|
81
|
+
def is_available(self, agent: "ConversableAgent", messages: list[dict[str, Any]]) -> bool:
|
|
82
|
+
"""Evaluate the expression against the context variables.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
agent: The agent with context variables
|
|
86
|
+
messages: The conversation history (not used)
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Boolean result of the expression evaluation
|
|
90
|
+
"""
|
|
91
|
+
return self.expression.evaluate(agent.context_variables)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
from .context_expression import ContextExpression
|
|
11
|
+
from .context_variables import ContextVariables
|
|
12
|
+
|
|
13
|
+
__all__ = ["ContextCondition", "ExpressionContextCondition", "StringContextCondition"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ContextCondition(BaseModel):
|
|
17
|
+
"""Protocol for conditions evaluated directly using context variables."""
|
|
18
|
+
|
|
19
|
+
def evaluate(self, context_variables: ContextVariables) -> bool:
|
|
20
|
+
"""Evaluate the condition to a boolean result.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
context_variables: The context variables to evaluate against
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Boolean result of the condition evaluation
|
|
27
|
+
"""
|
|
28
|
+
raise NotImplementedError("Requires subclasses to implement.")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StringContextCondition(ContextCondition):
|
|
32
|
+
"""Simple string-based context condition.
|
|
33
|
+
|
|
34
|
+
This condition checks if a named context variable exists and is truthy.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
variable_name: str
|
|
38
|
+
|
|
39
|
+
def evaluate(self, context_variables: ContextVariables) -> bool:
|
|
40
|
+
"""Check if the named context variable is truthy.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
context_variables: The context variables to check against
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
True if the variable exists and is truthy, False otherwise
|
|
47
|
+
"""
|
|
48
|
+
return bool(context_variables.get(self.variable_name, False))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ExpressionContextCondition(ContextCondition):
|
|
52
|
+
"""Complex expression-based context condition.
|
|
53
|
+
|
|
54
|
+
This condition evaluates a ContextExpression against the context variables.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
expression: ContextExpression
|
|
58
|
+
|
|
59
|
+
def __init__(self, expression: ContextExpression, **data: Any) -> None:
|
|
60
|
+
"""Initialize with an expression as a positional parameter.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
expression: The context expression to evaluate
|
|
64
|
+
data: Additional data for the parent class
|
|
65
|
+
"""
|
|
66
|
+
super().__init__(expression=expression, **data)
|
|
67
|
+
|
|
68
|
+
def evaluate(self, context_variables: ContextVariables) -> bool:
|
|
69
|
+
"""Evaluate the expression against the context variables.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
context_variables: The context variables to evaluate against
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Boolean result of the expression evaluation
|
|
76
|
+
"""
|
|
77
|
+
return self.expression.evaluate(context_variables)
|
|
@@ -0,0 +1,238 @@
|
|
|
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 ast
|
|
6
|
+
import re
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from ...doc_utils import export_module
|
|
10
|
+
from .context_variables import ContextVariables
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
@export_module("autogen")
|
|
15
|
+
class ContextExpression:
|
|
16
|
+
"""A class to evaluate logical expressions using context variables.\n
|
|
17
|
+
\n
|
|
18
|
+
Args:\n
|
|
19
|
+
expression (str): A string containing a logical expression with context variable references.\n
|
|
20
|
+
- Variable references use ${var_name} syntax: ${logged_in}, ${attempts}\n
|
|
21
|
+
- String literals can use normal quotes: 'hello', "world"\n
|
|
22
|
+
- Supported operators:\n
|
|
23
|
+
- Logical: not/!, and/&, or/|\n
|
|
24
|
+
- Comparison: >, <, >=, <=, ==, !=\n
|
|
25
|
+
- Supported functions:\n
|
|
26
|
+
- len(${var_name}): Gets the length of a list, string, or other collection\n
|
|
27
|
+
- Parentheses can be used for grouping\n
|
|
28
|
+
- Examples:\n
|
|
29
|
+
- "not ${logged_in} and ${is_admin} or ${guest_checkout}"\n
|
|
30
|
+
- "!${logged_in} & ${is_admin} | ${guest_checkout}"\n
|
|
31
|
+
- "len(${orders}) > 0 & ${user_active}"\n
|
|
32
|
+
- "len(${cart_items}) == 0 | ${checkout_started}"\n
|
|
33
|
+
\n
|
|
34
|
+
Raises:\n
|
|
35
|
+
SyntaxError: If the expression cannot be parsed\n
|
|
36
|
+
ValueError: If the expression contains disallowed operations\n
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
expression: str
|
|
40
|
+
|
|
41
|
+
def __post_init__(self) -> None:
|
|
42
|
+
# Validate the expression immediately upon creation
|
|
43
|
+
try:
|
|
44
|
+
# Extract variable references and replace with placeholders
|
|
45
|
+
self._variable_names = self._extract_variable_names(self.expression)
|
|
46
|
+
|
|
47
|
+
# Convert symbolic operators to Python keywords
|
|
48
|
+
python_expr = self._convert_to_python_syntax(self.expression)
|
|
49
|
+
|
|
50
|
+
# Sanitize for AST parsing
|
|
51
|
+
sanitized_expr = self._prepare_for_ast(python_expr)
|
|
52
|
+
|
|
53
|
+
# Use ast to parse and validate the expression
|
|
54
|
+
self._ast = ast.parse(sanitized_expr, mode="eval")
|
|
55
|
+
|
|
56
|
+
# Verify it only contains allowed operations
|
|
57
|
+
self._validate_operations(self._ast.body)
|
|
58
|
+
|
|
59
|
+
# Store the Python-syntax version for evaluation
|
|
60
|
+
self._python_expr = python_expr
|
|
61
|
+
|
|
62
|
+
except SyntaxError as e:
|
|
63
|
+
raise SyntaxError(f"Invalid expression syntax in '{self.expression}': {str(e)}")
|
|
64
|
+
except Exception as e:
|
|
65
|
+
raise ValueError(f"Error validating expression '{self.expression}': {str(e)}")
|
|
66
|
+
|
|
67
|
+
def _extract_variable_names(self, expr: str) -> list[str]:
|
|
68
|
+
"""Extract all variable references ${var_name} from the expression."""
|
|
69
|
+
# Find all patterns like ${var_name}
|
|
70
|
+
matches = re.findall(r"\${([^}]*)}", expr)
|
|
71
|
+
return matches
|
|
72
|
+
|
|
73
|
+
def _convert_to_python_syntax(self, expr: str) -> str:
|
|
74
|
+
"""Convert symbolic operators to Python keywords."""
|
|
75
|
+
# We need to be careful about operators inside string literals
|
|
76
|
+
# First, temporarily replace string literals with placeholders
|
|
77
|
+
string_literals = []
|
|
78
|
+
|
|
79
|
+
def replace_string_literal(match: re.Match[str]) -> str:
|
|
80
|
+
string_literals.append(match.group(0))
|
|
81
|
+
return f"__STRING_LITERAL_{len(string_literals) - 1}__"
|
|
82
|
+
|
|
83
|
+
# Replace both single and double quoted strings
|
|
84
|
+
expr_without_strings = re.sub(r"'[^']*'|\"[^\"]*\"", replace_string_literal, expr)
|
|
85
|
+
|
|
86
|
+
# Handle the NOT operator (!) - no parentheses handling needed
|
|
87
|
+
# Replace standalone ! before variables or expressions
|
|
88
|
+
expr_without_strings = re.sub(r"!\s*(\${|\()", "not \\1", expr_without_strings)
|
|
89
|
+
|
|
90
|
+
# Handle AND and OR operators - simpler approach without parentheses handling
|
|
91
|
+
expr_without_strings = re.sub(r"\s+&\s+", " and ", expr_without_strings)
|
|
92
|
+
expr_without_strings = re.sub(r"\s+\|\s+", " or ", expr_without_strings)
|
|
93
|
+
|
|
94
|
+
# Now put string literals back
|
|
95
|
+
for i, literal in enumerate(string_literals):
|
|
96
|
+
expr_without_strings = expr_without_strings.replace(f"__STRING_LITERAL_{i}__", literal)
|
|
97
|
+
|
|
98
|
+
return expr_without_strings
|
|
99
|
+
|
|
100
|
+
def _prepare_for_ast(self, expr: str) -> str:
|
|
101
|
+
"""Convert the expression to valid Python for AST parsing by replacing variables with placeholders."""
|
|
102
|
+
# Replace ${var_name} with var_name for AST parsing
|
|
103
|
+
processed_expr = expr
|
|
104
|
+
for var_name in self._variable_names:
|
|
105
|
+
processed_expr = processed_expr.replace(f"${{{var_name}}}", var_name)
|
|
106
|
+
|
|
107
|
+
return processed_expr
|
|
108
|
+
|
|
109
|
+
def _validate_operations(self, node: ast.AST) -> None:
|
|
110
|
+
"""Recursively validate that only allowed operations exist in the AST."""
|
|
111
|
+
allowed_node_types = (
|
|
112
|
+
# Boolean operations
|
|
113
|
+
ast.BoolOp,
|
|
114
|
+
ast.UnaryOp,
|
|
115
|
+
ast.And,
|
|
116
|
+
ast.Or,
|
|
117
|
+
ast.Not,
|
|
118
|
+
# Comparison operations
|
|
119
|
+
ast.Compare,
|
|
120
|
+
ast.Eq,
|
|
121
|
+
ast.NotEq,
|
|
122
|
+
ast.Lt,
|
|
123
|
+
ast.LtE,
|
|
124
|
+
ast.Gt,
|
|
125
|
+
ast.GtE,
|
|
126
|
+
# Basic nodes
|
|
127
|
+
ast.Name,
|
|
128
|
+
ast.Load,
|
|
129
|
+
ast.Constant,
|
|
130
|
+
ast.Expression,
|
|
131
|
+
# Support for basic numeric operations in comparisons
|
|
132
|
+
ast.Num,
|
|
133
|
+
ast.NameConstant,
|
|
134
|
+
# Support for negative numbers
|
|
135
|
+
ast.USub,
|
|
136
|
+
ast.UnaryOp,
|
|
137
|
+
# Support for string literals
|
|
138
|
+
ast.Str,
|
|
139
|
+
ast.Constant,
|
|
140
|
+
# Support for function calls (specifically len())
|
|
141
|
+
ast.Call,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if not isinstance(node, allowed_node_types):
|
|
145
|
+
raise ValueError(f"Operation type {type(node).__name__} is not allowed in logical expressions")
|
|
146
|
+
|
|
147
|
+
# Special validation for function calls - only allow len()
|
|
148
|
+
if isinstance(node, ast.Call):
|
|
149
|
+
if not (isinstance(node.func, ast.Name) and node.func.id == "len"):
|
|
150
|
+
raise ValueError(f"Only the len() function is allowed, got: {getattr(node.func, 'id', 'unknown')}")
|
|
151
|
+
if len(node.args) != 1:
|
|
152
|
+
raise ValueError(f"len() function must have exactly one argument, got {len(node.args)}")
|
|
153
|
+
|
|
154
|
+
# Special validation for Compare nodes
|
|
155
|
+
if isinstance(node, ast.Compare):
|
|
156
|
+
for op in node.ops:
|
|
157
|
+
if not isinstance(op, (ast.Eq, ast.NotEq, ast.Lt, ast.LtE, ast.Gt, ast.GtE)):
|
|
158
|
+
raise ValueError(f"Comparison operator {type(op).__name__} is not allowed")
|
|
159
|
+
|
|
160
|
+
# Recursively check child nodes
|
|
161
|
+
for child in ast.iter_child_nodes(node):
|
|
162
|
+
self._validate_operations(child)
|
|
163
|
+
|
|
164
|
+
def evaluate(self, context_variables: ContextVariables) -> bool:
|
|
165
|
+
"""Evaluate the expression using the provided context variables.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
context_variables: Dictionary of context variables to use for evaluation
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
bool: The result of evaluating the expression
|
|
172
|
+
|
|
173
|
+
Raises:
|
|
174
|
+
KeyError: If a variable referenced in the expression is not found in the context
|
|
175
|
+
"""
|
|
176
|
+
# Create a modified expression that we can safely evaluate
|
|
177
|
+
eval_expr = self._python_expr # Use the Python-syntax version
|
|
178
|
+
|
|
179
|
+
# First, handle len() functions with variable references inside
|
|
180
|
+
len_pattern = r"len\(\${([^}]*)}\)"
|
|
181
|
+
len_matches = list(re.finditer(len_pattern, eval_expr))
|
|
182
|
+
|
|
183
|
+
# Process all len() operations first
|
|
184
|
+
for match in len_matches:
|
|
185
|
+
var_name = match.group(1)
|
|
186
|
+
# Check if variable exists in context, raise KeyError if not
|
|
187
|
+
if not context_variables.contains(var_name):
|
|
188
|
+
raise KeyError(f"Missing context variable: '{var_name}'")
|
|
189
|
+
|
|
190
|
+
var_value = context_variables.get(var_name)
|
|
191
|
+
|
|
192
|
+
# Calculate the length - works for lists, strings, dictionaries, etc.
|
|
193
|
+
try:
|
|
194
|
+
length_value = len(var_value) # type: ignore[arg-type]
|
|
195
|
+
except TypeError:
|
|
196
|
+
# If the value doesn't support len(), treat as 0
|
|
197
|
+
length_value = 0
|
|
198
|
+
|
|
199
|
+
# Replace the len() expression with the actual length
|
|
200
|
+
full_match = match.group(0)
|
|
201
|
+
eval_expr = eval_expr.replace(full_match, str(length_value))
|
|
202
|
+
|
|
203
|
+
# Then replace remaining variable references with their values
|
|
204
|
+
for var_name in self._variable_names:
|
|
205
|
+
# Skip variables that were already processed in len() expressions
|
|
206
|
+
if any(m.group(1) == var_name for m in len_matches):
|
|
207
|
+
continue
|
|
208
|
+
|
|
209
|
+
# Check if variable exists in context, raise KeyError if not
|
|
210
|
+
if not context_variables.contains(var_name):
|
|
211
|
+
raise KeyError(f"Missing context variable: '{var_name}'")
|
|
212
|
+
|
|
213
|
+
# Get the value from context
|
|
214
|
+
var_value = context_variables.get(var_name)
|
|
215
|
+
|
|
216
|
+
# Format the value appropriately based on its type
|
|
217
|
+
if isinstance(var_value, (bool, int, float)):
|
|
218
|
+
formatted_value = str(var_value)
|
|
219
|
+
elif isinstance(var_value, str):
|
|
220
|
+
formatted_value = f"'{var_value}'" # Quote strings
|
|
221
|
+
elif isinstance(var_value, (list, dict, tuple)):
|
|
222
|
+
# For collections, convert to their boolean evaluation
|
|
223
|
+
formatted_value = str(bool(var_value))
|
|
224
|
+
else:
|
|
225
|
+
formatted_value = str(var_value)
|
|
226
|
+
|
|
227
|
+
# Replace the variable reference with the formatted value
|
|
228
|
+
eval_expr = eval_expr.replace(f"${{{var_name}}}", formatted_value)
|
|
229
|
+
|
|
230
|
+
try:
|
|
231
|
+
return eval(eval_expr) # type: ignore[no-any-return]
|
|
232
|
+
except Exception as e:
|
|
233
|
+
raise ValueError(
|
|
234
|
+
f"Error evaluating expression '{self.expression}' (are you sure you're using ${{my_context_variable_key}}): {str(e)}"
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
def __str__(self) -> str:
|
|
238
|
+
return f"ContextExpression('{self.expression}')"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from .context_variables import ContextVariables
|
|
9
|
+
|
|
10
|
+
__all__ = ["ContextStr"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ContextStr(BaseModel):
|
|
14
|
+
"""A string that requires context variable substitution.
|
|
15
|
+
|
|
16
|
+
Use the format method to substitute context variables into the string.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
"""The string to be substituted with context variables. It is expected that the string will contain `{var}` placeholders and that string format will be able to replace all values."""
|
|
20
|
+
template: str
|
|
21
|
+
|
|
22
|
+
def format(self, context_variables: ContextVariables) -> str | None:
|
|
23
|
+
"""Substitute context variables into the string.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
context_variables (ContextVariables): The context variables to substitute into the string.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Optional[str]: The formatted string with context variables substituted.
|
|
30
|
+
"""
|
|
31
|
+
context = context_variables.to_dict()
|
|
32
|
+
|
|
33
|
+
if not context:
|
|
34
|
+
return self.template
|
|
35
|
+
|
|
36
|
+
return self.template.format(**context)
|
|
37
|
+
|
|
38
|
+
def __str__(self) -> str:
|
|
39
|
+
return f"ContextStr, unformatted: {self.template}"
|
|
@@ -0,0 +1,182 @@
|
|
|
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 collections.abc import Generator, Iterable
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
__all__ = ["ContextVariables"]
|
|
11
|
+
|
|
12
|
+
# Parameter name for context variables
|
|
13
|
+
# Use the value in functions and they will be substituted with the context variables:
|
|
14
|
+
# e.g. def my_function(context_variables: ContextVariables, my_other_parameters: Any) -> Any:
|
|
15
|
+
__CONTEXT_VARIABLES_PARAM_NAME__ = "context_variables"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ContextVariables(BaseModel):
|
|
19
|
+
"""Stores and manages context variables for agentic workflows.
|
|
20
|
+
|
|
21
|
+
Utilises a dictionary-like interface for setting, getting, and removing variables.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# Internal storage for context variables
|
|
25
|
+
data: dict[str, Any] = Field(default_factory=dict)
|
|
26
|
+
|
|
27
|
+
def __init__(self, data: dict[str, Any] | None = None, **kwargs: Any) -> None:
|
|
28
|
+
"""Initialize with data dictionary as an optional positional parameter.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
data: Initial dictionary of context variables (optional)
|
|
32
|
+
kwargs: Additional keyword arguments for the parent class
|
|
33
|
+
"""
|
|
34
|
+
init_data = data or {}
|
|
35
|
+
super().__init__(data=init_data, **kwargs)
|
|
36
|
+
|
|
37
|
+
def get(self, key: str, default: Any | None = None) -> Any | None:
|
|
38
|
+
"""Get a value from the context by key.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
key: The key to retrieve
|
|
42
|
+
default: The default value to return if key is not found
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
The value associated with the key or default if not found
|
|
46
|
+
"""
|
|
47
|
+
return self.data.get(key, default)
|
|
48
|
+
|
|
49
|
+
def set(self, key: str, value: Any) -> None:
|
|
50
|
+
"""Set a value in the context by key.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
key: The key to set
|
|
54
|
+
value: The value to store
|
|
55
|
+
"""
|
|
56
|
+
self.data[key] = value
|
|
57
|
+
|
|
58
|
+
def remove(self, key: str) -> bool:
|
|
59
|
+
"""Remove a key from the context.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
key: The key to remove
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
True if the key was removed, False if it didn't exist
|
|
66
|
+
"""
|
|
67
|
+
if key in self.data:
|
|
68
|
+
del self.data[key]
|
|
69
|
+
return True
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
def keys(self) -> Iterable[str]:
|
|
73
|
+
"""Get all keys in the context.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
An iterable of all keys
|
|
77
|
+
"""
|
|
78
|
+
return self.data.keys()
|
|
79
|
+
|
|
80
|
+
def values(self) -> Iterable[Any]:
|
|
81
|
+
"""Get all values in the context.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
An iterable of all values
|
|
85
|
+
"""
|
|
86
|
+
return self.data.values()
|
|
87
|
+
|
|
88
|
+
def items(self) -> Iterable[tuple[str, Any]]:
|
|
89
|
+
"""Get all key-value pairs in the context.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
An iterable of all key-value pairs
|
|
93
|
+
"""
|
|
94
|
+
return self.data.items()
|
|
95
|
+
|
|
96
|
+
def clear(self) -> None:
|
|
97
|
+
"""Clear all keys and values from the context."""
|
|
98
|
+
self.data.clear()
|
|
99
|
+
|
|
100
|
+
def contains(self, key: str) -> bool:
|
|
101
|
+
"""Check if a key exists in the context.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
key: The key to check
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
True if the key exists, False otherwise
|
|
108
|
+
"""
|
|
109
|
+
return key in self.data
|
|
110
|
+
|
|
111
|
+
def update(self, other: dict[str, Any]) -> None:
|
|
112
|
+
"""Update context with key-value pairs from another dictionary.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
other: Dictionary containing key-value pairs to add
|
|
116
|
+
"""
|
|
117
|
+
self.data.update(other)
|
|
118
|
+
|
|
119
|
+
def to_dict(self) -> dict[str, Any]:
|
|
120
|
+
"""Convert context variables to a dictionary.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Dictionary representation of all context variables
|
|
124
|
+
"""
|
|
125
|
+
return self.data.copy()
|
|
126
|
+
|
|
127
|
+
# Dictionary-compatible interface
|
|
128
|
+
def __getitem__(self, key: str) -> Any:
|
|
129
|
+
"""Get a value using dictionary syntax: context[key]"""
|
|
130
|
+
try:
|
|
131
|
+
return self.data[key]
|
|
132
|
+
except KeyError:
|
|
133
|
+
raise KeyError(f"Context variable '{key}' not found")
|
|
134
|
+
|
|
135
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
136
|
+
"""Set a value using dictionary syntax: context[key] = value"""
|
|
137
|
+
self.data[key] = value
|
|
138
|
+
|
|
139
|
+
def __delitem__(self, key: str) -> None:
|
|
140
|
+
"""Delete a key using dictionary syntax: del context[key]"""
|
|
141
|
+
try:
|
|
142
|
+
del self.data[key]
|
|
143
|
+
except KeyError:
|
|
144
|
+
raise KeyError(f"Cannot delete non-existent context variable '{key}'")
|
|
145
|
+
|
|
146
|
+
def __contains__(self, key: str) -> bool:
|
|
147
|
+
"""Check if key exists using 'in' operator: key in context"""
|
|
148
|
+
return key in self.data
|
|
149
|
+
|
|
150
|
+
def __len__(self) -> int:
|
|
151
|
+
"""Get the number of items: len(context)"""
|
|
152
|
+
return len(self.data)
|
|
153
|
+
|
|
154
|
+
def __iter__(self) -> Generator[tuple[str, Any], None, None]:
|
|
155
|
+
"""Iterate over keys: for key in context"""
|
|
156
|
+
for key in self.data:
|
|
157
|
+
yield (key, self.data[key])
|
|
158
|
+
|
|
159
|
+
def __str__(self) -> str:
|
|
160
|
+
"""String representation of context variables."""
|
|
161
|
+
return f"ContextVariables({self.data})"
|
|
162
|
+
|
|
163
|
+
def __repr__(self) -> str:
|
|
164
|
+
"""Detailed representation of context variables."""
|
|
165
|
+
return f"ContextVariables(data={self.data!r})"
|
|
166
|
+
|
|
167
|
+
# Utility methods
|
|
168
|
+
@classmethod
|
|
169
|
+
def from_dict(cls, data: dict[str, Any]) -> "ContextVariables":
|
|
170
|
+
"""Create a new ContextVariables instance from a dictionary.
|
|
171
|
+
|
|
172
|
+
E.g.:
|
|
173
|
+
my_context = {"user_id": "12345", "settings": {"theme": "dark"}}
|
|
174
|
+
context = ContextVariables.from_dict(my_context)
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
data: Dictionary of key-value pairs
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
New ContextVariables instance
|
|
181
|
+
"""
|
|
182
|
+
return cls(data=data)
|