ag2 0.9.7__py3-none-any.whl → 0.9.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ag2 might be problematic. Click here for more details.
- {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/METADATA +102 -75
- ag2-0.9.9.dist-info/RECORD +387 -0
- autogen/__init__.py +1 -2
- autogen/_website/generate_api_references.py +4 -5
- autogen/_website/generate_mkdocs.py +9 -15
- autogen/_website/notebook_processor.py +13 -14
- autogen/_website/process_notebooks.py +10 -10
- autogen/_website/utils.py +5 -4
- autogen/agentchat/agent.py +13 -13
- autogen/agentchat/assistant_agent.py +7 -6
- autogen/agentchat/contrib/agent_eval/agent_eval.py +3 -3
- autogen/agentchat/contrib/agent_eval/critic_agent.py +3 -3
- autogen/agentchat/contrib/agent_eval/quantifier_agent.py +3 -3
- autogen/agentchat/contrib/agent_eval/subcritic_agent.py +3 -3
- autogen/agentchat/contrib/agent_optimizer.py +3 -3
- autogen/agentchat/contrib/capabilities/generate_images.py +11 -11
- autogen/agentchat/contrib/capabilities/teachability.py +15 -15
- autogen/agentchat/contrib/capabilities/transforms.py +17 -18
- autogen/agentchat/contrib/capabilities/transforms_util.py +5 -5
- autogen/agentchat/contrib/capabilities/vision_capability.py +4 -3
- autogen/agentchat/contrib/captainagent/agent_builder.py +30 -30
- autogen/agentchat/contrib/captainagent/captainagent.py +22 -21
- autogen/agentchat/contrib/captainagent/tool_retriever.py +2 -3
- autogen/agentchat/contrib/gpt_assistant_agent.py +9 -9
- autogen/agentchat/contrib/graph_rag/document.py +3 -3
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +3 -3
- autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +6 -6
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +3 -3
- autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +5 -11
- autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +6 -6
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +7 -7
- autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +6 -6
- autogen/agentchat/contrib/img_utils.py +1 -1
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +11 -11
- autogen/agentchat/contrib/llava_agent.py +18 -4
- autogen/agentchat/contrib/math_user_proxy_agent.py +11 -11
- autogen/agentchat/contrib/multimodal_conversable_agent.py +8 -8
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +6 -5
- autogen/agentchat/contrib/rag/chromadb_query_engine.py +22 -26
- autogen/agentchat/contrib/rag/llamaindex_query_engine.py +14 -17
- autogen/agentchat/contrib/rag/mongodb_query_engine.py +27 -37
- autogen/agentchat/contrib/rag/query_engine.py +7 -5
- autogen/agentchat/contrib/retrieve_assistant_agent.py +5 -5
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +8 -7
- autogen/agentchat/contrib/society_of_mind_agent.py +15 -14
- autogen/agentchat/contrib/swarm_agent.py +76 -98
- autogen/agentchat/contrib/text_analyzer_agent.py +7 -7
- autogen/agentchat/contrib/vectordb/base.py +10 -18
- autogen/agentchat/contrib/vectordb/chromadb.py +2 -1
- autogen/agentchat/contrib/vectordb/couchbase.py +18 -20
- autogen/agentchat/contrib/vectordb/mongodb.py +6 -5
- autogen/agentchat/contrib/vectordb/pgvectordb.py +40 -41
- autogen/agentchat/contrib/vectordb/qdrant.py +5 -5
- autogen/agentchat/contrib/web_surfer.py +20 -19
- autogen/agentchat/conversable_agent.py +292 -290
- autogen/agentchat/group/context_str.py +1 -3
- autogen/agentchat/group/context_variables.py +15 -25
- autogen/agentchat/group/group_tool_executor.py +10 -10
- autogen/agentchat/group/group_utils.py +15 -15
- autogen/agentchat/group/guardrails.py +7 -7
- autogen/agentchat/group/handoffs.py +19 -36
- autogen/agentchat/group/multi_agent_chat.py +7 -7
- autogen/agentchat/group/on_condition.py +4 -7
- autogen/agentchat/group/on_context_condition.py +4 -7
- autogen/agentchat/group/patterns/auto.py +8 -7
- autogen/agentchat/group/patterns/manual.py +7 -6
- autogen/agentchat/group/patterns/pattern.py +13 -12
- autogen/agentchat/group/patterns/random.py +3 -3
- autogen/agentchat/group/patterns/round_robin.py +3 -3
- autogen/agentchat/group/reply_result.py +2 -4
- autogen/agentchat/group/speaker_selection_result.py +5 -5
- autogen/agentchat/group/targets/group_chat_target.py +7 -6
- autogen/agentchat/group/targets/group_manager_target.py +4 -4
- autogen/agentchat/group/targets/transition_target.py +2 -1
- autogen/agentchat/groupchat.py +60 -63
- autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +4 -4
- autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +4 -4
- autogen/agentchat/realtime/experimental/clients/gemini/client.py +7 -7
- autogen/agentchat/realtime/experimental/clients/oai/base_client.py +8 -8
- autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +6 -6
- autogen/agentchat/realtime/experimental/clients/realtime_client.py +10 -9
- autogen/agentchat/realtime/experimental/realtime_agent.py +10 -9
- autogen/agentchat/realtime/experimental/realtime_observer.py +3 -3
- autogen/agentchat/realtime/experimental/realtime_swarm.py +44 -44
- autogen/agentchat/user_proxy_agent.py +10 -9
- autogen/agentchat/utils.py +3 -3
- autogen/agents/contrib/time/time_reply_agent.py +6 -5
- autogen/agents/contrib/time/time_tool_agent.py +2 -1
- autogen/agents/experimental/deep_research/deep_research.py +3 -3
- autogen/agents/experimental/discord/discord.py +2 -2
- autogen/agents/experimental/document_agent/chroma_query_engine.py +29 -44
- autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +9 -14
- autogen/agents/experimental/document_agent/document_agent.py +15 -16
- autogen/agents/experimental/document_agent/document_conditions.py +3 -3
- autogen/agents/experimental/document_agent/document_utils.py +5 -9
- autogen/agents/experimental/document_agent/inmemory_query_engine.py +14 -20
- autogen/agents/experimental/document_agent/parser_utils.py +4 -4
- autogen/agents/experimental/document_agent/url_utils.py +14 -23
- autogen/agents/experimental/reasoning/reasoning_agent.py +33 -33
- autogen/agents/experimental/slack/slack.py +2 -2
- autogen/agents/experimental/telegram/telegram.py +2 -3
- autogen/agents/experimental/websurfer/websurfer.py +4 -4
- autogen/agents/experimental/wikipedia/wikipedia.py +5 -7
- autogen/browser_utils.py +8 -8
- autogen/cache/abstract_cache_base.py +5 -5
- autogen/cache/cache.py +12 -12
- autogen/cache/cache_factory.py +4 -4
- autogen/cache/cosmos_db_cache.py +9 -9
- autogen/cache/disk_cache.py +6 -6
- autogen/cache/in_memory_cache.py +4 -4
- autogen/cache/redis_cache.py +4 -4
- autogen/code_utils.py +18 -18
- autogen/coding/base.py +6 -6
- autogen/coding/docker_commandline_code_executor.py +9 -9
- autogen/coding/func_with_reqs.py +7 -6
- autogen/coding/jupyter/base.py +3 -3
- autogen/coding/jupyter/docker_jupyter_server.py +3 -4
- autogen/coding/jupyter/import_utils.py +3 -3
- autogen/coding/jupyter/jupyter_client.py +5 -5
- autogen/coding/jupyter/jupyter_code_executor.py +3 -4
- autogen/coding/jupyter/local_jupyter_server.py +2 -6
- autogen/coding/local_commandline_code_executor.py +8 -7
- autogen/coding/markdown_code_extractor.py +1 -2
- autogen/coding/utils.py +1 -2
- autogen/doc_utils.py +3 -2
- autogen/environments/docker_python_environment.py +19 -29
- autogen/environments/python_environment.py +8 -17
- autogen/environments/system_python_environment.py +3 -4
- autogen/environments/venv_python_environment.py +8 -12
- autogen/environments/working_directory.py +1 -2
- autogen/events/agent_events.py +106 -109
- autogen/events/base_event.py +6 -5
- autogen/events/client_events.py +15 -14
- autogen/events/helpers.py +1 -1
- autogen/events/print_event.py +4 -5
- autogen/fast_depends/_compat.py +10 -15
- autogen/fast_depends/core/build.py +17 -36
- autogen/fast_depends/core/model.py +64 -113
- autogen/fast_depends/dependencies/model.py +2 -1
- autogen/fast_depends/dependencies/provider.py +3 -2
- autogen/fast_depends/library/model.py +4 -4
- autogen/fast_depends/schema.py +7 -7
- autogen/fast_depends/use.py +17 -25
- autogen/fast_depends/utils.py +10 -30
- autogen/formatting_utils.py +6 -6
- autogen/graph_utils.py +1 -4
- autogen/import_utils.py +38 -27
- autogen/interop/crewai/crewai.py +2 -2
- autogen/interop/interoperable.py +2 -2
- autogen/interop/langchain/langchain_chat_model_factory.py +3 -2
- autogen/interop/langchain/langchain_tool.py +2 -6
- autogen/interop/litellm/litellm_config_factory.py +6 -7
- autogen/interop/pydantic_ai/pydantic_ai.py +4 -7
- autogen/interop/registry.py +2 -1
- autogen/io/base.py +5 -5
- autogen/io/run_response.py +33 -32
- autogen/io/websockets.py +6 -5
- autogen/json_utils.py +1 -2
- autogen/llm_config/__init__.py +11 -0
- autogen/llm_config/client.py +58 -0
- autogen/llm_config/config.py +384 -0
- autogen/llm_config/entry.py +154 -0
- autogen/logger/base_logger.py +4 -3
- autogen/logger/file_logger.py +2 -1
- autogen/logger/logger_factory.py +2 -2
- autogen/logger/logger_utils.py +2 -2
- autogen/logger/sqlite_logger.py +2 -1
- autogen/math_utils.py +4 -5
- autogen/mcp/__main__.py +6 -6
- autogen/mcp/helpers.py +4 -4
- autogen/mcp/mcp_client.py +170 -29
- autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +3 -4
- autogen/mcp/mcp_proxy/mcp_proxy.py +23 -26
- autogen/mcp/mcp_proxy/operation_grouping.py +4 -5
- autogen/mcp/mcp_proxy/operation_renaming.py +6 -10
- autogen/mcp/mcp_proxy/security.py +2 -3
- autogen/messages/agent_messages.py +96 -98
- autogen/messages/base_message.py +6 -5
- autogen/messages/client_messages.py +15 -14
- autogen/messages/print_message.py +4 -5
- autogen/oai/__init__.py +1 -2
- autogen/oai/anthropic.py +42 -41
- autogen/oai/bedrock.py +68 -57
- autogen/oai/cerebras.py +26 -25
- autogen/oai/client.py +113 -139
- autogen/oai/client_utils.py +3 -3
- autogen/oai/cohere.py +34 -11
- autogen/oai/gemini.py +39 -17
- autogen/oai/gemini_types.py +11 -12
- autogen/oai/groq.py +22 -10
- autogen/oai/mistral.py +17 -11
- autogen/oai/oai_models/__init__.py +14 -2
- autogen/oai/oai_models/_models.py +2 -2
- autogen/oai/oai_models/chat_completion.py +13 -14
- autogen/oai/oai_models/chat_completion_message.py +11 -9
- autogen/oai/oai_models/chat_completion_message_tool_call.py +26 -3
- autogen/oai/oai_models/chat_completion_token_logprob.py +3 -4
- autogen/oai/oai_models/completion_usage.py +8 -9
- autogen/oai/ollama.py +19 -9
- autogen/oai/openai_responses.py +40 -17
- autogen/oai/openai_utils.py +48 -38
- autogen/oai/together.py +29 -14
- autogen/retrieve_utils.py +6 -7
- autogen/runtime_logging.py +5 -4
- autogen/token_count_utils.py +7 -4
- autogen/tools/contrib/time/time.py +0 -1
- autogen/tools/dependency_injection.py +5 -6
- autogen/tools/experimental/browser_use/browser_use.py +10 -10
- autogen/tools/experimental/code_execution/python_code_execution.py +5 -7
- autogen/tools/experimental/crawl4ai/crawl4ai.py +12 -15
- autogen/tools/experimental/deep_research/deep_research.py +9 -8
- autogen/tools/experimental/duckduckgo/duckduckgo_search.py +5 -11
- autogen/tools/experimental/firecrawl/firecrawl_tool.py +98 -115
- autogen/tools/experimental/google/authentication/credentials_local_provider.py +1 -1
- autogen/tools/experimental/google/drive/drive_functions.py +4 -4
- autogen/tools/experimental/google/drive/toolkit.py +5 -5
- autogen/tools/experimental/google_search/google_search.py +5 -5
- autogen/tools/experimental/google_search/youtube_search.py +5 -5
- autogen/tools/experimental/messageplatform/discord/discord.py +8 -12
- autogen/tools/experimental/messageplatform/slack/slack.py +14 -20
- autogen/tools/experimental/messageplatform/telegram/telegram.py +8 -12
- autogen/tools/experimental/perplexity/perplexity_search.py +18 -29
- autogen/tools/experimental/reliable/reliable.py +68 -74
- autogen/tools/experimental/searxng/searxng_search.py +20 -19
- autogen/tools/experimental/tavily/tavily_search.py +12 -19
- autogen/tools/experimental/web_search_preview/web_search_preview.py +13 -7
- autogen/tools/experimental/wikipedia/wikipedia.py +7 -10
- autogen/tools/function_utils.py +7 -7
- autogen/tools/tool.py +8 -6
- autogen/types.py +2 -2
- autogen/version.py +1 -1
- ag2-0.9.7.dist-info/RECORD +0 -421
- autogen/llm_config.py +0 -385
- {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/WHEEL +0 -0
- {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/licenses/LICENSE +0 -0
- {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,384 @@
|
|
|
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 functools
|
|
6
|
+
import json
|
|
7
|
+
import re
|
|
8
|
+
from collections.abc import Iterable
|
|
9
|
+
from contextvars import ContextVar
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Annotated, Any, Literal, TypeAlias
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
14
|
+
|
|
15
|
+
from autogen.oai.anthropic import AnthropicEntryDict, AnthropicLLMConfigEntry
|
|
16
|
+
from autogen.oai.bedrock import BedrockEntryDict, BedrockLLMConfigEntry
|
|
17
|
+
from autogen.oai.cerebras import CerebrasEntryDict, CerebrasLLMConfigEntry
|
|
18
|
+
from autogen.oai.client import (
|
|
19
|
+
AzureOpenAIEntryDict,
|
|
20
|
+
AzureOpenAILLMConfigEntry,
|
|
21
|
+
DeepSeekEntyDict,
|
|
22
|
+
DeepSeekLLMConfigEntry,
|
|
23
|
+
OpenAIEntryDict,
|
|
24
|
+
OpenAILLMConfigEntry,
|
|
25
|
+
OpenAIResponsesLLMConfigEntry,
|
|
26
|
+
)
|
|
27
|
+
from autogen.oai.cohere import CohereEntryDict, CohereLLMConfigEntry
|
|
28
|
+
from autogen.oai.gemini import GeminiEntryDict, GeminiLLMConfigEntry
|
|
29
|
+
from autogen.oai.groq import GroqEntryDict, GroqLLMConfigEntry
|
|
30
|
+
from autogen.oai.mistral import MistralEntryDict, MistralLLMConfigEntry
|
|
31
|
+
from autogen.oai.ollama import OllamaEntryDict, OllamaLLMConfigEntry
|
|
32
|
+
from autogen.oai.together import TogetherEntryDict, TogetherLLMConfigEntry
|
|
33
|
+
|
|
34
|
+
from ..doc_utils import export_module
|
|
35
|
+
from .entry import ApplicationConfig, LLMConfigEntry
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Meta class to allow LLMConfig.current and LLMConfig.default to be used as class properties
|
|
39
|
+
class MetaLLMConfig(type):
|
|
40
|
+
def __init__(cls, *args: Any, **kwargs: Any) -> None:
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def current(cls) -> "LLMConfig":
|
|
45
|
+
current_llm_config = LLMConfig.get_current_llm_config(llm_config=None)
|
|
46
|
+
if current_llm_config is None:
|
|
47
|
+
raise ValueError("No current LLMConfig set. Are you inside a context block?")
|
|
48
|
+
return current_llm_config # type: ignore[return-value]
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def default(cls) -> "LLMConfig":
|
|
52
|
+
return cls.current
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
ConfigItem: TypeAlias = (
|
|
56
|
+
LLMConfigEntry
|
|
57
|
+
| AnthropicEntryDict
|
|
58
|
+
| BedrockEntryDict
|
|
59
|
+
| CerebrasEntryDict
|
|
60
|
+
| CohereEntryDict
|
|
61
|
+
| AzureOpenAIEntryDict
|
|
62
|
+
| OpenAIEntryDict
|
|
63
|
+
| DeepSeekEntyDict
|
|
64
|
+
| MistralEntryDict
|
|
65
|
+
| GroqEntryDict
|
|
66
|
+
| OllamaEntryDict
|
|
67
|
+
| GeminiEntryDict
|
|
68
|
+
| TogetherEntryDict
|
|
69
|
+
| dict[str, Any]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@export_module("autogen")
|
|
74
|
+
class LLMConfig(metaclass=MetaLLMConfig):
|
|
75
|
+
_current_llm_config: ContextVar["LLMConfig"] = ContextVar("current_llm_config")
|
|
76
|
+
|
|
77
|
+
def __init__(
|
|
78
|
+
self,
|
|
79
|
+
*,
|
|
80
|
+
top_p: float | None = None,
|
|
81
|
+
temperature: float | None = None,
|
|
82
|
+
max_tokens: int | None = None,
|
|
83
|
+
config_list: Iterable[ConfigItem] | dict[str, Any] = (),
|
|
84
|
+
check_every_ms: int | None = None,
|
|
85
|
+
allow_format_str_template: bool | None = None,
|
|
86
|
+
response_format: str | dict[str, Any] | BaseModel | type[BaseModel] | None = None,
|
|
87
|
+
timeout: int | None = None,
|
|
88
|
+
seed: int | None = None,
|
|
89
|
+
cache_seed: int | None = None,
|
|
90
|
+
parallel_tool_calls: bool | None = None,
|
|
91
|
+
tools: Iterable[Any] = (),
|
|
92
|
+
functions: Iterable[Any] = (),
|
|
93
|
+
routing_method: Literal["fixed_order", "round_robin"] | None = None,
|
|
94
|
+
**kwargs: Any,
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Initializes the LLMConfig object.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
config_list: A list of LLM configuration entries or dictionaries.
|
|
100
|
+
temperature: The sampling temperature for LLM generation.
|
|
101
|
+
check_every_ms: The interval (in milliseconds) to check for updates
|
|
102
|
+
allow_format_str_template: Whether to allow format string templates.
|
|
103
|
+
response_format: The format of the response (e.g., JSON, text).
|
|
104
|
+
timeout: The timeout for LLM requests in seconds.
|
|
105
|
+
seed: The random seed for reproducible results.
|
|
106
|
+
cache_seed: The seed for caching LLM responses.
|
|
107
|
+
parallel_tool_calls: Whether to enable parallel tool calls.
|
|
108
|
+
tools: A list of tools available for the LLM.
|
|
109
|
+
functions: A list of functions available for the LLM.
|
|
110
|
+
max_tokens: The maximum number of tokens to generate.
|
|
111
|
+
top_p: The nucleus sampling probability.
|
|
112
|
+
routing_method: The method used to route requests (e.g., fixed_order, round_robin).
|
|
113
|
+
**kwargs: Additional keyword arguments for future extensions.
|
|
114
|
+
|
|
115
|
+
Examples:
|
|
116
|
+
```python
|
|
117
|
+
# Example 1: create config from `kwargs` options
|
|
118
|
+
config = LLMConfig(
|
|
119
|
+
model="gpt-4o-mini",
|
|
120
|
+
api_key=os.environ["OPENAI_API_KEY"],
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Example 2: create config from `config_list` dictionary
|
|
124
|
+
config = LLMConfig(
|
|
125
|
+
config_list={
|
|
126
|
+
"model": "gpt-4o-mini",
|
|
127
|
+
"api_key": os.environ["OPENAI_API_KEY"],
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Example 3: create config from `config_list` list
|
|
132
|
+
config = LLMConfig(
|
|
133
|
+
config_list=[
|
|
134
|
+
{
|
|
135
|
+
"model": "gpt-4o-mini",
|
|
136
|
+
"api_key": os.environ["OPENAI_API_KEY"],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"model": "gpt-4",
|
|
140
|
+
"api_key": os.environ["OPENAI_API_KEY"],
|
|
141
|
+
},
|
|
142
|
+
]
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
"""
|
|
146
|
+
app_config = ApplicationConfig(
|
|
147
|
+
max_tokens=max_tokens,
|
|
148
|
+
top_p=top_p,
|
|
149
|
+
temperature=temperature,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
application_level_options = app_config.model_dump(exclude_none=True)
|
|
153
|
+
|
|
154
|
+
final_config_list: list[LLMConfigEntry | dict[str, Any]] = []
|
|
155
|
+
|
|
156
|
+
if isinstance(config_list, dict):
|
|
157
|
+
config_list = [config_list]
|
|
158
|
+
|
|
159
|
+
for c in filter(bool, (*config_list, kwargs)):
|
|
160
|
+
if isinstance(c, LLMConfigEntry):
|
|
161
|
+
final_config_list.append(c.apply_application_config(app_config))
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
else:
|
|
165
|
+
final_config_list.append({
|
|
166
|
+
"api_type": "openai", # default api_type
|
|
167
|
+
**application_level_options,
|
|
168
|
+
**c,
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
self._model = _LLMConfig(
|
|
172
|
+
**application_level_options,
|
|
173
|
+
config_list=final_config_list,
|
|
174
|
+
check_every_ms=check_every_ms,
|
|
175
|
+
seed=seed,
|
|
176
|
+
allow_format_str_template=allow_format_str_template,
|
|
177
|
+
response_format=response_format,
|
|
178
|
+
timeout=timeout,
|
|
179
|
+
cache_seed=cache_seed,
|
|
180
|
+
tools=tools or [],
|
|
181
|
+
functions=functions or [],
|
|
182
|
+
parallel_tool_calls=parallel_tool_calls,
|
|
183
|
+
routing_method=routing_method,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# used by BaseModel to create instance variables
|
|
187
|
+
def __enter__(self) -> "LLMConfig":
|
|
188
|
+
# Store previous context and set self as current
|
|
189
|
+
self._token = LLMConfig._current_llm_config.set(self)
|
|
190
|
+
return self
|
|
191
|
+
|
|
192
|
+
def __exit__(self, exc_type: type[Exception], exc_val: Exception, exc_tb: Any) -> None:
|
|
193
|
+
LLMConfig._current_llm_config.reset(self._token)
|
|
194
|
+
|
|
195
|
+
@classmethod
|
|
196
|
+
def get_current_llm_config(cls, llm_config: "LLMConfig | None" = None) -> "LLMConfig | None":
|
|
197
|
+
if llm_config is not None:
|
|
198
|
+
return llm_config
|
|
199
|
+
try:
|
|
200
|
+
return (LLMConfig._current_llm_config.get()).copy()
|
|
201
|
+
except LookupError:
|
|
202
|
+
return None
|
|
203
|
+
|
|
204
|
+
def _satisfies_criteria(self, value: Any, criteria_values: Any) -> bool:
|
|
205
|
+
if value is None:
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
if isinstance(value, list):
|
|
209
|
+
return bool(set(value) & set(criteria_values)) # Non-empty intersection
|
|
210
|
+
else:
|
|
211
|
+
return value in criteria_values
|
|
212
|
+
|
|
213
|
+
@classmethod
|
|
214
|
+
def from_json(
|
|
215
|
+
cls,
|
|
216
|
+
*,
|
|
217
|
+
env: str | None = None,
|
|
218
|
+
path: str | Path | None = None,
|
|
219
|
+
file_location: str | None = None,
|
|
220
|
+
**kwargs: Any,
|
|
221
|
+
) -> "LLMConfig":
|
|
222
|
+
from autogen.oai.openai_utils import config_list_from_json
|
|
223
|
+
|
|
224
|
+
if env is None and path is None:
|
|
225
|
+
raise ValueError("Either 'env' or 'path' must be provided")
|
|
226
|
+
if env is not None and path is not None:
|
|
227
|
+
raise ValueError("Only one of 'env' or 'path' can be provided")
|
|
228
|
+
|
|
229
|
+
config_list = config_list_from_json(
|
|
230
|
+
env_or_file=env if env is not None else str(path), file_location=file_location
|
|
231
|
+
)
|
|
232
|
+
return LLMConfig(config_list=config_list, **kwargs)
|
|
233
|
+
|
|
234
|
+
def where(self, *, exclude: bool = False, **kwargs: Any) -> "LLMConfig":
|
|
235
|
+
from autogen.oai.openai_utils import filter_config
|
|
236
|
+
|
|
237
|
+
filtered_config_list = filter_config(config_list=self.config_list, filter_dict=kwargs, exclude=exclude)
|
|
238
|
+
if len(filtered_config_list) == 0:
|
|
239
|
+
raise ValueError(f"No config found that satisfies the filter criteria: {kwargs}")
|
|
240
|
+
|
|
241
|
+
kwargs = self.model_dump()
|
|
242
|
+
kwargs["config_list"] = filtered_config_list
|
|
243
|
+
|
|
244
|
+
return LLMConfig(**kwargs)
|
|
245
|
+
|
|
246
|
+
# @functools.wraps(BaseModel.model_dump)
|
|
247
|
+
def model_dump(self, *args: Any, exclude_none: bool = True, **kwargs: Any) -> dict[str, Any]:
|
|
248
|
+
d = self._model.model_dump(*args, exclude_none=exclude_none, **kwargs)
|
|
249
|
+
return {k: v for k, v in d.items() if not (isinstance(v, list) and len(v) == 0)}
|
|
250
|
+
|
|
251
|
+
# @functools.wraps(BaseModel.model_dump_json)
|
|
252
|
+
def model_dump_json(self, *args: Any, exclude_none: bool = True, **kwargs: Any) -> str:
|
|
253
|
+
# return self._model.model_dump_json(*args, exclude_none=exclude_none, **kwargs)
|
|
254
|
+
d = self.model_dump(*args, exclude_none=exclude_none, **kwargs)
|
|
255
|
+
return json.dumps(d)
|
|
256
|
+
|
|
257
|
+
# @functools.wraps(BaseModel.model_validate)
|
|
258
|
+
def model_validate(self, *args: Any, **kwargs: Any) -> Any:
|
|
259
|
+
return self._model.model_validate(*args, **kwargs)
|
|
260
|
+
|
|
261
|
+
@functools.wraps(BaseModel.model_validate_json)
|
|
262
|
+
def model_validate_json(self, *args: Any, **kwargs: Any) -> Any:
|
|
263
|
+
return self._model.model_validate_json(*args, **kwargs)
|
|
264
|
+
|
|
265
|
+
@functools.wraps(BaseModel.model_validate_strings)
|
|
266
|
+
def model_validate_strings(self, *args: Any, **kwargs: Any) -> Any:
|
|
267
|
+
return self._model.model_validate_strings(*args, **kwargs)
|
|
268
|
+
|
|
269
|
+
def __eq__(self, value: Any) -> bool:
|
|
270
|
+
if not isinstance(value, LLMConfig):
|
|
271
|
+
return NotImplemented
|
|
272
|
+
return self._model == value._model
|
|
273
|
+
|
|
274
|
+
def _getattr(self, o: object, name: str) -> Any:
|
|
275
|
+
val = getattr(o, name)
|
|
276
|
+
return val
|
|
277
|
+
|
|
278
|
+
def get(self, key: str, default: Any | None = None) -> Any:
|
|
279
|
+
val = getattr(self._model, key, default)
|
|
280
|
+
return val
|
|
281
|
+
|
|
282
|
+
def __getitem__(self, key: str) -> Any:
|
|
283
|
+
try:
|
|
284
|
+
return self._getattr(self._model, key)
|
|
285
|
+
except AttributeError:
|
|
286
|
+
raise KeyError(f"Key '{key}' not found in {self.__class__.__name__}")
|
|
287
|
+
|
|
288
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
289
|
+
try:
|
|
290
|
+
setattr(self._model, key, value)
|
|
291
|
+
except ValueError:
|
|
292
|
+
raise ValueError(f"'{self.__class__.__name__}' object has no field '{key}'")
|
|
293
|
+
|
|
294
|
+
def __getattr__(self, name: Any) -> Any:
|
|
295
|
+
try:
|
|
296
|
+
return self._getattr(self._model, name)
|
|
297
|
+
except AttributeError:
|
|
298
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
|
|
299
|
+
|
|
300
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
301
|
+
if name == "_model":
|
|
302
|
+
object.__setattr__(self, name, value)
|
|
303
|
+
else:
|
|
304
|
+
setattr(self._model, name, value)
|
|
305
|
+
|
|
306
|
+
def __contains__(self, key: str) -> bool:
|
|
307
|
+
return hasattr(self._model, key)
|
|
308
|
+
|
|
309
|
+
def __repr__(self) -> str:
|
|
310
|
+
d = self.model_dump()
|
|
311
|
+
r = [f"{k}={repr(v)}" for k, v in d.items()]
|
|
312
|
+
|
|
313
|
+
s = f"LLMConfig({', '.join(r)})"
|
|
314
|
+
# Replace any keys ending with 'key' or 'token' values with stars for security
|
|
315
|
+
s = re.sub(
|
|
316
|
+
r"(['\"])(\w*(key|token))\1:\s*(['\"])([^'\"]*)(?:\4)", r"\1\2\1: \4**********\4", s, flags=re.IGNORECASE
|
|
317
|
+
)
|
|
318
|
+
return s
|
|
319
|
+
|
|
320
|
+
def __copy__(self) -> "LLMConfig":
|
|
321
|
+
return LLMConfig(**self.model_dump())
|
|
322
|
+
|
|
323
|
+
def __deepcopy__(self, memo: dict[int, Any] | None = None) -> "LLMConfig":
|
|
324
|
+
return self.__copy__()
|
|
325
|
+
|
|
326
|
+
def copy(self) -> "LLMConfig":
|
|
327
|
+
return self.__copy__()
|
|
328
|
+
|
|
329
|
+
def deepcopy(self, memo: dict[int, Any] | None = None) -> "LLMConfig":
|
|
330
|
+
return self.__deepcopy__(memo)
|
|
331
|
+
|
|
332
|
+
def __str__(self) -> str:
|
|
333
|
+
return repr(self)
|
|
334
|
+
|
|
335
|
+
def items(self) -> Iterable[tuple[str, Any]]:
|
|
336
|
+
d = self.model_dump()
|
|
337
|
+
return d.items()
|
|
338
|
+
|
|
339
|
+
def keys(self) -> Iterable[str]:
|
|
340
|
+
d = self.model_dump()
|
|
341
|
+
return d.keys()
|
|
342
|
+
|
|
343
|
+
def values(self) -> Iterable[Any]:
|
|
344
|
+
d = self.model_dump()
|
|
345
|
+
return d.values()
|
|
346
|
+
|
|
347
|
+
_base_model_classes: dict[tuple[type["LLMConfigEntry"], ...], type[BaseModel]] = {}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
class _LLMConfig(ApplicationConfig):
|
|
351
|
+
check_every_ms: int | None
|
|
352
|
+
seed: int | None
|
|
353
|
+
allow_format_str_template: bool | None
|
|
354
|
+
response_format: str | dict[str, Any] | BaseModel | type[BaseModel] | None
|
|
355
|
+
timeout: int | None
|
|
356
|
+
cache_seed: int | None
|
|
357
|
+
parallel_tool_calls: bool | None
|
|
358
|
+
|
|
359
|
+
tools: list[Any]
|
|
360
|
+
functions: list[Any]
|
|
361
|
+
|
|
362
|
+
config_list: list[ # type: ignore[valid-type]
|
|
363
|
+
Annotated[
|
|
364
|
+
AnthropicLLMConfigEntry
|
|
365
|
+
| CerebrasLLMConfigEntry
|
|
366
|
+
| BedrockLLMConfigEntry
|
|
367
|
+
| AzureOpenAILLMConfigEntry
|
|
368
|
+
| DeepSeekLLMConfigEntry
|
|
369
|
+
| OpenAILLMConfigEntry
|
|
370
|
+
| OpenAIResponsesLLMConfigEntry
|
|
371
|
+
| CohereLLMConfigEntry
|
|
372
|
+
| GeminiLLMConfigEntry
|
|
373
|
+
| GroqLLMConfigEntry
|
|
374
|
+
| MistralLLMConfigEntry
|
|
375
|
+
| OllamaLLMConfigEntry
|
|
376
|
+
| TogetherLLMConfigEntry,
|
|
377
|
+
Field(discriminator="api_type"),
|
|
378
|
+
],
|
|
379
|
+
] = Field(..., min_length=1)
|
|
380
|
+
|
|
381
|
+
routing_method: Literal["fixed_order", "round_robin"] | None
|
|
382
|
+
|
|
383
|
+
# Following field is configuration for pydantic to disallow extra fields
|
|
384
|
+
model_config = ConfigDict(extra="forbid")
|
|
@@ -0,0 +1,154 @@
|
|
|
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 re
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from collections.abc import Iterable, Mapping
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from httpx import Client as httpxClient
|
|
11
|
+
from pydantic import BaseModel, ConfigDict, Field, HttpUrl, SecretStr, ValidationInfo, field_serializer, field_validator
|
|
12
|
+
from typing_extensions import Required, TypedDict
|
|
13
|
+
|
|
14
|
+
from .client import ModelClient
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LLMConfigEntryDict(TypedDict, total=False):
|
|
18
|
+
api_type: Required[str]
|
|
19
|
+
model: str
|
|
20
|
+
max_tokens: int | None
|
|
21
|
+
top_p: float | None
|
|
22
|
+
temperature: float | None
|
|
23
|
+
|
|
24
|
+
api_key: SecretStr | None
|
|
25
|
+
api_version: str | None
|
|
26
|
+
base_url: HttpUrl | None
|
|
27
|
+
voice: str | None
|
|
28
|
+
http_client: httpxClient | None
|
|
29
|
+
model_client_cls: str | None
|
|
30
|
+
response_format: str | dict[str, Any] | BaseModel | type[BaseModel] | None
|
|
31
|
+
default_headers: Mapping[str, Any] | None
|
|
32
|
+
tags: list[str]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ApplicationConfig(BaseModel):
|
|
36
|
+
max_tokens: int | None = Field(default=None, ge=0)
|
|
37
|
+
top_p: float | None = Field(default=None, gt=0, lt=1)
|
|
38
|
+
temperature: float | None = Field(default=None, ge=0, le=1)
|
|
39
|
+
|
|
40
|
+
@field_validator("top_p", mode="before")
|
|
41
|
+
@classmethod
|
|
42
|
+
def check_top_p(cls, v: float | None, info: ValidationInfo) -> float | None:
|
|
43
|
+
if v is not None and info.data.get("temperature") is not None:
|
|
44
|
+
raise ValueError("temperature and top_p cannot be set at the same time.")
|
|
45
|
+
return v
|
|
46
|
+
|
|
47
|
+
@field_validator("temperature", mode="before")
|
|
48
|
+
@classmethod
|
|
49
|
+
def check_temperature(cls, v: float | None, info: ValidationInfo) -> float | None:
|
|
50
|
+
if v is not None and info.data.get("top_p") is not None:
|
|
51
|
+
raise ValueError("temperature and top_p cannot be set at the same time.")
|
|
52
|
+
return v
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class LLMConfigEntry(ApplicationConfig, ABC):
|
|
56
|
+
api_type: str
|
|
57
|
+
model: str = Field(..., min_length=1)
|
|
58
|
+
|
|
59
|
+
api_key: SecretStr | None = None
|
|
60
|
+
api_version: str | None = None
|
|
61
|
+
base_url: HttpUrl | None = None
|
|
62
|
+
voice: str | None = None
|
|
63
|
+
model_client_cls: str | None = None
|
|
64
|
+
http_client: httpxClient | None = None
|
|
65
|
+
response_format: str | dict[str, Any] | BaseModel | type[BaseModel] | None = None
|
|
66
|
+
default_headers: Mapping[str, Any] | None = None
|
|
67
|
+
tags: list[str] = Field(default_factory=list)
|
|
68
|
+
|
|
69
|
+
# Following field is configuration for pydantic to disallow extra fields
|
|
70
|
+
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
|
71
|
+
|
|
72
|
+
def apply_application_config(self, application_config: ApplicationConfig) -> "LLMConfigEntry":
|
|
73
|
+
"""Apply application level configurations."""
|
|
74
|
+
# TODO: should create a new instance instead of mutating current one
|
|
75
|
+
self.max_tokens = self.max_tokens or application_config.max_tokens
|
|
76
|
+
self.top_p = self.top_p or application_config.top_p
|
|
77
|
+
self.temperature = self.temperature or application_config.temperature
|
|
78
|
+
return self
|
|
79
|
+
|
|
80
|
+
@abstractmethod
|
|
81
|
+
def create_client(self) -> "ModelClient": ...
|
|
82
|
+
|
|
83
|
+
@field_validator("base_url", mode="before")
|
|
84
|
+
@classmethod
|
|
85
|
+
def check_base_url(cls, v: HttpUrl | str | None, info: ValidationInfo) -> str | None:
|
|
86
|
+
if v is None: # Handle None case explicitly
|
|
87
|
+
return None
|
|
88
|
+
if not str(v).startswith("https://") and not str(v).startswith("http://"):
|
|
89
|
+
return f"http://{str(v)}"
|
|
90
|
+
return str(v)
|
|
91
|
+
|
|
92
|
+
@field_serializer("base_url", when_used="unless-none") # Ensure serializer also respects None
|
|
93
|
+
def serialize_base_url(self, v: HttpUrl | None) -> str | None:
|
|
94
|
+
return str(v) if v is not None else None
|
|
95
|
+
|
|
96
|
+
@field_serializer("api_key", when_used="unless-none")
|
|
97
|
+
def serialize_api_key(self, v: SecretStr) -> str:
|
|
98
|
+
return v.get_secret_value()
|
|
99
|
+
|
|
100
|
+
def model_dump(self, *args: Any, exclude_none: bool = True, **kwargs: Any) -> dict[str, Any]:
|
|
101
|
+
return BaseModel.model_dump(self, exclude_none=exclude_none, *args, **kwargs)
|
|
102
|
+
|
|
103
|
+
def model_dump_json(self, *args: Any, exclude_none: bool = True, **kwargs: Any) -> str:
|
|
104
|
+
return BaseModel.model_dump_json(self, exclude_none=exclude_none, *args, **kwargs)
|
|
105
|
+
|
|
106
|
+
def get(self, key: str, default: Any | None = None) -> Any:
|
|
107
|
+
val = getattr(self, key, default)
|
|
108
|
+
if isinstance(val, SecretStr):
|
|
109
|
+
return val.get_secret_value()
|
|
110
|
+
return val
|
|
111
|
+
|
|
112
|
+
def __getitem__(self, key: str) -> Any:
|
|
113
|
+
try:
|
|
114
|
+
val = getattr(self, key)
|
|
115
|
+
if isinstance(val, SecretStr):
|
|
116
|
+
return val.get_secret_value()
|
|
117
|
+
return val
|
|
118
|
+
except AttributeError:
|
|
119
|
+
raise KeyError(f"Key '{key}' not found in {self.__class__.__name__}")
|
|
120
|
+
|
|
121
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
122
|
+
setattr(self, key, value)
|
|
123
|
+
|
|
124
|
+
def __contains__(self, key: str) -> bool:
|
|
125
|
+
return hasattr(self, key)
|
|
126
|
+
|
|
127
|
+
def items(self) -> Iterable[tuple[str, Any]]:
|
|
128
|
+
d = self.model_dump()
|
|
129
|
+
return d.items()
|
|
130
|
+
|
|
131
|
+
def keys(self) -> Iterable[str]:
|
|
132
|
+
d = self.model_dump()
|
|
133
|
+
return d.keys()
|
|
134
|
+
|
|
135
|
+
def values(self) -> Iterable[Any]:
|
|
136
|
+
d = self.model_dump()
|
|
137
|
+
return d.values()
|
|
138
|
+
|
|
139
|
+
def __repr__(self) -> str:
|
|
140
|
+
# Override to eliminate none values from the repr
|
|
141
|
+
d = self.model_dump()
|
|
142
|
+
r = [f"{k}={repr(v)}" for k, v in d.items()]
|
|
143
|
+
|
|
144
|
+
s = f"{self.__class__.__name__}({', '.join(r)})"
|
|
145
|
+
|
|
146
|
+
# Replace any keys ending with '_key' or '_token' values with stars for security
|
|
147
|
+
# This regex will match any key ending with '_key' or '_token' and its value, and replace the value with stars
|
|
148
|
+
# It also captures the type of quote used (single or double) and reuses it in the replacement
|
|
149
|
+
s = re.sub(r'(\w+_(key|token)\s*=\s*)([\'"]).*?\3', r"\1\3**********\3", s, flags=re.IGNORECASE)
|
|
150
|
+
|
|
151
|
+
return s
|
|
152
|
+
|
|
153
|
+
def __str__(self) -> str:
|
|
154
|
+
return repr(self)
|
autogen/logger/base_logger.py
CHANGED
|
@@ -9,7 +9,8 @@ from __future__ import annotations
|
|
|
9
9
|
import sqlite3
|
|
10
10
|
import uuid
|
|
11
11
|
from abc import ABC, abstractmethod
|
|
12
|
-
from
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from openai import AzureOpenAI, OpenAI
|
|
@@ -18,8 +19,8 @@ if TYPE_CHECKING:
|
|
|
18
19
|
from .. import Agent, ConversableAgent, OpenAIWrapper
|
|
19
20
|
|
|
20
21
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
21
|
-
ConfigItem = dict[str,
|
|
22
|
-
LLMConfig = dict[str,
|
|
22
|
+
ConfigItem = dict[str, str | list[str]]
|
|
23
|
+
LLMConfig = dict[str, None | float | int | ConfigItem | list[ConfigItem]]
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class BaseLogger(ABC):
|
autogen/logger/file_logger.py
CHANGED
|
@@ -11,7 +11,8 @@ import logging
|
|
|
11
11
|
import os
|
|
12
12
|
import threading
|
|
13
13
|
import uuid
|
|
14
|
-
from
|
|
14
|
+
from collections.abc import Callable
|
|
15
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
15
16
|
|
|
16
17
|
from ..doc_utils import export_module
|
|
17
18
|
from .base_logger import BaseLogger, LLMConfig
|
autogen/logger/logger_factory.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#
|
|
5
5
|
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
6
|
# SPDX-License-Identifier: MIT
|
|
7
|
-
from typing import Any, Literal
|
|
7
|
+
from typing import Any, Literal
|
|
8
8
|
|
|
9
9
|
from ..doc_utils import export_module
|
|
10
10
|
from .base_logger import BaseLogger
|
|
@@ -20,7 +20,7 @@ class LoggerFactory:
|
|
|
20
20
|
|
|
21
21
|
@staticmethod
|
|
22
22
|
def get_logger(
|
|
23
|
-
logger_type: Literal["sqlite", "file"] = "sqlite", config:
|
|
23
|
+
logger_type: Literal["sqlite", "file"] = "sqlite", config: dict[str, Any] | None = None
|
|
24
24
|
) -> BaseLogger:
|
|
25
25
|
"""Factory method to create logger objects.
|
|
26
26
|
|
autogen/logger/logger_utils.py
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import inspect
|
|
8
8
|
from datetime import datetime, timezone
|
|
9
9
|
from pathlib import Path, PurePath
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
11
11
|
|
|
12
12
|
__all__ = ("get_current_ts", "to_dict")
|
|
13
13
|
|
|
@@ -22,7 +22,7 @@ def get_current_ts() -> str:
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def to_dict(
|
|
25
|
-
obj:
|
|
25
|
+
obj: int | float | str | bool | dict[Any, Any] | list[Any] | tuple[Any, ...] | Any,
|
|
26
26
|
exclude: tuple[str, ...] = (),
|
|
27
27
|
no_recursive: tuple[Any, ...] = (),
|
|
28
28
|
) -> Any:
|
autogen/logger/sqlite_logger.py
CHANGED
|
@@ -12,7 +12,8 @@ import os
|
|
|
12
12
|
import sqlite3
|
|
13
13
|
import threading
|
|
14
14
|
import uuid
|
|
15
|
-
from
|
|
15
|
+
from collections.abc import Callable
|
|
16
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
16
17
|
|
|
17
18
|
from ..doc_utils import export_module
|
|
18
19
|
from .base_logger import BaseLogger, LLMConfig
|
autogen/math_utils.py
CHANGED
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
#
|
|
5
5
|
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
6
|
# SPDX-License-Identifier: MIT
|
|
7
|
-
from typing import Optional
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
def remove_boxed(string: str) ->
|
|
9
|
+
def remove_boxed(string: str) -> str | None:
|
|
11
10
|
"""Source: https://github.com/hendrycks/math
|
|
12
11
|
Extract the text within a \\boxed`{...}` environment.
|
|
13
12
|
|
|
@@ -28,7 +27,7 @@ def remove_boxed(string: str) -> Optional[str]:
|
|
|
28
27
|
return None
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
def last_boxed_only_string(string: str) ->
|
|
30
|
+
def last_boxed_only_string(string: str) -> str | None:
|
|
32
31
|
"""Source: https://github.com/hendrycks/math
|
|
33
32
|
Extract the last \\boxed`{...}` or \\fbox`{...}` element from a string.
|
|
34
33
|
"""
|
|
@@ -239,7 +238,7 @@ def _strip_string(string: str) -> str:
|
|
|
239
238
|
return string
|
|
240
239
|
|
|
241
240
|
|
|
242
|
-
def get_answer(solution:
|
|
241
|
+
def get_answer(solution: str | None) -> str | None:
|
|
243
242
|
if solution is None:
|
|
244
243
|
return None
|
|
245
244
|
last_boxed = last_boxed_only_string(solution)
|
|
@@ -251,7 +250,7 @@ def get_answer(solution: Optional[str]) -> Optional[str]:
|
|
|
251
250
|
return answer
|
|
252
251
|
|
|
253
252
|
|
|
254
|
-
def is_equiv(str1:
|
|
253
|
+
def is_equiv(str1: str | None, str2: str | None) -> float:
|
|
255
254
|
"""Returns (as a float) whether two strings containing math are equivalent up to differences of formatting in
|
|
256
255
|
- units
|
|
257
256
|
- fractions
|