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,294 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
+
# SPDX-License-Identifier: MIT
|
|
7
|
+
|
|
8
|
+
import queue
|
|
9
|
+
from asyncio import Queue as AsyncQueue
|
|
10
|
+
from collections.abc import AsyncIterable, Iterable, Sequence
|
|
11
|
+
from typing import Any, Optional, Protocol
|
|
12
|
+
from uuid import UUID, uuid4
|
|
13
|
+
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
|
|
16
|
+
from autogen.tools.tool import Tool
|
|
17
|
+
|
|
18
|
+
from ..agentchat.agent import Agent, LLMMessageType
|
|
19
|
+
from ..agentchat.group.context_variables import ContextVariables
|
|
20
|
+
from ..events.agent_events import ErrorEvent, InputRequestEvent, RunCompletionEvent
|
|
21
|
+
from ..events.base_event import BaseEvent
|
|
22
|
+
from .processors import (
|
|
23
|
+
AsyncConsoleEventProcessor,
|
|
24
|
+
AsyncEventProcessorProtocol,
|
|
25
|
+
ConsoleEventProcessor,
|
|
26
|
+
EventProcessorProtocol,
|
|
27
|
+
)
|
|
28
|
+
from .thread_io_stream import AsyncThreadIOStream, ThreadIOStream
|
|
29
|
+
|
|
30
|
+
Message = dict[str, Any]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class RunInfoProtocol(Protocol):
|
|
34
|
+
@property
|
|
35
|
+
def uuid(self) -> UUID: ...
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def above_run(self) -> Optional["RunResponseProtocol"]: ...
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Usage(BaseModel):
|
|
42
|
+
cost: float
|
|
43
|
+
prompt_tokens: int
|
|
44
|
+
completion_tokens: int
|
|
45
|
+
total_tokens: int
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class CostBreakdown(BaseModel):
|
|
49
|
+
total_cost: float
|
|
50
|
+
models: dict[str, Usage] = Field(default_factory=dict)
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_raw(cls, data: dict[str, Any]) -> "CostBreakdown":
|
|
54
|
+
# Extract total cost
|
|
55
|
+
total_cost = data.get("total_cost", 0.0)
|
|
56
|
+
|
|
57
|
+
# Remove total_cost key to extract models
|
|
58
|
+
model_usages = {k: Usage(**v) for k, v in data.items() if k != "total_cost"}
|
|
59
|
+
|
|
60
|
+
return cls(total_cost=total_cost, models=model_usages)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class Cost(BaseModel):
|
|
64
|
+
usage_including_cached_inference: CostBreakdown
|
|
65
|
+
usage_excluding_cached_inference: CostBreakdown
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def from_raw(cls, data: dict[str, Any]) -> "Cost":
|
|
69
|
+
return cls(
|
|
70
|
+
usage_including_cached_inference=CostBreakdown.from_raw(data.get("usage_including_cached_inference", {})),
|
|
71
|
+
usage_excluding_cached_inference=CostBreakdown.from_raw(data.get("usage_excluding_cached_inference", {})),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class RunResponseProtocol(RunInfoProtocol, Protocol):
|
|
76
|
+
@property
|
|
77
|
+
def events(self) -> Iterable[BaseEvent]: ...
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def messages(self) -> Iterable[Message]: ...
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def summary(self) -> str | None: ...
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def context_variables(self) -> ContextVariables | None: ...
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def last_speaker(self) -> str | None: ...
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def cost(self) -> Cost | None: ...
|
|
93
|
+
|
|
94
|
+
def process(self, processor: EventProcessorProtocol | None = None) -> None: ...
|
|
95
|
+
|
|
96
|
+
def set_ui_tools(self, tools: list[Tool]) -> None: ...
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class AsyncRunResponseProtocol(RunInfoProtocol, Protocol):
|
|
100
|
+
@property
|
|
101
|
+
def events(self) -> AsyncIterable[BaseEvent]: ...
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
async def messages(self) -> Iterable[Message]: ...
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
async def summary(self) -> str | None: ...
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
async def context_variables(self) -> ContextVariables | None: ...
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
async def last_speaker(self) -> str | None: ...
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
async def cost(self) -> Cost | None: ...
|
|
117
|
+
|
|
118
|
+
async def process(self, processor: AsyncEventProcessorProtocol | None = None) -> None: ...
|
|
119
|
+
|
|
120
|
+
def set_ui_tools(self, tools: list[Tool]) -> None: ...
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class RunResponse:
|
|
124
|
+
def __init__(self, iostream: ThreadIOStream, agents: list[Agent]):
|
|
125
|
+
self.iostream = iostream
|
|
126
|
+
self.agents = agents
|
|
127
|
+
self._summary: str | None = None
|
|
128
|
+
self._messages: Sequence[LLMMessageType] = []
|
|
129
|
+
self._uuid = uuid4()
|
|
130
|
+
self._context_variables: ContextVariables | None = None
|
|
131
|
+
self._last_speaker: str | None = None
|
|
132
|
+
self._cost: Cost | None = None
|
|
133
|
+
|
|
134
|
+
def _queue_generator(self, q: queue.Queue) -> Iterable[BaseEvent]: # type: ignore[type-arg]
|
|
135
|
+
"""A generator to yield items from the queue until the termination message is found."""
|
|
136
|
+
while True:
|
|
137
|
+
try:
|
|
138
|
+
# Get an item from the queue
|
|
139
|
+
event = q.get(timeout=0.1) # Adjust timeout as needed
|
|
140
|
+
|
|
141
|
+
if isinstance(event, InputRequestEvent):
|
|
142
|
+
event.content.respond = lambda response: self.iostream._output_stream.put(response) # type: ignore[attr-defined]
|
|
143
|
+
|
|
144
|
+
yield event
|
|
145
|
+
|
|
146
|
+
if isinstance(event, RunCompletionEvent):
|
|
147
|
+
self._messages = event.content.history # type: ignore[attr-defined]
|
|
148
|
+
self._last_speaker = event.content.last_speaker # type: ignore[attr-defined]
|
|
149
|
+
self._summary = event.content.summary # type: ignore[attr-defined]
|
|
150
|
+
self._context_variables = event.content.context_variables # type: ignore[attr-defined]
|
|
151
|
+
self.cost = event.content.cost # type: ignore[attr-defined]
|
|
152
|
+
break
|
|
153
|
+
|
|
154
|
+
if isinstance(event, ErrorEvent):
|
|
155
|
+
raise event.content.error # type: ignore[attr-defined]
|
|
156
|
+
except queue.Empty:
|
|
157
|
+
continue # Wait for more items in the queue
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def events(self) -> Iterable[BaseEvent]:
|
|
161
|
+
return self._queue_generator(self.iostream.input_stream)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def messages(self) -> Iterable[Message]:
|
|
165
|
+
return self._messages
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def summary(self) -> str | None:
|
|
169
|
+
return self._summary
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def above_run(self) -> Optional["RunResponseProtocol"]:
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def uuid(self) -> UUID:
|
|
177
|
+
return self._uuid
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def context_variables(self) -> ContextVariables | None:
|
|
181
|
+
return self._context_variables
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def last_speaker(self) -> str | None:
|
|
185
|
+
return self._last_speaker
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def cost(self) -> Cost | None:
|
|
189
|
+
return self._cost
|
|
190
|
+
|
|
191
|
+
@cost.setter
|
|
192
|
+
def cost(self, value: Cost | dict[str, Any]) -> None:
|
|
193
|
+
if isinstance(value, dict):
|
|
194
|
+
self._cost = Cost.from_raw(value)
|
|
195
|
+
else:
|
|
196
|
+
self._cost = value
|
|
197
|
+
|
|
198
|
+
def process(self, processor: EventProcessorProtocol | None = None) -> None:
|
|
199
|
+
processor = processor or ConsoleEventProcessor()
|
|
200
|
+
processor.process(self)
|
|
201
|
+
|
|
202
|
+
def set_ui_tools(self, tools: list[Tool]) -> None:
|
|
203
|
+
"""Set the UI tools for the agents."""
|
|
204
|
+
for agent in self.agents:
|
|
205
|
+
agent.set_ui_tools(tools)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class AsyncRunResponse:
|
|
209
|
+
def __init__(self, iostream: AsyncThreadIOStream, agents: list[Agent]):
|
|
210
|
+
self.iostream = iostream
|
|
211
|
+
self.agents = agents
|
|
212
|
+
self._summary: str | None = None
|
|
213
|
+
self._messages: Sequence[LLMMessageType] = []
|
|
214
|
+
self._uuid = uuid4()
|
|
215
|
+
self._context_variables: ContextVariables | None = None
|
|
216
|
+
self._last_speaker: str | None = None
|
|
217
|
+
self._cost: Cost | None = None
|
|
218
|
+
|
|
219
|
+
async def _queue_generator(self, q: AsyncQueue[Any]) -> AsyncIterable[BaseEvent]: # type: ignore[type-arg]
|
|
220
|
+
"""A generator to yield items from the queue until the termination message is found."""
|
|
221
|
+
while True:
|
|
222
|
+
try:
|
|
223
|
+
# Get an item from the queue
|
|
224
|
+
event = await q.get()
|
|
225
|
+
|
|
226
|
+
if isinstance(event, InputRequestEvent):
|
|
227
|
+
|
|
228
|
+
async def respond(response: str) -> None:
|
|
229
|
+
await self.iostream._output_stream.put(response)
|
|
230
|
+
|
|
231
|
+
event.content.respond = respond # type: ignore[attr-defined]
|
|
232
|
+
|
|
233
|
+
yield event
|
|
234
|
+
|
|
235
|
+
if isinstance(event, RunCompletionEvent):
|
|
236
|
+
self._messages = event.content.history # type: ignore[attr-defined]
|
|
237
|
+
self._last_speaker = event.content.last_speaker # type: ignore[attr-defined]
|
|
238
|
+
self._summary = event.content.summary # type: ignore[attr-defined]
|
|
239
|
+
self._context_variables = event.content.context_variables # type: ignore[attr-defined]
|
|
240
|
+
self.cost = event.content.cost # type: ignore[attr-defined]
|
|
241
|
+
break
|
|
242
|
+
|
|
243
|
+
if isinstance(event, ErrorEvent):
|
|
244
|
+
raise event.content.error # type: ignore[attr-defined]
|
|
245
|
+
except queue.Empty:
|
|
246
|
+
continue
|
|
247
|
+
|
|
248
|
+
@property
|
|
249
|
+
def events(self) -> AsyncIterable[BaseEvent]:
|
|
250
|
+
return self._queue_generator(self.iostream.input_stream)
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
async def messages(self) -> Iterable[Message]:
|
|
254
|
+
return self._messages
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
async def summary(self) -> str | None:
|
|
258
|
+
return self._summary
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def above_run(self) -> Optional["RunResponseProtocol"]:
|
|
262
|
+
return None
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def uuid(self) -> UUID:
|
|
266
|
+
return self._uuid
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
async def context_variables(self) -> ContextVariables | None:
|
|
270
|
+
return self._context_variables
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
async def last_speaker(self) -> str | None:
|
|
274
|
+
return self._last_speaker
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
async def cost(self) -> Cost | None:
|
|
278
|
+
return self._cost
|
|
279
|
+
|
|
280
|
+
@cost.setter
|
|
281
|
+
def cost(self, value: Cost | dict[str, Any]) -> None:
|
|
282
|
+
if isinstance(value, dict):
|
|
283
|
+
self._cost = Cost.from_raw(value)
|
|
284
|
+
else:
|
|
285
|
+
self._cost = value
|
|
286
|
+
|
|
287
|
+
async def process(self, processor: AsyncEventProcessorProtocol | None = None) -> None:
|
|
288
|
+
processor = processor or AsyncConsoleEventProcessor()
|
|
289
|
+
await processor.process(self)
|
|
290
|
+
|
|
291
|
+
def set_ui_tools(self, tools: list[Tool]) -> None:
|
|
292
|
+
"""Set the UI tools for the agents."""
|
|
293
|
+
for agent in self.agents:
|
|
294
|
+
agent.set_ui_tools(tools)
|
|
@@ -0,0 +1,63 @@
|
|
|
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 queue
|
|
6
|
+
from asyncio import Queue as AsyncQueue
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
from autogen.io.base import AsyncIOStreamProtocol, IOStreamProtocol
|
|
10
|
+
|
|
11
|
+
from ..events.agent_events import InputRequestEvent
|
|
12
|
+
from ..events.print_event import PrintEvent
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ThreadIOStream:
|
|
16
|
+
def __init__(self) -> None:
|
|
17
|
+
self._input_stream: queue.Queue = queue.Queue() # type: ignore[type-arg]
|
|
18
|
+
self._output_stream: queue.Queue = queue.Queue() # type: ignore[type-arg]
|
|
19
|
+
|
|
20
|
+
def input(self, prompt: str = "", *, password: bool = False) -> str:
|
|
21
|
+
self.send(InputRequestEvent(prompt=prompt, password=password)) # type: ignore[call-arg]
|
|
22
|
+
return self._output_stream.get() # type: ignore[no-any-return]
|
|
23
|
+
|
|
24
|
+
def print(self, *objects: Any, sep: str = " ", end: str = "\n", flush: bool = False) -> None:
|
|
25
|
+
print_message = PrintEvent(*objects, sep=sep, end=end)
|
|
26
|
+
self.send(print_message)
|
|
27
|
+
|
|
28
|
+
def send(self, message: Any) -> None:
|
|
29
|
+
self._input_stream.put(message)
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def input_stream(self) -> queue.Queue: # type: ignore[type-arg]
|
|
33
|
+
return self._input_stream
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AsyncThreadIOStream:
|
|
37
|
+
def __init__(self) -> None:
|
|
38
|
+
self._input_stream: AsyncQueue = AsyncQueue() # type: ignore[type-arg]
|
|
39
|
+
self._output_stream: AsyncQueue = AsyncQueue() # type: ignore[type-arg]
|
|
40
|
+
|
|
41
|
+
async def input(self, prompt: str = "", *, password: bool = False) -> str:
|
|
42
|
+
self.send(InputRequestEvent(prompt=prompt, password=password)) # type: ignore[call-arg]
|
|
43
|
+
return await self._output_stream.get() # type: ignore[no-any-return]
|
|
44
|
+
|
|
45
|
+
def print(self, *objects: Any, sep: str = " ", end: str = "\n", flush: bool = False) -> None:
|
|
46
|
+
print_message = PrintEvent(*objects, sep=sep, end=end)
|
|
47
|
+
self.send(print_message)
|
|
48
|
+
|
|
49
|
+
def send(self, message: Any) -> None:
|
|
50
|
+
self._input_stream.put_nowait(message)
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def input_stream(self) -> AsyncQueue[Any]:
|
|
54
|
+
return self._input_stream
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if TYPE_CHECKING:
|
|
58
|
+
|
|
59
|
+
def check_type_1(x: ThreadIOStream) -> IOStreamProtocol:
|
|
60
|
+
return x
|
|
61
|
+
|
|
62
|
+
def check_type_2(x: AsyncThreadIOStream) -> AsyncIOStreamProtocol:
|
|
63
|
+
return x
|
autogen/io/websockets.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
+
# SPDX-License-Identifier: MIT
|
|
7
|
+
import logging
|
|
8
|
+
import ssl
|
|
9
|
+
import threading
|
|
10
|
+
from collections.abc import Callable, Iterable, Iterator
|
|
11
|
+
from contextlib import contextmanager
|
|
12
|
+
from functools import partial
|
|
13
|
+
from time import sleep
|
|
14
|
+
from typing import Any, Protocol
|
|
15
|
+
|
|
16
|
+
from ..doc_utils import export_module
|
|
17
|
+
from ..events.base_event import BaseEvent
|
|
18
|
+
from ..events.print_event import PrintEvent
|
|
19
|
+
from ..import_utils import optional_import_block, require_optional_import
|
|
20
|
+
from .base import IOStream
|
|
21
|
+
|
|
22
|
+
# Check if the websockets module is available
|
|
23
|
+
with optional_import_block():
|
|
24
|
+
from websockets.sync.server import serve as ws_serve
|
|
25
|
+
|
|
26
|
+
__all__ = ("IOWebsockets",)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
logger.setLevel(logging.INFO)
|
|
31
|
+
|
|
32
|
+
# The following type and protocols are used to define the ServerConnection and WebSocketServer classes
|
|
33
|
+
# if websockets is not installed, they would be untyped
|
|
34
|
+
Data = str | bytes
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ServerConnection(Protocol):
|
|
38
|
+
def send(self, message: Data | Iterable[Data]) -> None:
|
|
39
|
+
"""Send a message to the client.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
message (Union[Data, Iterable[Data]]): The message to send.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
... # pragma: no cover
|
|
46
|
+
|
|
47
|
+
def recv(self, timeout: float | None = None) -> Data:
|
|
48
|
+
"""Receive a message from the client.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
timeout (Optional[float], optional): The timeout for the receive operation. Defaults to None.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Data: The message received from the client.
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
... # pragma: no cover
|
|
58
|
+
|
|
59
|
+
def close(self) -> None:
|
|
60
|
+
"""Close the connection."""
|
|
61
|
+
...
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class WebSocketServer(Protocol):
|
|
65
|
+
def serve_forever(self) -> None:
|
|
66
|
+
"""Run the server forever."""
|
|
67
|
+
... # pragma: no cover
|
|
68
|
+
|
|
69
|
+
def shutdown(self) -> None:
|
|
70
|
+
"""Shutdown the server."""
|
|
71
|
+
... # pragma: no cover
|
|
72
|
+
|
|
73
|
+
def __enter__(self) -> "WebSocketServer":
|
|
74
|
+
"""Enter the server context."""
|
|
75
|
+
... # pragma: no cover
|
|
76
|
+
|
|
77
|
+
def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
|
|
78
|
+
"""Exit the server context."""
|
|
79
|
+
... # pragma: no cover
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@require_optional_import("websockets", "websockets")
|
|
83
|
+
@export_module("autogen.io")
|
|
84
|
+
class IOWebsockets(IOStream):
|
|
85
|
+
"""A websocket input/output stream."""
|
|
86
|
+
|
|
87
|
+
def __init__(self, websocket: ServerConnection) -> None:
|
|
88
|
+
"""Initialize the websocket input/output stream.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
websocket (ServerConnection): The websocket server.
|
|
92
|
+
"""
|
|
93
|
+
self._websocket = websocket
|
|
94
|
+
|
|
95
|
+
@staticmethod
|
|
96
|
+
def _handler(websocket: ServerConnection, on_connect: Callable[["IOWebsockets"], None]) -> None:
|
|
97
|
+
"""The handler function for the websocket server."""
|
|
98
|
+
logger.info(f" - IOWebsockets._handler(): Client connected on {websocket}")
|
|
99
|
+
# create a new IOWebsockets instance using the websocket that is create when a client connects
|
|
100
|
+
try:
|
|
101
|
+
iowebsocket = IOWebsockets(websocket)
|
|
102
|
+
with IOStream.set_default(iowebsocket):
|
|
103
|
+
# call the on_connect function
|
|
104
|
+
try:
|
|
105
|
+
on_connect(iowebsocket)
|
|
106
|
+
except Exception as e:
|
|
107
|
+
logger.warning(f" - IOWebsockets._handler(): Error in on_connect: {e}")
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.error(f" - IOWebsockets._handler(): Unexpected error in IOWebsockets: {e}")
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
@contextmanager
|
|
113
|
+
def run_server_in_thread(
|
|
114
|
+
*,
|
|
115
|
+
host: str = "127.0.0.1",
|
|
116
|
+
port: int = 8765,
|
|
117
|
+
on_connect: Callable[["IOWebsockets"], None],
|
|
118
|
+
ssl_context: ssl.SSLContext | None = None,
|
|
119
|
+
**kwargs: Any,
|
|
120
|
+
) -> Iterator[str]:
|
|
121
|
+
"""Factory function to create a websocket input/output stream.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
host (str, optional): The host to bind the server to. Defaults to "127.0.0.1".
|
|
125
|
+
port (int, optional): The port to bind the server to. Defaults to 8765.
|
|
126
|
+
on_connect (Callable[[IOWebsockets], None]): The function to be executed on client connection. Typically creates agents and initiate chat.
|
|
127
|
+
ssl_context (Optional[ssl.SSLContext], optional): The SSL context to use for secure connections. Defaults to None.
|
|
128
|
+
kwargs (Any): Additional keyword arguments to pass to the websocket server.
|
|
129
|
+
|
|
130
|
+
Yields:
|
|
131
|
+
str: The URI of the websocket server.
|
|
132
|
+
"""
|
|
133
|
+
server_dict: dict[str, WebSocketServer] = {}
|
|
134
|
+
|
|
135
|
+
def _run_server() -> None:
|
|
136
|
+
# print(f" - _run_server(): starting server on ws://{host}:{port}", flush=True)
|
|
137
|
+
with ws_serve(
|
|
138
|
+
handler=partial(IOWebsockets._handler, on_connect=on_connect),
|
|
139
|
+
host=host,
|
|
140
|
+
port=port,
|
|
141
|
+
ssl_context=ssl_context,
|
|
142
|
+
**kwargs,
|
|
143
|
+
) as server:
|
|
144
|
+
# print(f" - _run_server(): server {server} started on ws://{host}:{port}", flush=True)
|
|
145
|
+
|
|
146
|
+
server_dict["server"] = server
|
|
147
|
+
|
|
148
|
+
# runs until the server is shutdown
|
|
149
|
+
server.serve_forever()
|
|
150
|
+
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
# start server in a separate thread
|
|
154
|
+
thread = threading.Thread(target=_run_server)
|
|
155
|
+
thread.start()
|
|
156
|
+
try:
|
|
157
|
+
while "server" not in server_dict:
|
|
158
|
+
sleep(0.1)
|
|
159
|
+
|
|
160
|
+
yield f"ws://{host}:{port}"
|
|
161
|
+
|
|
162
|
+
finally:
|
|
163
|
+
# print(f" - run_server_in_thread(): shutting down server on ws://{host}:{port}", flush=True)
|
|
164
|
+
# gracefully stop server
|
|
165
|
+
if "server" in server_dict:
|
|
166
|
+
# print(f" - run_server_in_thread(): shutting down server {server_dict['server']}", flush=True)
|
|
167
|
+
server_dict["server"].shutdown()
|
|
168
|
+
|
|
169
|
+
# wait for the thread to stop
|
|
170
|
+
if thread:
|
|
171
|
+
thread.join()
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def websocket(self) -> "ServerConnection":
|
|
175
|
+
"""The URI of the websocket server."""
|
|
176
|
+
return self._websocket
|
|
177
|
+
|
|
178
|
+
def print(self, *objects: Any, sep: str = " ", end: str = "\n", flush: bool = False) -> None:
|
|
179
|
+
"""Print data to the output stream.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
objects (any): The data to print.
|
|
183
|
+
sep (str, optional): The separator between objects. Defaults to " ".
|
|
184
|
+
end (str, optional): The end of the output. Defaults to "\n".
|
|
185
|
+
flush (bool, optional): Whether to flush the output. Defaults to False.
|
|
186
|
+
"""
|
|
187
|
+
print_message = PrintEvent(*objects, sep=sep, end=end)
|
|
188
|
+
self.send(print_message)
|
|
189
|
+
|
|
190
|
+
def send(self, message: BaseEvent) -> None:
|
|
191
|
+
"""Send a message to the output stream.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
message (Any): The message to send.
|
|
195
|
+
"""
|
|
196
|
+
self._websocket.send(message.model_dump_json())
|
|
197
|
+
|
|
198
|
+
def input(self, prompt: str = "", *, password: bool = False) -> str:
|
|
199
|
+
"""Read a line from the input stream.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
prompt (str, optional): The prompt to display. Defaults to "".
|
|
203
|
+
password (bool, optional): Whether to read a password. Defaults to False.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
str: The line read from the input stream.
|
|
207
|
+
|
|
208
|
+
"""
|
|
209
|
+
if prompt != "":
|
|
210
|
+
self._websocket.send(prompt)
|
|
211
|
+
|
|
212
|
+
msg = self._websocket.recv()
|
|
213
|
+
|
|
214
|
+
return msg.decode("utf-8") if isinstance(msg, bytes) else msg
|
autogen/json_utils.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
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 Any
|
|
6
|
+
|
|
7
|
+
from .import_utils import optional_import_block, require_optional_import
|
|
8
|
+
|
|
9
|
+
with optional_import_block():
|
|
10
|
+
from jsonschema import Draft7Validator, RefResolver
|
|
11
|
+
|
|
12
|
+
__all__ = ["resolve_json_references"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@require_optional_import("jsonschema", "gemini")
|
|
16
|
+
def resolve_json_references(schema: dict[str, Any]) -> dict[str, Any]:
|
|
17
|
+
"""Resolve JSON references in the given schema.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
schema (dict): The JSON schema with references.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
dict: The JSON schema with resolved references.
|
|
24
|
+
"""
|
|
25
|
+
resolver = RefResolver.from_schema(schema)
|
|
26
|
+
validator = Draft7Validator(schema, resolver=resolver)
|
|
27
|
+
resolved_schema = validator.schema
|
|
28
|
+
|
|
29
|
+
def resolve_refs(node: Any) -> Any:
|
|
30
|
+
if isinstance(node, dict):
|
|
31
|
+
if "$ref" in node:
|
|
32
|
+
ref = node["$ref"]
|
|
33
|
+
with resolver.resolving(ref) as resolved:
|
|
34
|
+
return resolve_refs(resolved)
|
|
35
|
+
else:
|
|
36
|
+
return {k: resolve_refs(v) for k, v in node.items()}
|
|
37
|
+
elif isinstance(node, list):
|
|
38
|
+
return [resolve_refs(item) for item in node]
|
|
39
|
+
else:
|
|
40
|
+
return node
|
|
41
|
+
|
|
42
|
+
return resolve_refs(resolved_schema) # type: ignore[no-any-return]
|