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,37 @@
|
|
|
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 autogen.oai.anthropic import AnthropicLLMConfigEntry
|
|
6
|
+
from autogen.oai.bedrock import BedrockLLMConfigEntry
|
|
7
|
+
from autogen.oai.cerebras import CerebrasLLMConfigEntry
|
|
8
|
+
from autogen.oai.client import (
|
|
9
|
+
AzureOpenAILLMConfigEntry,
|
|
10
|
+
DeepSeekLLMConfigEntry,
|
|
11
|
+
OpenAILLMConfigEntry,
|
|
12
|
+
OpenAIResponsesLLMConfigEntry,
|
|
13
|
+
OpenAIV2LLMConfigEntry,
|
|
14
|
+
)
|
|
15
|
+
from autogen.oai.cohere import CohereLLMConfigEntry
|
|
16
|
+
from autogen.oai.gemini import GeminiLLMConfigEntry
|
|
17
|
+
from autogen.oai.groq import GroqLLMConfigEntry
|
|
18
|
+
from autogen.oai.mistral import MistralLLMConfigEntry
|
|
19
|
+
from autogen.oai.ollama import OllamaLLMConfigEntry
|
|
20
|
+
from autogen.oai.together import TogetherLLMConfigEntry
|
|
21
|
+
|
|
22
|
+
ConfigEntries = (
|
|
23
|
+
AnthropicLLMConfigEntry
|
|
24
|
+
| CerebrasLLMConfigEntry
|
|
25
|
+
| BedrockLLMConfigEntry
|
|
26
|
+
| AzureOpenAILLMConfigEntry
|
|
27
|
+
| DeepSeekLLMConfigEntry
|
|
28
|
+
| OpenAILLMConfigEntry
|
|
29
|
+
| OpenAIResponsesLLMConfigEntry
|
|
30
|
+
| OpenAIV2LLMConfigEntry
|
|
31
|
+
| CohereLLMConfigEntry
|
|
32
|
+
| GeminiLLMConfigEntry
|
|
33
|
+
| GroqLLMConfigEntry
|
|
34
|
+
| MistralLLMConfigEntry
|
|
35
|
+
| OllamaLLMConfigEntry
|
|
36
|
+
| TogetherLLMConfigEntry
|
|
37
|
+
)
|
|
@@ -0,0 +1,223 @@
|
|
|
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 json
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def config_list_from_json(
|
|
14
|
+
env_or_file: str | Path,
|
|
15
|
+
file_location: str | Path | None = "",
|
|
16
|
+
filter_dict: dict[str, list[str | None] | set[str | None]] | None = None,
|
|
17
|
+
) -> list[dict[str, Any]]:
|
|
18
|
+
"""Retrieves a list of API configurations from a JSON stored in an environment variable or a file.
|
|
19
|
+
|
|
20
|
+
This function attempts to parse JSON data from the given `env_or_file` parameter. If `env_or_file` is an
|
|
21
|
+
environment variable containing JSON data, it will be used directly. Otherwise, it is assumed to be a filename,
|
|
22
|
+
and the function will attempt to read the file from the specified `file_location`.
|
|
23
|
+
|
|
24
|
+
The `filter_dict` parameter allows for filtering the configurations based on specified criteria. Each key in the
|
|
25
|
+
`filter_dict` corresponds to a field in the configuration dictionaries, and the associated value is a list or set
|
|
26
|
+
of acceptable values for that field. If a field is missing in a configuration and `None` is included in the list
|
|
27
|
+
of acceptable values for that field, the configuration will still be considered a match.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
env_or_file (str): The name of the environment variable, the filename, or the environment variable of the filename
|
|
31
|
+
that containing the JSON data.
|
|
32
|
+
file_location (str, optional): The directory path where the file is located, if `env_or_file` is a filename.
|
|
33
|
+
filter_dict (dict, optional): A dictionary specifying the filtering criteria for the configurations, with
|
|
34
|
+
keys representing field names and values being lists or sets of acceptable values for those fields.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
```python
|
|
38
|
+
# Suppose we have an environment variable 'CONFIG_JSON' with the following content:
|
|
39
|
+
# '[{"model": "gpt-3.5-turbo", "api_type": "azure"}, {"model": "gpt-4"}]'
|
|
40
|
+
|
|
41
|
+
# We can retrieve a filtered list of configurations like this:
|
|
42
|
+
filter_criteria = {"model": ["gpt-3.5-turbo"]}
|
|
43
|
+
configs = config_list_from_json("CONFIG_JSON", filter_dict=filter_criteria)
|
|
44
|
+
# The 'configs' variable will now contain only the configurations that match the filter criteria.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
List[Dict]: A list of configuration dictionaries that match the filtering criteria specified in `filter_dict`.
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
FileNotFoundError: if env_or_file is neither found as an environment variable nor a file
|
|
52
|
+
"""
|
|
53
|
+
env_str = os.environ.get(str(env_or_file))
|
|
54
|
+
|
|
55
|
+
if env_str:
|
|
56
|
+
# The environment variable exists. We should use information from it.
|
|
57
|
+
if os.path.exists(env_str): # noqa: SIM108
|
|
58
|
+
# It is a file location, and we need to load the json from the file.
|
|
59
|
+
json_str = Path(env_str).read_text()
|
|
60
|
+
else:
|
|
61
|
+
# Else, it should be a JSON string by itself.
|
|
62
|
+
json_str = env_str
|
|
63
|
+
config_list = json.loads(json_str)
|
|
64
|
+
|
|
65
|
+
else:
|
|
66
|
+
# The environment variable does not exist.
|
|
67
|
+
# So, `env_or_file` is a filename. We should use the file location.
|
|
68
|
+
config_list_path = Path(file_location) / env_or_file if file_location else Path(env_or_file)
|
|
69
|
+
|
|
70
|
+
with open(config_list_path) as json_file:
|
|
71
|
+
config_list = json.load(json_file)
|
|
72
|
+
|
|
73
|
+
return filter_config(config_list, filter_dict)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def filter_config(
|
|
77
|
+
config_list: list[dict[str, Any]],
|
|
78
|
+
filter_dict: dict[str, list[str | None] | set[str | None]] | None,
|
|
79
|
+
exclude: bool = False,
|
|
80
|
+
) -> list[dict[str, Any]]:
|
|
81
|
+
"""Filter configuration dictionaries based on specified criteria.
|
|
82
|
+
|
|
83
|
+
This function filters a list of configuration dictionaries by applying ALL criteria specified in `filter_dict`.
|
|
84
|
+
A configuration is included in the result if it satisfies every key-value constraint in the filter dictionary.
|
|
85
|
+
For each filter key, the configuration's corresponding field value must match at least one of the acceptable
|
|
86
|
+
values (OR logic within each criteria, AND logic between different criteria).
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
config_list (list of dict): A list of configuration dictionaries to be filtered.
|
|
90
|
+
|
|
91
|
+
filter_dict (dict, optional): A dictionary specifying filter criteria where:
|
|
92
|
+
- Keys are field names to check in each configuration dictionary
|
|
93
|
+
- Values are lists/sets of acceptable values for that field
|
|
94
|
+
- A configuration matches if ALL filter keys are satisfied AND for each key,
|
|
95
|
+
the config's field value matches at least one acceptable value
|
|
96
|
+
- If a filter value includes None, configurations missing that field will match
|
|
97
|
+
- If None, no filtering is applied
|
|
98
|
+
|
|
99
|
+
exclude (bool, optional): If False (default), return configurations that match the filter.
|
|
100
|
+
If True, return configurations that do NOT match the filter.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
list of dict: Filtered list of configuration dictionaries.
|
|
104
|
+
|
|
105
|
+
Matching Logic:
|
|
106
|
+
- **Between different filter keys**: AND logic (all criteria must be satisfied)
|
|
107
|
+
- **Within each filter key's values**: OR logic (any acceptable value can match)
|
|
108
|
+
- **For list-type config values**: Match if there's any intersection with acceptable values
|
|
109
|
+
- **For scalar config values**: Match if the value is in the list of acceptable values
|
|
110
|
+
- **Missing fields**: Only match if None is included in the acceptable values for that field
|
|
111
|
+
|
|
112
|
+
Examples:
|
|
113
|
+
```python
|
|
114
|
+
configs = [
|
|
115
|
+
{"model": "gpt-3.5-turbo", "api_type": "openai"},
|
|
116
|
+
{"model": "gpt-4", "api_type": "openai"},
|
|
117
|
+
{"model": "gpt-3.5-turbo", "api_type": "azure", "api_version": "2024-02-01"},
|
|
118
|
+
{"model": "gpt-4", "tags": ["premium", "latest"]},
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
# Example 1: Single criterion - matches any model in the list
|
|
122
|
+
filter_dict = {"model": ["gpt-4", "gpt-4o"]}
|
|
123
|
+
result = filter_config(configs, filter_dict)
|
|
124
|
+
# Returns: [{"model": "gpt-4", "api_type": "openai"}, {"model": "gpt-4", "tags": ["premium", "latest"]}]
|
|
125
|
+
|
|
126
|
+
# Example 2: Multiple criteria - must satisfy ALL conditions
|
|
127
|
+
filter_dict = {"model": ["gpt-3.5-turbo"], "api_type": ["azure"]}
|
|
128
|
+
result = filter_config(configs, filter_dict)
|
|
129
|
+
# Returns: [{"model": "gpt-3.5-turbo", "api_type": "azure", "api_version": "2024-02-01"}]
|
|
130
|
+
|
|
131
|
+
# Example 3: Tag filtering with list intersection
|
|
132
|
+
filter_dict = {"tags": ["premium"]}
|
|
133
|
+
result = filter_config(configs, filter_dict)
|
|
134
|
+
# Returns: [{"model": "gpt-4", "tags": ["premium", "latest"]}]
|
|
135
|
+
|
|
136
|
+
# Example 4: Exclude matching configurations
|
|
137
|
+
filter_dict = {"api_type": ["openai"]}
|
|
138
|
+
result = filter_config(configs, filter_dict, exclude=True)
|
|
139
|
+
# Returns configs that do NOT have api_type="openai"
|
|
140
|
+
```
|
|
141
|
+
Note:
|
|
142
|
+
- If `filter_dict` is empty or None, no filtering is applied and `config_list` is returned as is.
|
|
143
|
+
- If a configuration dictionary in `config_list` does not contain a key specified in `filter_dict`,
|
|
144
|
+
it is considered a non-match and is excluded from the result.
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
if filter_dict:
|
|
148
|
+
return [
|
|
149
|
+
item
|
|
150
|
+
for item in config_list
|
|
151
|
+
if all(_satisfies_criteria(item.get(key), values) != exclude for key, values in filter_dict.items())
|
|
152
|
+
]
|
|
153
|
+
|
|
154
|
+
return config_list
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _satisfies_criteria(config_value: Any, criteria_values: Any) -> bool:
|
|
158
|
+
"""Check if a configuration field value satisfies the filter criteria.
|
|
159
|
+
|
|
160
|
+
This helper function implements the matching logic between a single configuration
|
|
161
|
+
field value and the acceptable values specified in the filter criteria. It handles
|
|
162
|
+
both scalar and list-type configuration values with appropriate matching strategies.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
config_value (Any): The value from a configuration dictionary field.
|
|
166
|
+
Can be None, a scalar value, or a list of values.
|
|
167
|
+
criteria_values (Any): The acceptable values from the filter dictionary.
|
|
168
|
+
Can be a single value or a list/set of acceptable values.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
bool: True if the config_value satisfies the criteria, False otherwise.
|
|
172
|
+
|
|
173
|
+
Matching Logic:
|
|
174
|
+
- **None config values**: Always return False (missing fields don't match)
|
|
175
|
+
- **List config values**:
|
|
176
|
+
- If criteria is a list: Match if there's any intersection (set overlap)
|
|
177
|
+
- If criteria is scalar: Match if the scalar is contained in the config list
|
|
178
|
+
- **Scalar config values**:
|
|
179
|
+
- If criteria is a list: Match if the config value is in the criteria list
|
|
180
|
+
- If criteria is scalar: Match if the values are exactly equal
|
|
181
|
+
|
|
182
|
+
Examples:
|
|
183
|
+
```python
|
|
184
|
+
# List config value with list criteria (intersection matching)
|
|
185
|
+
_satisfies_criteria(["gpt-4", "gpt-3.5"], ["gpt-4", "claude"]) # True (gpt-4 intersects)
|
|
186
|
+
_satisfies_criteria(["tag1", "tag2"], ["tag3", "tag4"]) # False (no intersection)
|
|
187
|
+
|
|
188
|
+
# List config value with scalar criteria (containment matching)
|
|
189
|
+
_satisfies_criteria(["premium", "latest"], "premium") # True (premium is in list)
|
|
190
|
+
_satisfies_criteria(["tag1", "tag2"], "tag3") # False (tag3 not in list)
|
|
191
|
+
|
|
192
|
+
# Scalar config value with list criteria (membership matching)
|
|
193
|
+
_satisfies_criteria("gpt-4", ["gpt-4", "gpt-3.5"]) # True (gpt-4 in criteria)
|
|
194
|
+
_satisfies_criteria("claude", ["gpt-4", "gpt-3.5"]) # False (claude not in criteria)
|
|
195
|
+
|
|
196
|
+
# Scalar config value with scalar criteria (equality matching)
|
|
197
|
+
_satisfies_criteria("openai", "openai") # True (exact match)
|
|
198
|
+
_satisfies_criteria("openai", "azure") # False (different values)
|
|
199
|
+
|
|
200
|
+
# None config values (missing fields)
|
|
201
|
+
_satisfies_criteria(None, ["gpt-4"]) # False (missing field)
|
|
202
|
+
_satisfies_criteria(None, "gpt-4") # False (missing field)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Note:
|
|
206
|
+
This is an internal helper function used by `filter_config()`. The function
|
|
207
|
+
assumes that both parameters can be of various types and handles type
|
|
208
|
+
checking internally to determine the appropriate matching strategy.
|
|
209
|
+
"""
|
|
210
|
+
if config_value is None:
|
|
211
|
+
return False
|
|
212
|
+
|
|
213
|
+
if isinstance(config_value, list):
|
|
214
|
+
if isinstance(criteria_values, list):
|
|
215
|
+
return bool(set(config_value) & set(criteria_values)) # Non-empty intersection
|
|
216
|
+
else:
|
|
217
|
+
return criteria_values in config_value
|
|
218
|
+
else:
|
|
219
|
+
# In filter_dict, filter could be either a list of values or a single value.
|
|
220
|
+
# For example, filter_dict = {"model": ["gpt-3.5-turbo"]} or {"model": "gpt-3.5-turbo"}
|
|
221
|
+
if isinstance(criteria_values, list):
|
|
222
|
+
return config_value in criteria_values
|
|
223
|
+
return bool(config_value == criteria_values)
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
from .file_logger import FileLogger
|
|
8
|
+
from .logger_factory import LoggerFactory
|
|
9
|
+
from .sqlite_logger import SqliteLogger
|
|
10
|
+
|
|
11
|
+
__all__ = ("FileLogger", "LoggerFactory", "SqliteLogger")
|
|
@@ -0,0 +1,129 @@
|
|
|
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
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sqlite3
|
|
10
|
+
import uuid
|
|
11
|
+
from abc import ABC, abstractmethod
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from openai import AzureOpenAI, OpenAI
|
|
17
|
+
from openai.types.chat import ChatCompletion
|
|
18
|
+
|
|
19
|
+
from .. import Agent, ConversableAgent, OpenAIWrapper
|
|
20
|
+
|
|
21
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
22
|
+
ConfigItem = dict[str, str | list[str]]
|
|
23
|
+
LLMConfig = dict[str, None | float | int | ConfigItem | list[ConfigItem]]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BaseLogger(ABC):
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def start(self) -> str:
|
|
29
|
+
"""Open a connection to the logging database, and start recording.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
session_id (str): a unique id for the logging session
|
|
33
|
+
"""
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def log_chat_completion(
|
|
38
|
+
self,
|
|
39
|
+
invocation_id: uuid.UUID,
|
|
40
|
+
client_id: int,
|
|
41
|
+
wrapper_id: int,
|
|
42
|
+
source: str | Agent,
|
|
43
|
+
request: dict[str, float | str | list[dict[str, str]]],
|
|
44
|
+
response: str | ChatCompletion,
|
|
45
|
+
is_cached: int,
|
|
46
|
+
cost: float,
|
|
47
|
+
start_time: str,
|
|
48
|
+
) -> None:
|
|
49
|
+
"""Log a chat completion to database.
|
|
50
|
+
|
|
51
|
+
In AG2, chat completions are somewhat complicated because they are handled by the `autogen.oai.OpenAIWrapper` class.
|
|
52
|
+
One invocation to `create` can lead to multiple underlying OpenAI calls, depending on the llm_config list used, and
|
|
53
|
+
any errors or retries.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
invocation_id (uuid): A unique identifier for the invocation to the OpenAIWrapper.create method call
|
|
57
|
+
client_id (int): A unique identifier for the underlying OpenAI client instance
|
|
58
|
+
wrapper_id (int): A unique identifier for the OpenAIWrapper instance
|
|
59
|
+
source (str or Agent): The source/creator of the event as a string name or an Agent instance
|
|
60
|
+
request (dict): A dictionary representing the request or call to the OpenAI client endpoint
|
|
61
|
+
response (str or ChatCompletion): The response from OpenAI
|
|
62
|
+
is_cached (int): 1 if the response was a cache hit, 0 otherwise
|
|
63
|
+
cost(float): The cost for OpenAI response
|
|
64
|
+
start_time (str): A string representing the moment the request was initiated
|
|
65
|
+
"""
|
|
66
|
+
...
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def log_new_agent(self, agent: ConversableAgent, init_args: dict[str, Any]) -> None:
|
|
70
|
+
"""Log the birth of a new agent.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
agent (ConversableAgent): The agent to log.
|
|
74
|
+
init_args (dict): The arguments passed to the construct the conversable agent
|
|
75
|
+
"""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
@abstractmethod
|
|
79
|
+
def log_event(self, source: str | Agent, name: str, **kwargs: dict[str, Any]) -> None:
|
|
80
|
+
"""Log an event for an agent.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
source (str or Agent): The source/creator of the event as a string name or an Agent instance
|
|
84
|
+
name (str): The name of the event
|
|
85
|
+
kwargs (dict): The event information to log
|
|
86
|
+
"""
|
|
87
|
+
...
|
|
88
|
+
|
|
89
|
+
@abstractmethod
|
|
90
|
+
def log_new_wrapper(self, wrapper: OpenAIWrapper, init_args: dict[str, LLMConfig | list[LLMConfig]]) -> None:
|
|
91
|
+
"""Log the birth of a new OpenAIWrapper.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
wrapper (OpenAIWrapper): The wrapper to log.
|
|
95
|
+
init_args (dict): The arguments passed to the construct the wrapper
|
|
96
|
+
"""
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
@abstractmethod
|
|
100
|
+
def log_new_client(self, client: AzureOpenAI | OpenAI, wrapper: OpenAIWrapper, init_args: dict[str, Any]) -> None:
|
|
101
|
+
"""Log the birth of a new OpenAIWrapper.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
client: The client to log.
|
|
105
|
+
wrapper: The wrapper that created the client.
|
|
106
|
+
init_args: The arguments passed to the construct the client.
|
|
107
|
+
"""
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
@abstractmethod
|
|
111
|
+
def log_function_use(self, source: str | Agent, function: F, args: dict[str, Any], returns: Any) -> None:
|
|
112
|
+
"""Log the use of a registered function (could be a tool)
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
source (str or Agent): The source/creator of the event as a string name or an Agent instance
|
|
116
|
+
function (F): The function information
|
|
117
|
+
args (dict): The function args to log
|
|
118
|
+
returns (any): The return
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
@abstractmethod
|
|
122
|
+
def stop(self) -> None:
|
|
123
|
+
"""Close the connection to the logging database, and stop logging."""
|
|
124
|
+
...
|
|
125
|
+
|
|
126
|
+
@abstractmethod
|
|
127
|
+
def get_connection(self) -> None | sqlite3.Connection:
|
|
128
|
+
"""Return a connection to the logging database."""
|
|
129
|
+
...
|
|
@@ -0,0 +1,262 @@
|
|
|
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
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
import os
|
|
12
|
+
import threading
|
|
13
|
+
import uuid
|
|
14
|
+
from collections.abc import Callable
|
|
15
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
16
|
+
|
|
17
|
+
from ..doc_utils import export_module
|
|
18
|
+
from .base_logger import BaseLogger, LLMConfig
|
|
19
|
+
from .logger_utils import get_current_ts, to_dict
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from openai import AzureOpenAI, OpenAI
|
|
23
|
+
from openai.types.chat import ChatCompletion
|
|
24
|
+
|
|
25
|
+
from .. import Agent, ConversableAgent, OpenAIWrapper
|
|
26
|
+
from ..oai.anthropic import AnthropicClient
|
|
27
|
+
from ..oai.bedrock import BedrockClient
|
|
28
|
+
from ..oai.cerebras import CerebrasClient
|
|
29
|
+
from ..oai.cohere import CohereClient
|
|
30
|
+
from ..oai.gemini import GeminiClient
|
|
31
|
+
from ..oai.groq import GroqClient
|
|
32
|
+
from ..oai.mistral import MistralAIClient
|
|
33
|
+
from ..oai.ollama import OllamaClient
|
|
34
|
+
from ..oai.together import TogetherClient
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
39
|
+
|
|
40
|
+
__all__ = ("FileLogger",)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def safe_serialize(obj: Any) -> str:
|
|
44
|
+
def default(o: Any) -> str:
|
|
45
|
+
if hasattr(o, "to_json"):
|
|
46
|
+
return str(o.to_json())
|
|
47
|
+
else:
|
|
48
|
+
return f"<<non-serializable: {type(o).__qualname__}>>"
|
|
49
|
+
|
|
50
|
+
return json.dumps(obj, default=default)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@export_module("autogen.logger")
|
|
54
|
+
class FileLogger(BaseLogger):
|
|
55
|
+
def __init__(self, config: dict[str, Any]):
|
|
56
|
+
self.config = config
|
|
57
|
+
self.session_id = str(uuid.uuid4())
|
|
58
|
+
|
|
59
|
+
curr_dir = os.getcwd()
|
|
60
|
+
self.log_dir = os.path.join(curr_dir, "autogen_logs")
|
|
61
|
+
os.makedirs(self.log_dir, exist_ok=True)
|
|
62
|
+
|
|
63
|
+
self.log_file = os.path.join(self.log_dir, self.config.get("filename", "runtime.log"))
|
|
64
|
+
try:
|
|
65
|
+
with open(self.log_file, "a"):
|
|
66
|
+
pass
|
|
67
|
+
except Exception as e:
|
|
68
|
+
logger.error(f"[file_logger] Failed to create logging file: {e}")
|
|
69
|
+
|
|
70
|
+
self.logger = logging.getLogger(__name__)
|
|
71
|
+
self.logger.setLevel(logging.INFO)
|
|
72
|
+
file_handler = logging.FileHandler(self.log_file)
|
|
73
|
+
self.logger.addHandler(file_handler)
|
|
74
|
+
|
|
75
|
+
def start(self) -> str:
|
|
76
|
+
"""Start the logger and return the session_id."""
|
|
77
|
+
try:
|
|
78
|
+
self.logger.info(f"Started new session with Session ID: {self.session_id}")
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"[file_logger] Failed to create logging file: {e}")
|
|
81
|
+
finally:
|
|
82
|
+
return self.session_id
|
|
83
|
+
|
|
84
|
+
def log_chat_completion(
|
|
85
|
+
self,
|
|
86
|
+
invocation_id: uuid.UUID,
|
|
87
|
+
client_id: int,
|
|
88
|
+
wrapper_id: int,
|
|
89
|
+
source: str | Agent,
|
|
90
|
+
request: dict[str, float | str | list[dict[str, str]]],
|
|
91
|
+
response: str | ChatCompletion,
|
|
92
|
+
is_cached: int,
|
|
93
|
+
cost: float,
|
|
94
|
+
start_time: str,
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Log a chat completion."""
|
|
97
|
+
thread_id = threading.get_ident()
|
|
98
|
+
source_name = (
|
|
99
|
+
source
|
|
100
|
+
if isinstance(source, str)
|
|
101
|
+
else source.name
|
|
102
|
+
if hasattr(source, "name") and source.name is not None
|
|
103
|
+
else ""
|
|
104
|
+
)
|
|
105
|
+
try:
|
|
106
|
+
log_data = json.dumps({
|
|
107
|
+
"invocation_id": str(invocation_id),
|
|
108
|
+
"client_id": client_id,
|
|
109
|
+
"wrapper_id": wrapper_id,
|
|
110
|
+
"request": to_dict(request),
|
|
111
|
+
"response": str(response),
|
|
112
|
+
"is_cached": is_cached,
|
|
113
|
+
"cost": cost,
|
|
114
|
+
"start_time": start_time,
|
|
115
|
+
"end_time": get_current_ts(),
|
|
116
|
+
"thread_id": thread_id,
|
|
117
|
+
"source_name": source_name,
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
self.logger.info(log_data)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
self.logger.error(f"[file_logger] Failed to log chat completion: {e}")
|
|
123
|
+
|
|
124
|
+
def log_new_agent(self, agent: ConversableAgent, init_args: dict[str, Any] = {}) -> None:
|
|
125
|
+
"""Log a new agent instance."""
|
|
126
|
+
thread_id = threading.get_ident()
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
log_data = json.dumps({
|
|
130
|
+
"id": id(agent),
|
|
131
|
+
"agent_name": agent.name if hasattr(agent, "name") and agent.name is not None else "",
|
|
132
|
+
"wrapper_id": to_dict(
|
|
133
|
+
agent.client.wrapper_id if hasattr(agent, "client") and agent.client is not None else ""
|
|
134
|
+
),
|
|
135
|
+
"session_id": self.session_id,
|
|
136
|
+
"current_time": get_current_ts(),
|
|
137
|
+
"agent_type": type(agent).__name__,
|
|
138
|
+
"args": to_dict(init_args),
|
|
139
|
+
"thread_id": thread_id,
|
|
140
|
+
})
|
|
141
|
+
self.logger.info(log_data)
|
|
142
|
+
except Exception as e:
|
|
143
|
+
self.logger.error(f"[file_logger] Failed to log new agent: {e}")
|
|
144
|
+
|
|
145
|
+
def log_event(self, source: str | Agent, name: str, **kwargs: dict[str, Any]) -> None:
|
|
146
|
+
"""Log an event from an agent or a string source."""
|
|
147
|
+
from .. import Agent
|
|
148
|
+
|
|
149
|
+
# This takes an object o as input and returns a string. If the object o cannot be serialized, instead of raising an error,
|
|
150
|
+
# it returns a string indicating that the object is non-serializable, along with its type's qualified name obtained using __qualname__.
|
|
151
|
+
json_args = json.dumps(kwargs, default=lambda o: f"<<non-serializable: {type(o).__qualname__}>>")
|
|
152
|
+
thread_id = threading.get_ident()
|
|
153
|
+
|
|
154
|
+
if isinstance(source, Agent):
|
|
155
|
+
try:
|
|
156
|
+
log_data = json.dumps({
|
|
157
|
+
"source_id": id(source),
|
|
158
|
+
"source_name": str(source.name) if hasattr(source, "name") else source,
|
|
159
|
+
"event_name": name,
|
|
160
|
+
"agent_module": source.__module__,
|
|
161
|
+
"agent_class": source.__class__.__name__,
|
|
162
|
+
"json_state": json_args,
|
|
163
|
+
"timestamp": get_current_ts(),
|
|
164
|
+
"thread_id": thread_id,
|
|
165
|
+
})
|
|
166
|
+
self.logger.info(log_data)
|
|
167
|
+
except Exception as e:
|
|
168
|
+
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
169
|
+
else:
|
|
170
|
+
try:
|
|
171
|
+
log_data = json.dumps({
|
|
172
|
+
"source_id": id(source),
|
|
173
|
+
"source_name": str(source.name) if hasattr(source, "name") else source,
|
|
174
|
+
"event_name": name,
|
|
175
|
+
"json_state": json_args,
|
|
176
|
+
"timestamp": get_current_ts(),
|
|
177
|
+
"thread_id": thread_id,
|
|
178
|
+
})
|
|
179
|
+
self.logger.info(log_data)
|
|
180
|
+
except Exception as e:
|
|
181
|
+
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
182
|
+
|
|
183
|
+
def log_new_wrapper(self, wrapper: OpenAIWrapper, init_args: dict[str, LLMConfig | list[LLMConfig]] = {}) -> None:
|
|
184
|
+
"""Log a new wrapper instance."""
|
|
185
|
+
thread_id = threading.get_ident()
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
log_data = json.dumps({
|
|
189
|
+
"wrapper_id": id(wrapper),
|
|
190
|
+
"session_id": self.session_id,
|
|
191
|
+
"json_state": json.dumps(init_args),
|
|
192
|
+
"timestamp": get_current_ts(),
|
|
193
|
+
"thread_id": thread_id,
|
|
194
|
+
})
|
|
195
|
+
self.logger.info(log_data)
|
|
196
|
+
except Exception as e:
|
|
197
|
+
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
198
|
+
|
|
199
|
+
def log_new_client(
|
|
200
|
+
self,
|
|
201
|
+
client: (
|
|
202
|
+
AzureOpenAI
|
|
203
|
+
| OpenAI
|
|
204
|
+
| CerebrasClient
|
|
205
|
+
| GeminiClient
|
|
206
|
+
| AnthropicClient
|
|
207
|
+
| MistralAIClient
|
|
208
|
+
| TogetherClient
|
|
209
|
+
| GroqClient
|
|
210
|
+
| CohereClient
|
|
211
|
+
| OllamaClient
|
|
212
|
+
| BedrockClient
|
|
213
|
+
),
|
|
214
|
+
wrapper: OpenAIWrapper,
|
|
215
|
+
init_args: dict[str, Any],
|
|
216
|
+
) -> None:
|
|
217
|
+
"""Log a new client instance."""
|
|
218
|
+
thread_id = threading.get_ident()
|
|
219
|
+
|
|
220
|
+
try:
|
|
221
|
+
log_data = json.dumps({
|
|
222
|
+
"client_id": id(client),
|
|
223
|
+
"wrapper_id": id(wrapper),
|
|
224
|
+
"session_id": self.session_id,
|
|
225
|
+
"class": type(client).__name__,
|
|
226
|
+
"json_state": json.dumps(init_args),
|
|
227
|
+
"timestamp": get_current_ts(),
|
|
228
|
+
"thread_id": thread_id,
|
|
229
|
+
})
|
|
230
|
+
self.logger.info(log_data)
|
|
231
|
+
except Exception as e:
|
|
232
|
+
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
233
|
+
|
|
234
|
+
def log_function_use(self, source: str | Agent, function: F, args: dict[str, Any], returns: Any) -> None:
|
|
235
|
+
"""Log a registered function(can be a tool) use from an agent or a string source."""
|
|
236
|
+
thread_id = threading.get_ident()
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
log_data = json.dumps({
|
|
240
|
+
"source_id": id(source),
|
|
241
|
+
"source_name": str(source.name) if hasattr(source, "name") else source,
|
|
242
|
+
"agent_module": source.__module__,
|
|
243
|
+
"agent_class": source.__class__.__name__,
|
|
244
|
+
"timestamp": get_current_ts(),
|
|
245
|
+
"thread_id": thread_id,
|
|
246
|
+
"input_args": safe_serialize(args),
|
|
247
|
+
"returns": safe_serialize(returns),
|
|
248
|
+
})
|
|
249
|
+
self.logger.info(log_data)
|
|
250
|
+
except Exception as e:
|
|
251
|
+
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
252
|
+
|
|
253
|
+
def get_connection(self) -> None:
|
|
254
|
+
"""Method is intentionally left blank because there is no specific connection needed for the FileLogger."""
|
|
255
|
+
pass
|
|
256
|
+
|
|
257
|
+
def stop(self) -> None:
|
|
258
|
+
"""Close the file handler and remove it from the logger."""
|
|
259
|
+
for handler in self.logger.handlers:
|
|
260
|
+
if isinstance(handler, logging.FileHandler):
|
|
261
|
+
handler.close()
|
|
262
|
+
self.logger.removeHandler(handler)
|