ag2 0.9.1a1__py3-none-any.whl → 0.9.1.post0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ag2 might be problematic. Click here for more details.
- {ag2-0.9.1a1.dist-info → ag2-0.9.1.post0.dist-info}/METADATA +264 -73
- ag2-0.9.1.post0.dist-info/RECORD +392 -0
- {ag2-0.9.1a1.dist-info → ag2-0.9.1.post0.dist-info}/WHEEL +1 -2
- autogen/__init__.py +89 -0
- autogen/_website/__init__.py +3 -0
- autogen/_website/generate_api_references.py +427 -0
- autogen/_website/generate_mkdocs.py +1174 -0
- autogen/_website/notebook_processor.py +476 -0
- autogen/_website/process_notebooks.py +656 -0
- autogen/_website/utils.py +412 -0
- autogen/agentchat/__init__.py +44 -0
- autogen/agentchat/agent.py +182 -0
- autogen/agentchat/assistant_agent.py +85 -0
- autogen/agentchat/chat.py +309 -0
- autogen/agentchat/contrib/__init__.py +5 -0
- autogen/agentchat/contrib/agent_eval/README.md +7 -0
- autogen/agentchat/contrib/agent_eval/agent_eval.py +108 -0
- autogen/agentchat/contrib/agent_eval/criterion.py +43 -0
- autogen/agentchat/contrib/agent_eval/critic_agent.py +44 -0
- autogen/agentchat/contrib/agent_eval/quantifier_agent.py +39 -0
- autogen/agentchat/contrib/agent_eval/subcritic_agent.py +45 -0
- autogen/agentchat/contrib/agent_eval/task.py +42 -0
- autogen/agentchat/contrib/agent_optimizer.py +429 -0
- autogen/agentchat/contrib/capabilities/__init__.py +5 -0
- autogen/agentchat/contrib/capabilities/agent_capability.py +20 -0
- autogen/agentchat/contrib/capabilities/generate_images.py +301 -0
- autogen/agentchat/contrib/capabilities/teachability.py +393 -0
- autogen/agentchat/contrib/capabilities/text_compressors.py +66 -0
- autogen/agentchat/contrib/capabilities/tools_capability.py +22 -0
- autogen/agentchat/contrib/capabilities/transform_messages.py +93 -0
- autogen/agentchat/contrib/capabilities/transforms.py +566 -0
- autogen/agentchat/contrib/capabilities/transforms_util.py +122 -0
- autogen/agentchat/contrib/capabilities/vision_capability.py +214 -0
- autogen/agentchat/contrib/captainagent/__init__.py +9 -0
- autogen/agentchat/contrib/captainagent/agent_builder.py +790 -0
- autogen/agentchat/contrib/captainagent/captainagent.py +512 -0
- autogen/agentchat/contrib/captainagent/tool_retriever.py +335 -0
- autogen/agentchat/contrib/captainagent/tools/README.md +44 -0
- autogen/agentchat/contrib/captainagent/tools/__init__.py +5 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_correlation.py +40 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/calculate_skewness_and_kurtosis.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_iqr.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/detect_outlier_zscore.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/explore_csv.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/data_analysis/shapiro_wilk_test.py +30 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_download.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/arxiv_search.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_image.py +53 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/extract_pdf_text.py +38 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_wikipedia_text.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/get_youtube_caption.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/image_qa.py +60 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/optical_character_recognition.py +61 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/perform_web_search.py +47 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/scrape_wikipedia_tables.py +33 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/transcribe_audio_file.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/information_retrieval/youtube_download.py +35 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_circle_area_from_diameter.py +21 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_day_of_the_week.py +18 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_fraction_sum.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_matrix_power.py +31 -0
- autogen/agentchat/contrib/captainagent/tools/math/calculate_reflected_point.py +16 -0
- autogen/agentchat/contrib/captainagent/tools/math/complex_numbers_product.py +25 -0
- autogen/agentchat/contrib/captainagent/tools/math/compute_currency_conversion.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/count_distinct_permutations.py +27 -0
- autogen/agentchat/contrib/captainagent/tools/math/evaluate_expression.py +28 -0
- autogen/agentchat/contrib/captainagent/tools/math/find_continuity_point.py +34 -0
- autogen/agentchat/contrib/captainagent/tools/math/fraction_to_mixed_numbers.py +39 -0
- autogen/agentchat/contrib/captainagent/tools/math/modular_inverse_sum.py +23 -0
- autogen/agentchat/contrib/captainagent/tools/math/simplify_mixed_numbers.py +36 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_digit_factorials.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/math/sum_of_primes_below.py +15 -0
- autogen/agentchat/contrib/captainagent/tools/requirements.txt +10 -0
- autogen/agentchat/contrib/captainagent/tools/tool_description.tsv +34 -0
- autogen/agentchat/contrib/gpt_assistant_agent.py +526 -0
- autogen/agentchat/contrib/graph_rag/__init__.py +9 -0
- autogen/agentchat/contrib/graph_rag/document.py +29 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +170 -0
- autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +103 -0
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +53 -0
- autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +63 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +268 -0
- autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +83 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +210 -0
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +93 -0
- autogen/agentchat/contrib/img_utils.py +397 -0
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +117 -0
- autogen/agentchat/contrib/llava_agent.py +187 -0
- autogen/agentchat/contrib/math_user_proxy_agent.py +464 -0
- autogen/agentchat/contrib/multimodal_conversable_agent.py +125 -0
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +324 -0
- autogen/agentchat/contrib/rag/__init__.py +10 -0
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +272 -0
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +198 -0
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +329 -0
- autogen/agentchat/contrib/rag/query_engine.py +74 -0
- autogen/agentchat/contrib/retrieve_assistant_agent.py +56 -0
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +703 -0
- autogen/agentchat/contrib/society_of_mind_agent.py +199 -0
- autogen/agentchat/contrib/swarm_agent.py +1425 -0
- autogen/agentchat/contrib/text_analyzer_agent.py +79 -0
- autogen/agentchat/contrib/vectordb/__init__.py +5 -0
- autogen/agentchat/contrib/vectordb/base.py +232 -0
- autogen/agentchat/contrib/vectordb/chromadb.py +315 -0
- autogen/agentchat/contrib/vectordb/couchbase.py +407 -0
- autogen/agentchat/contrib/vectordb/mongodb.py +550 -0
- autogen/agentchat/contrib/vectordb/pgvectordb.py +928 -0
- autogen/agentchat/contrib/vectordb/qdrant.py +320 -0
- autogen/agentchat/contrib/vectordb/utils.py +126 -0
- autogen/agentchat/contrib/web_surfer.py +303 -0
- autogen/agentchat/conversable_agent.py +4020 -0
- autogen/agentchat/group/__init__.py +64 -0
- autogen/agentchat/group/available_condition.py +91 -0
- autogen/agentchat/group/context_condition.py +77 -0
- autogen/agentchat/group/context_expression.py +238 -0
- autogen/agentchat/group/context_str.py +41 -0
- autogen/agentchat/group/context_variables.py +192 -0
- autogen/agentchat/group/group_tool_executor.py +202 -0
- autogen/agentchat/group/group_utils.py +591 -0
- autogen/agentchat/group/handoffs.py +244 -0
- autogen/agentchat/group/llm_condition.py +93 -0
- autogen/agentchat/group/multi_agent_chat.py +237 -0
- autogen/agentchat/group/on_condition.py +58 -0
- autogen/agentchat/group/on_context_condition.py +54 -0
- autogen/agentchat/group/patterns/__init__.py +18 -0
- autogen/agentchat/group/patterns/auto.py +159 -0
- autogen/agentchat/group/patterns/manual.py +176 -0
- autogen/agentchat/group/patterns/pattern.py +288 -0
- autogen/agentchat/group/patterns/random.py +106 -0
- autogen/agentchat/group/patterns/round_robin.py +117 -0
- autogen/agentchat/group/reply_result.py +26 -0
- autogen/agentchat/group/speaker_selection_result.py +41 -0
- autogen/agentchat/group/targets/__init__.py +4 -0
- autogen/agentchat/group/targets/group_chat_target.py +132 -0
- autogen/agentchat/group/targets/group_manager_target.py +151 -0
- autogen/agentchat/group/targets/transition_target.py +413 -0
- autogen/agentchat/group/targets/transition_utils.py +6 -0
- autogen/agentchat/groupchat.py +1694 -0
- autogen/agentchat/realtime/__init__.py +3 -0
- autogen/agentchat/realtime/experimental/__init__.py +20 -0
- autogen/agentchat/realtime/experimental/audio_adapters/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +148 -0
- autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +139 -0
- autogen/agentchat/realtime/experimental/audio_observer.py +42 -0
- autogen/agentchat/realtime/experimental/clients/__init__.py +15 -0
- autogen/agentchat/realtime/experimental/clients/gemini/__init__.py +7 -0
- autogen/agentchat/realtime/experimental/clients/gemini/client.py +274 -0
- autogen/agentchat/realtime/experimental/clients/oai/__init__.py +8 -0
- autogen/agentchat/realtime/experimental/clients/oai/base_client.py +220 -0
- autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +243 -0
- autogen/agentchat/realtime/experimental/clients/oai/utils.py +48 -0
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +190 -0
- autogen/agentchat/realtime/experimental/function_observer.py +85 -0
- autogen/agentchat/realtime/experimental/realtime_agent.py +158 -0
- autogen/agentchat/realtime/experimental/realtime_events.py +42 -0
- autogen/agentchat/realtime/experimental/realtime_observer.py +100 -0
- autogen/agentchat/realtime/experimental/realtime_swarm.py +475 -0
- autogen/agentchat/realtime/experimental/websockets.py +21 -0
- autogen/agentchat/realtime_agent/__init__.py +21 -0
- autogen/agentchat/user_proxy_agent.py +111 -0
- autogen/agentchat/utils.py +206 -0
- autogen/agents/__init__.py +3 -0
- autogen/agents/contrib/__init__.py +10 -0
- autogen/agents/contrib/time/__init__.py +8 -0
- autogen/agents/contrib/time/time_reply_agent.py +73 -0
- autogen/agents/contrib/time/time_tool_agent.py +51 -0
- autogen/agents/experimental/__init__.py +27 -0
- autogen/agents/experimental/deep_research/__init__.py +7 -0
- autogen/agents/experimental/deep_research/deep_research.py +52 -0
- autogen/agents/experimental/discord/__init__.py +7 -0
- autogen/agents/experimental/discord/discord.py +66 -0
- autogen/agents/experimental/document_agent/__init__.py +19 -0
- autogen/agents/experimental/document_agent/chroma_query_engine.py +316 -0
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +118 -0
- autogen/agents/experimental/document_agent/document_agent.py +461 -0
- autogen/agents/experimental/document_agent/document_conditions.py +50 -0
- autogen/agents/experimental/document_agent/document_utils.py +380 -0
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +220 -0
- autogen/agents/experimental/document_agent/parser_utils.py +130 -0
- autogen/agents/experimental/document_agent/url_utils.py +426 -0
- autogen/agents/experimental/reasoning/__init__.py +7 -0
- autogen/agents/experimental/reasoning/reasoning_agent.py +1178 -0
- autogen/agents/experimental/slack/__init__.py +7 -0
- autogen/agents/experimental/slack/slack.py +73 -0
- autogen/agents/experimental/telegram/__init__.py +7 -0
- autogen/agents/experimental/telegram/telegram.py +77 -0
- autogen/agents/experimental/websurfer/__init__.py +7 -0
- autogen/agents/experimental/websurfer/websurfer.py +62 -0
- autogen/agents/experimental/wikipedia/__init__.py +7 -0
- autogen/agents/experimental/wikipedia/wikipedia.py +90 -0
- autogen/browser_utils.py +309 -0
- autogen/cache/__init__.py +10 -0
- autogen/cache/abstract_cache_base.py +75 -0
- autogen/cache/cache.py +203 -0
- autogen/cache/cache_factory.py +88 -0
- autogen/cache/cosmos_db_cache.py +144 -0
- autogen/cache/disk_cache.py +102 -0
- autogen/cache/in_memory_cache.py +58 -0
- autogen/cache/redis_cache.py +123 -0
- autogen/code_utils.py +596 -0
- autogen/coding/__init__.py +22 -0
- autogen/coding/base.py +119 -0
- autogen/coding/docker_commandline_code_executor.py +268 -0
- autogen/coding/factory.py +47 -0
- autogen/coding/func_with_reqs.py +202 -0
- autogen/coding/jupyter/__init__.py +23 -0
- autogen/coding/jupyter/base.py +36 -0
- autogen/coding/jupyter/docker_jupyter_server.py +167 -0
- autogen/coding/jupyter/embedded_ipython_code_executor.py +182 -0
- autogen/coding/jupyter/import_utils.py +82 -0
- autogen/coding/jupyter/jupyter_client.py +231 -0
- autogen/coding/jupyter/jupyter_code_executor.py +160 -0
- autogen/coding/jupyter/local_jupyter_server.py +172 -0
- autogen/coding/local_commandline_code_executor.py +405 -0
- autogen/coding/markdown_code_extractor.py +45 -0
- autogen/coding/utils.py +56 -0
- autogen/doc_utils.py +34 -0
- autogen/events/__init__.py +7 -0
- autogen/events/agent_events.py +1010 -0
- autogen/events/base_event.py +99 -0
- autogen/events/client_events.py +167 -0
- autogen/events/helpers.py +36 -0
- autogen/events/print_event.py +46 -0
- autogen/exception_utils.py +73 -0
- autogen/extensions/__init__.py +5 -0
- autogen/fast_depends/__init__.py +16 -0
- autogen/fast_depends/_compat.py +80 -0
- autogen/fast_depends/core/__init__.py +14 -0
- autogen/fast_depends/core/build.py +225 -0
- autogen/fast_depends/core/model.py +576 -0
- autogen/fast_depends/dependencies/__init__.py +15 -0
- autogen/fast_depends/dependencies/model.py +29 -0
- autogen/fast_depends/dependencies/provider.py +39 -0
- autogen/fast_depends/library/__init__.py +10 -0
- autogen/fast_depends/library/model.py +46 -0
- autogen/fast_depends/py.typed +6 -0
- autogen/fast_depends/schema.py +66 -0
- autogen/fast_depends/use.py +280 -0
- autogen/fast_depends/utils.py +187 -0
- autogen/formatting_utils.py +83 -0
- autogen/function_utils.py +13 -0
- autogen/graph_utils.py +178 -0
- autogen/import_utils.py +526 -0
- autogen/interop/__init__.py +22 -0
- autogen/interop/crewai/__init__.py +7 -0
- autogen/interop/crewai/crewai.py +88 -0
- autogen/interop/interoperability.py +71 -0
- autogen/interop/interoperable.py +46 -0
- autogen/interop/langchain/__init__.py +8 -0
- autogen/interop/langchain/langchain_chat_model_factory.py +155 -0
- autogen/interop/langchain/langchain_tool.py +82 -0
- autogen/interop/litellm/__init__.py +7 -0
- autogen/interop/litellm/litellm_config_factory.py +113 -0
- autogen/interop/pydantic_ai/__init__.py +7 -0
- autogen/interop/pydantic_ai/pydantic_ai.py +168 -0
- autogen/interop/registry.py +69 -0
- autogen/io/__init__.py +15 -0
- autogen/io/base.py +151 -0
- autogen/io/console.py +56 -0
- autogen/io/processors/__init__.py +12 -0
- autogen/io/processors/base.py +21 -0
- autogen/io/processors/console_event_processor.py +56 -0
- autogen/io/run_response.py +293 -0
- autogen/io/thread_io_stream.py +63 -0
- autogen/io/websockets.py +213 -0
- autogen/json_utils.py +43 -0
- autogen/llm_config.py +379 -0
- autogen/logger/__init__.py +11 -0
- autogen/logger/base_logger.py +128 -0
- autogen/logger/file_logger.py +261 -0
- autogen/logger/logger_factory.py +42 -0
- autogen/logger/logger_utils.py +57 -0
- autogen/logger/sqlite_logger.py +523 -0
- autogen/math_utils.py +339 -0
- autogen/mcp/__init__.py +7 -0
- autogen/mcp/mcp_client.py +208 -0
- autogen/messages/__init__.py +7 -0
- autogen/messages/agent_messages.py +948 -0
- autogen/messages/base_message.py +107 -0
- autogen/messages/client_messages.py +171 -0
- autogen/messages/print_message.py +49 -0
- autogen/oai/__init__.py +53 -0
- autogen/oai/anthropic.py +714 -0
- autogen/oai/bedrock.py +628 -0
- autogen/oai/cerebras.py +299 -0
- autogen/oai/client.py +1435 -0
- autogen/oai/client_utils.py +169 -0
- autogen/oai/cohere.py +479 -0
- autogen/oai/gemini.py +990 -0
- autogen/oai/gemini_types.py +129 -0
- autogen/oai/groq.py +305 -0
- autogen/oai/mistral.py +303 -0
- autogen/oai/oai_models/__init__.py +11 -0
- autogen/oai/oai_models/_models.py +16 -0
- autogen/oai/oai_models/chat_completion.py +87 -0
- autogen/oai/oai_models/chat_completion_audio.py +32 -0
- autogen/oai/oai_models/chat_completion_message.py +86 -0
- autogen/oai/oai_models/chat_completion_message_tool_call.py +37 -0
- autogen/oai/oai_models/chat_completion_token_logprob.py +63 -0
- autogen/oai/oai_models/completion_usage.py +60 -0
- autogen/oai/ollama.py +643 -0
- autogen/oai/openai_utils.py +881 -0
- autogen/oai/together.py +370 -0
- autogen/retrieve_utils.py +491 -0
- autogen/runtime_logging.py +160 -0
- autogen/token_count_utils.py +267 -0
- autogen/tools/__init__.py +20 -0
- autogen/tools/contrib/__init__.py +9 -0
- autogen/tools/contrib/time/__init__.py +7 -0
- autogen/tools/contrib/time/time.py +41 -0
- autogen/tools/dependency_injection.py +254 -0
- autogen/tools/experimental/__init__.py +43 -0
- autogen/tools/experimental/browser_use/__init__.py +7 -0
- autogen/tools/experimental/browser_use/browser_use.py +161 -0
- autogen/tools/experimental/crawl4ai/__init__.py +7 -0
- autogen/tools/experimental/crawl4ai/crawl4ai.py +153 -0
- autogen/tools/experimental/deep_research/__init__.py +7 -0
- autogen/tools/experimental/deep_research/deep_research.py +328 -0
- autogen/tools/experimental/duckduckgo/__init__.py +7 -0
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +109 -0
- autogen/tools/experimental/google/__init__.py +14 -0
- autogen/tools/experimental/google/authentication/__init__.py +11 -0
- autogen/tools/experimental/google/authentication/credentials_hosted_provider.py +43 -0
- autogen/tools/experimental/google/authentication/credentials_local_provider.py +91 -0
- autogen/tools/experimental/google/authentication/credentials_provider.py +35 -0
- autogen/tools/experimental/google/drive/__init__.py +9 -0
- autogen/tools/experimental/google/drive/drive_functions.py +124 -0
- autogen/tools/experimental/google/drive/toolkit.py +88 -0
- autogen/tools/experimental/google/model.py +17 -0
- autogen/tools/experimental/google/toolkit_protocol.py +19 -0
- autogen/tools/experimental/google_search/__init__.py +8 -0
- autogen/tools/experimental/google_search/google_search.py +93 -0
- autogen/tools/experimental/google_search/youtube_search.py +181 -0
- autogen/tools/experimental/messageplatform/__init__.py +17 -0
- autogen/tools/experimental/messageplatform/discord/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/discord/discord.py +288 -0
- autogen/tools/experimental/messageplatform/slack/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/slack/slack.py +391 -0
- autogen/tools/experimental/messageplatform/telegram/__init__.py +7 -0
- autogen/tools/experimental/messageplatform/telegram/telegram.py +275 -0
- autogen/tools/experimental/perplexity/__init__.py +7 -0
- autogen/tools/experimental/perplexity/perplexity_search.py +260 -0
- autogen/tools/experimental/tavily/__init__.py +7 -0
- autogen/tools/experimental/tavily/tavily_search.py +183 -0
- autogen/tools/experimental/web_search_preview/__init__.py +7 -0
- autogen/tools/experimental/web_search_preview/web_search_preview.py +114 -0
- autogen/tools/experimental/wikipedia/__init__.py +7 -0
- autogen/tools/experimental/wikipedia/wikipedia.py +287 -0
- autogen/tools/function_utils.py +411 -0
- autogen/tools/tool.py +187 -0
- autogen/tools/toolkit.py +86 -0
- autogen/types.py +29 -0
- autogen/version.py +7 -0
- ag2-0.9.1a1.dist-info/RECORD +0 -6
- ag2-0.9.1a1.dist-info/top_level.txt +0 -1
- {ag2-0.9.1a1.dist-info → ag2-0.9.1.post0.dist-info/licenses}/LICENSE +0 -0
- {ag2-0.9.1a1.dist-info → ag2-0.9.1.post0.dist-info/licenses}/NOTICE.md +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
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.transition_target import (
|
|
28
|
+
AgentNameTarget,
|
|
29
|
+
AgentTarget,
|
|
30
|
+
AskUserTarget,
|
|
31
|
+
NestedChatTarget,
|
|
32
|
+
RevertToUserTarget,
|
|
33
|
+
StayTarget,
|
|
34
|
+
TerminateTarget,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"AgentNameTarget",
|
|
39
|
+
"AgentTarget",
|
|
40
|
+
"AskUserTarget",
|
|
41
|
+
"ContextExpression",
|
|
42
|
+
"ContextStr",
|
|
43
|
+
"ContextStrLLMCondition",
|
|
44
|
+
"ContextVariables",
|
|
45
|
+
"ExpressionAvailableCondition",
|
|
46
|
+
"ExpressionContextCondition",
|
|
47
|
+
"GroupChatConfig",
|
|
48
|
+
"GroupChatTarget",
|
|
49
|
+
# "GroupManagerSelectionMessageContextStr",
|
|
50
|
+
# "GroupManagerSelectionMessageString",
|
|
51
|
+
# "GroupManagerTarget",
|
|
52
|
+
"Handoffs",
|
|
53
|
+
"NestedChatTarget",
|
|
54
|
+
"OnCondition",
|
|
55
|
+
"OnContextCondition",
|
|
56
|
+
"ReplyResult",
|
|
57
|
+
"RevertToUserTarget",
|
|
58
|
+
"SpeakerSelectionResult",
|
|
59
|
+
"StayTarget",
|
|
60
|
+
"StringAvailableCondition",
|
|
61
|
+
"StringContextCondition",
|
|
62
|
+
"StringLLMCondition",
|
|
63
|
+
"TerminateTarget",
|
|
64
|
+
]
|
|
@@ -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.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
expression (str): A string containing a logical expression with context variable references.
|
|
20
|
+
- Variable references use ${var_name} syntax: ${logged_in}, ${attempts}
|
|
21
|
+
- String literals can use normal quotes: 'hello', "world"
|
|
22
|
+
- Supported operators:
|
|
23
|
+
- Logical: not/!, and/&, or/|
|
|
24
|
+
- Comparison: >, <, >=, <=, ==, !=
|
|
25
|
+
- Supported functions:
|
|
26
|
+
- len(${var_name}): Gets the length of a list, string, or other collection
|
|
27
|
+
- Parentheses can be used for grouping
|
|
28
|
+
- Examples:
|
|
29
|
+
- "not ${logged_in} and ${is_admin} or ${guest_checkout}"
|
|
30
|
+
- "!${logged_in} & ${is_admin} | ${guest_checkout}"
|
|
31
|
+
- "len(${orders}) > 0 & ${user_active}"
|
|
32
|
+
- "len(${cart_items}) == 0 | ${checkout_started}"
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
SyntaxError: If the expression cannot be parsed
|
|
36
|
+
ValueError: If the expression contains disallowed operations
|
|
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,41 @@
|
|
|
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 Optional
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from .context_variables import ContextVariables
|
|
10
|
+
|
|
11
|
+
__all__ = ["ContextStr"]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ContextStr(BaseModel):
|
|
15
|
+
"""A string that requires context variable substitution.
|
|
16
|
+
|
|
17
|
+
Use the format method to substitute context variables into the string.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
"""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."""
|
|
21
|
+
template: str
|
|
22
|
+
|
|
23
|
+
def format(self, context_variables: ContextVariables) -> Optional[str]:
|
|
24
|
+
"""Substitute context variables into the string.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
context_variables (ContextVariables): The context variables to substitute into the string.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Optional[str]: The formatted string with context variables substituted.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
context = context_variables.to_dict()
|
|
34
|
+
|
|
35
|
+
if not context:
|
|
36
|
+
return self.template
|
|
37
|
+
|
|
38
|
+
return self.template.format(**context)
|
|
39
|
+
|
|
40
|
+
def __str__(self) -> str:
|
|
41
|
+
return f"ContextStr, unformatted: {self.template}"
|