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
autogen/oai/ollama.py
CHANGED
|
@@ -29,12 +29,12 @@ import random
|
|
|
29
29
|
import re
|
|
30
30
|
import time
|
|
31
31
|
import warnings
|
|
32
|
-
from typing import Any, Literal
|
|
32
|
+
from typing import Any, Literal
|
|
33
33
|
|
|
34
34
|
from pydantic import BaseModel, Field, HttpUrl
|
|
35
35
|
|
|
36
36
|
from ..import_utils import optional_import_block, require_optional_import
|
|
37
|
-
from ..llm_config import LLMConfigEntry,
|
|
37
|
+
from ..llm_config.entry import LLMConfigEntry, LLMConfigEntryDict
|
|
38
38
|
from .client_utils import FormatterProtocol, should_hide_tools, validate_parameter
|
|
39
39
|
from .oai_models import ChatCompletion, ChatCompletionMessage, ChatCompletionMessageToolCall, Choice, CompletionUsage
|
|
40
40
|
|
|
@@ -44,10 +44,23 @@ with optional_import_block():
|
|
|
44
44
|
from ollama import Client
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
class OllamaEntryDict(LLMConfigEntryDict, total=False):
|
|
48
|
+
api_type: Literal["ollama"]
|
|
49
|
+
client_host: HttpUrl | None
|
|
50
|
+
stream: bool
|
|
51
|
+
num_predict: int
|
|
52
|
+
num_ctx: int
|
|
53
|
+
repeat_penalty: float
|
|
54
|
+
seed: int
|
|
55
|
+
top_k: int
|
|
56
|
+
hide_tools: Literal["if_all_run", "if_any_run", "never"]
|
|
57
|
+
native_tool_calls: bool
|
|
58
|
+
|
|
59
|
+
|
|
48
60
|
class OllamaLLMConfigEntry(LLMConfigEntry):
|
|
49
61
|
api_type: Literal["ollama"] = "ollama"
|
|
50
|
-
|
|
62
|
+
# TODO: max_tokens
|
|
63
|
+
client_host: HttpUrl | None = None
|
|
51
64
|
stream: bool = False
|
|
52
65
|
num_predict: int = Field(
|
|
53
66
|
default=-1,
|
|
@@ -56,9 +69,7 @@ class OllamaLLMConfigEntry(LLMConfigEntry):
|
|
|
56
69
|
num_ctx: int = Field(default=2048)
|
|
57
70
|
repeat_penalty: float = Field(default=1.1)
|
|
58
71
|
seed: int = Field(default=0)
|
|
59
|
-
temperature: float = Field(default=0.8)
|
|
60
72
|
top_k: int = Field(default=40)
|
|
61
|
-
top_p: float = Field(default=0.9)
|
|
62
73
|
hide_tools: Literal["if_all_run", "if_any_run", "never"] = "never"
|
|
63
74
|
native_tool_calls: bool = False
|
|
64
75
|
|
|
@@ -101,11 +112,10 @@ class OllamaClient:
|
|
|
101
112
|
# Override using "manual_tool_call_step2" config parameter
|
|
102
113
|
TOOL_CALL_MANUAL_STEP2 = " (proceed with step 2)"
|
|
103
114
|
|
|
104
|
-
def __init__(self, response_format:
|
|
115
|
+
def __init__(self, response_format: BaseModel | dict[str, Any] | None = None, **kwargs):
|
|
105
116
|
"""Note that no api_key or environment variable is required for Ollama."""
|
|
106
|
-
|
|
107
117
|
# Store the response format, if provided (for structured outputs)
|
|
108
|
-
self._response_format:
|
|
118
|
+
self._response_format: BaseModel | dict[str, Any] | None = response_format
|
|
109
119
|
|
|
110
120
|
def message_retrieval(self, response) -> list:
|
|
111
121
|
"""Retrieve and return a list of strings or a list of Choice.Message from the response.
|
autogen/oai/openai_responses.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import copy
|
|
6
6
|
import warnings
|
|
7
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
|
|
@@ -48,9 +48,8 @@ VALID_SIZES = {
|
|
|
48
48
|
|
|
49
49
|
def calculate_openai_image_cost(
|
|
50
50
|
model: str = "gpt-image-1", size: str = "1024x1024", quality: str = "high"
|
|
51
|
-
) ->
|
|
52
|
-
"""
|
|
53
|
-
Calculate the cost for a single image generation.
|
|
51
|
+
) -> tuple[float, str]:
|
|
52
|
+
"""Calculate the cost for a single image generation.
|
|
54
53
|
|
|
55
54
|
Args:
|
|
56
55
|
model: Model name ("gpt-image-1", "dall-e-3" or "dall-e-2")
|
|
@@ -114,7 +113,7 @@ class OpenAIResponsesClient:
|
|
|
114
113
|
def __init__(
|
|
115
114
|
self,
|
|
116
115
|
client: "OpenAI",
|
|
117
|
-
response_format:
|
|
116
|
+
response_format: BaseModel | dict[str, Any] | None = None,
|
|
118
117
|
):
|
|
119
118
|
self._oai_client = client # plain openai.OpenAI instance
|
|
120
119
|
self.response_format = response_format # kept for parity but unused for now
|
|
@@ -195,6 +194,12 @@ class OpenAIResponsesClient:
|
|
|
195
194
|
delta_messages.append(m)
|
|
196
195
|
return delta_messages[::-1]
|
|
197
196
|
|
|
197
|
+
def _parse_params(self, params: dict[str, Any]) -> None:
|
|
198
|
+
if "verbosity" in params:
|
|
199
|
+
verbosity = params.pop("verbosity")
|
|
200
|
+
params["text"] = {"verbosity": verbosity}
|
|
201
|
+
return params
|
|
202
|
+
|
|
198
203
|
def create(self, params: dict[str, Any]) -> "Response":
|
|
199
204
|
"""Invoke `client.responses.create() or .parse()`.
|
|
200
205
|
|
|
@@ -246,7 +251,14 @@ class OpenAIResponsesClient:
|
|
|
246
251
|
"output": content,
|
|
247
252
|
})
|
|
248
253
|
break
|
|
249
|
-
|
|
254
|
+
|
|
255
|
+
# Ensure we have at least one valid input item
|
|
256
|
+
if input_items:
|
|
257
|
+
params["input"] = input_items[::-1]
|
|
258
|
+
else:
|
|
259
|
+
# If no valid input items were created, create a default one
|
|
260
|
+
# This prevents the API error about missing required parameters
|
|
261
|
+
params["input"] = [{"role": "user", "content": [{"type": "input_text", "text": "Hello"}]}]
|
|
250
262
|
|
|
251
263
|
# Initialize tools list
|
|
252
264
|
tools_list = []
|
|
@@ -274,6 +286,11 @@ class OpenAIResponsesClient:
|
|
|
274
286
|
UserWarning,
|
|
275
287
|
)
|
|
276
288
|
|
|
289
|
+
# Validate that we have at least one of the required parameters
|
|
290
|
+
if not any(key in params for key in ["input", "previous_response_id", "prompt"]):
|
|
291
|
+
# If we still don't have any required parameters, create a minimal input
|
|
292
|
+
params["input"] = [{"role": "user", "content": [{"type": "input_text", "text": "Hello"}]}]
|
|
293
|
+
|
|
277
294
|
# ------------------------------------------------------------------
|
|
278
295
|
# Structured output handling - mimic OpenAIClient behaviour
|
|
279
296
|
# ------------------------------------------------------------------
|
|
@@ -306,7 +323,6 @@ class OpenAIResponsesClient:
|
|
|
306
323
|
kwargs["text_format"] = type_to_response_format_param(rf)
|
|
307
324
|
if "response_format" in kwargs:
|
|
308
325
|
kwargs["text_format"] = kwargs.pop("response_format")
|
|
309
|
-
|
|
310
326
|
try:
|
|
311
327
|
return self._oai_client.responses.parse(**kwargs)
|
|
312
328
|
except TypeError as e:
|
|
@@ -325,22 +341,19 @@ class OpenAIResponsesClient:
|
|
|
325
341
|
response = _create_or_parse(**params)
|
|
326
342
|
self.previous_response_id = response.id
|
|
327
343
|
return response
|
|
328
|
-
|
|
329
344
|
# No structured output
|
|
345
|
+
params = self._parse_params(params)
|
|
330
346
|
response = self._oai_client.responses.create(**params)
|
|
331
347
|
self.previous_response_id = response.id
|
|
332
|
-
|
|
333
348
|
# Accumulate image costs
|
|
334
349
|
self._add_image_cost(response)
|
|
335
|
-
|
|
336
350
|
return response
|
|
337
351
|
|
|
338
|
-
def message_retrieval(
|
|
339
|
-
self, response
|
|
340
|
-
) -> Union[list[str], list["ModelClient.ModelClientResponseProtocol.Choice.Message"]]:
|
|
352
|
+
def message_retrieval(self, response) -> list[str] | list["ModelClient.ModelClientResponseProtocol.Choice.Message"]:
|
|
341
353
|
output = getattr(response, "output", [])
|
|
342
|
-
content = []
|
|
354
|
+
content = []
|
|
343
355
|
tool_calls = []
|
|
356
|
+
|
|
344
357
|
for item in output:
|
|
345
358
|
# Convert pydantic objects to plain dicts for uniform handling
|
|
346
359
|
if hasattr(item, "model_dump"):
|
|
@@ -348,16 +361,26 @@ class OpenAIResponsesClient:
|
|
|
348
361
|
|
|
349
362
|
item_type = item.get("type")
|
|
350
363
|
|
|
351
|
-
#
|
|
352
|
-
|
|
353
|
-
|
|
364
|
+
# Skip reasoning items - they're not messages
|
|
365
|
+
if item_type == "reasoning":
|
|
366
|
+
continue
|
|
367
|
+
|
|
354
368
|
if item_type == "message":
|
|
355
369
|
new_item = copy.deepcopy(item)
|
|
356
370
|
new_item["type"] = "text"
|
|
357
371
|
new_item["role"] = "assistant"
|
|
372
|
+
|
|
358
373
|
blocks = item.get("content", [])
|
|
359
374
|
if len(blocks) == 1 and blocks[0].get("type") == "output_text":
|
|
360
375
|
new_item["text"] = blocks[0]["text"]
|
|
376
|
+
elif len(blocks) > 0:
|
|
377
|
+
# Handle multiple content blocks
|
|
378
|
+
text_parts = []
|
|
379
|
+
for block in blocks:
|
|
380
|
+
if block.get("type") == "output_text":
|
|
381
|
+
text_parts.append(block.get("text", ""))
|
|
382
|
+
new_item["text"] = " ".join(text_parts)
|
|
383
|
+
|
|
361
384
|
if "content" in new_item:
|
|
362
385
|
del new_item["content"]
|
|
363
386
|
content.append(new_item)
|
autogen/oai/openai_utils.py
CHANGED
|
@@ -17,7 +17,7 @@ import time
|
|
|
17
17
|
import warnings
|
|
18
18
|
from copy import deepcopy
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import TYPE_CHECKING, Any,
|
|
20
|
+
from typing import TYPE_CHECKING, Any, Union
|
|
21
21
|
|
|
22
22
|
from dotenv import find_dotenv, load_dotenv
|
|
23
23
|
from packaging.version import parse
|
|
@@ -27,8 +27,9 @@ if TYPE_CHECKING:
|
|
|
27
27
|
from openai import OpenAI
|
|
28
28
|
from openai.types.beta.assistant import Assistant
|
|
29
29
|
|
|
30
|
+
from ..llm_config import LLMConfig
|
|
31
|
+
|
|
30
32
|
from ..doc_utils import export_module
|
|
31
|
-
from ..llm_config import LLMConfig
|
|
32
33
|
|
|
33
34
|
NON_CACHE_KEY = [
|
|
34
35
|
"api_key",
|
|
@@ -58,6 +59,15 @@ OAI_PRICE1K = {
|
|
|
58
59
|
# o3
|
|
59
60
|
"o3": (0.0011, 0.0044),
|
|
60
61
|
"o3-mini-2025-01-31": (0.0011, 0.0044),
|
|
62
|
+
# gpt-5
|
|
63
|
+
"gpt-5": (0.00125, 0.00125),
|
|
64
|
+
"gpt-5-2025-08-07": (0.00125, 0.00125),
|
|
65
|
+
# gpt-5-mini
|
|
66
|
+
"gpt-5-mini": (0.00025, 0.00025),
|
|
67
|
+
"gpt-5-mini-2025-08-07": (0.00025, 0.00025),
|
|
68
|
+
# gpt-5-nano
|
|
69
|
+
"gpt-5-nano": (0.00005, 0.00005),
|
|
70
|
+
"gpt-5-nano-2025-08-07": (0.00005, 0.00005),
|
|
61
71
|
# gpt-4o
|
|
62
72
|
"gpt-4o": (0.005, 0.015),
|
|
63
73
|
"gpt-4o-2024-05-13": (0.005, 0.015),
|
|
@@ -157,9 +167,9 @@ def is_valid_api_key(api_key: str) -> bool:
|
|
|
157
167
|
@export_module("autogen")
|
|
158
168
|
def get_config_list(
|
|
159
169
|
api_keys: list[str],
|
|
160
|
-
base_urls:
|
|
161
|
-
api_type:
|
|
162
|
-
api_version:
|
|
170
|
+
base_urls: list[str] | None = None,
|
|
171
|
+
api_type: str | None = None,
|
|
172
|
+
api_version: str | None = None,
|
|
163
173
|
) -> list[dict[str, Any]]:
|
|
164
174
|
"""Get a list of configs for OpenAI API client.
|
|
165
175
|
|
|
@@ -208,7 +218,7 @@ def get_config_list(
|
|
|
208
218
|
|
|
209
219
|
@export_module("autogen")
|
|
210
220
|
def get_first_llm_config(
|
|
211
|
-
llm_config: Union[LLMConfig, dict[str, Any]],
|
|
221
|
+
llm_config: Union["LLMConfig", dict[str, Any]],
|
|
212
222
|
) -> dict[str, Any]:
|
|
213
223
|
"""Get the first LLM config from the given LLM config.
|
|
214
224
|
|
|
@@ -236,12 +246,12 @@ def get_first_llm_config(
|
|
|
236
246
|
|
|
237
247
|
@export_module("autogen")
|
|
238
248
|
def config_list_openai_aoai(
|
|
239
|
-
key_file_path:
|
|
240
|
-
openai_api_key_file:
|
|
241
|
-
aoai_api_key_file:
|
|
242
|
-
openai_api_base_file:
|
|
243
|
-
aoai_api_base_file:
|
|
244
|
-
exclude:
|
|
249
|
+
key_file_path: str | None = ".",
|
|
250
|
+
openai_api_key_file: str | None = "key_openai.txt",
|
|
251
|
+
aoai_api_key_file: str | None = "key_aoai.txt",
|
|
252
|
+
openai_api_base_file: str | None = "base_openai.txt",
|
|
253
|
+
aoai_api_base_file: str | None = "base_aoai.txt",
|
|
254
|
+
exclude: str | None = None,
|
|
245
255
|
) -> list[dict[str, Any]]:
|
|
246
256
|
"""Get a list of configs for OpenAI API client (including Azure or local model deployments that support OpenAI's chat completion API).
|
|
247
257
|
|
|
@@ -366,12 +376,12 @@ def config_list_openai_aoai(
|
|
|
366
376
|
|
|
367
377
|
@export_module("autogen")
|
|
368
378
|
def config_list_from_models(
|
|
369
|
-
key_file_path:
|
|
370
|
-
openai_api_key_file:
|
|
371
|
-
aoai_api_key_file:
|
|
372
|
-
aoai_api_base_file:
|
|
373
|
-
exclude:
|
|
374
|
-
model_list:
|
|
379
|
+
key_file_path: str | None = ".",
|
|
380
|
+
openai_api_key_file: str | None = "key_openai.txt",
|
|
381
|
+
aoai_api_key_file: str | None = "key_aoai.txt",
|
|
382
|
+
aoai_api_base_file: str | None = "base_aoai.txt",
|
|
383
|
+
exclude: str | None = None,
|
|
384
|
+
model_list: list[str] | None = None,
|
|
375
385
|
) -> list[dict[str, Any]]:
|
|
376
386
|
"""Get a list of configs for API calls with models specified in the model list.
|
|
377
387
|
|
|
@@ -433,11 +443,11 @@ def config_list_from_models(
|
|
|
433
443
|
|
|
434
444
|
@export_module("autogen")
|
|
435
445
|
def config_list_gpt4_gpt35(
|
|
436
|
-
key_file_path:
|
|
437
|
-
openai_api_key_file:
|
|
438
|
-
aoai_api_key_file:
|
|
439
|
-
aoai_api_base_file:
|
|
440
|
-
exclude:
|
|
446
|
+
key_file_path: str | None = ".",
|
|
447
|
+
openai_api_key_file: str | None = "key_openai.txt",
|
|
448
|
+
aoai_api_key_file: str | None = "key_aoai.txt",
|
|
449
|
+
aoai_api_base_file: str | None = "base_aoai.txt",
|
|
450
|
+
exclude: str | None = None,
|
|
441
451
|
) -> list[dict[str, Any]]:
|
|
442
452
|
"""Get a list of configs for 'gpt-4' followed by 'gpt-3.5-turbo' API calls.
|
|
443
453
|
|
|
@@ -464,7 +474,7 @@ def config_list_gpt4_gpt35(
|
|
|
464
474
|
@export_module("autogen")
|
|
465
475
|
def filter_config(
|
|
466
476
|
config_list: list[dict[str, Any]],
|
|
467
|
-
filter_dict:
|
|
477
|
+
filter_dict: dict[str, list[str | None] | set[str | None]] | None,
|
|
468
478
|
exclude: bool = False,
|
|
469
479
|
) -> list[dict[str, Any]]:
|
|
470
480
|
"""Filter configuration dictionaries based on specified criteria.
|
|
@@ -621,8 +631,8 @@ def _satisfies_criteria(config_value: Any, criteria_values: Any) -> bool:
|
|
|
621
631
|
@export_module("autogen")
|
|
622
632
|
def config_list_from_json(
|
|
623
633
|
env_or_file: str,
|
|
624
|
-
file_location:
|
|
625
|
-
filter_dict:
|
|
634
|
+
file_location: str | None = "",
|
|
635
|
+
filter_dict: dict[str, list[str | None] | set[str | None]] | None = None,
|
|
626
636
|
) -> list[dict[str, Any]]:
|
|
627
637
|
"""Retrieves a list of API configurations from a JSON stored in an environment variable or a file.
|
|
628
638
|
|
|
@@ -690,10 +700,10 @@ def config_list_from_json(
|
|
|
690
700
|
|
|
691
701
|
|
|
692
702
|
def get_config(
|
|
693
|
-
api_key:
|
|
694
|
-
base_url:
|
|
695
|
-
api_type:
|
|
696
|
-
api_version:
|
|
703
|
+
api_key: str | None,
|
|
704
|
+
base_url: str | None = None,
|
|
705
|
+
api_type: str | None = None,
|
|
706
|
+
api_version: str | None = None,
|
|
697
707
|
) -> dict[str, Any]:
|
|
698
708
|
"""Constructs a configuration dictionary for a single model with the provided API configurations.
|
|
699
709
|
|
|
@@ -729,10 +739,10 @@ def get_config(
|
|
|
729
739
|
|
|
730
740
|
@export_module("autogen")
|
|
731
741
|
def config_list_from_dotenv(
|
|
732
|
-
dotenv_file_path:
|
|
733
|
-
model_api_key_map:
|
|
734
|
-
filter_dict:
|
|
735
|
-
) -> list[dict[str,
|
|
742
|
+
dotenv_file_path: str | None = None,
|
|
743
|
+
model_api_key_map: dict[str, Any] | None = None,
|
|
744
|
+
filter_dict: dict[str, list[str | None] | set[str | None]] | None = None,
|
|
745
|
+
) -> list[dict[str, str | set[str]]]:
|
|
736
746
|
"""Load API configurations from a specified .env file or environment variables and construct a list of configurations.
|
|
737
747
|
|
|
738
748
|
This function will:
|
|
@@ -797,12 +807,12 @@ def config_list_from_dotenv(
|
|
|
797
807
|
config_without_key_var = {k: v for k, v in config.items() if k != "api_key_env_var"}
|
|
798
808
|
config_dict = get_config(api_key=api_key, **config_without_key_var)
|
|
799
809
|
else:
|
|
800
|
-
logging.warning(f"Unsupported type {type(config)} for model {model} configuration")
|
|
801
|
-
|
|
802
|
-
if not config_dict["api_key"] or config_dict["api_key"].strip() == "":
|
|
803
810
|
logging.warning(
|
|
804
|
-
|
|
811
|
+
"Unsupported configuration type encountered for a model. Please check your model_api_key_map."
|
|
805
812
|
)
|
|
813
|
+
|
|
814
|
+
if not config_dict["api_key"] or config_dict["api_key"].strip() == "":
|
|
815
|
+
logging.warning("API key not found or empty for a model. Please ensure path to .env file is correct.")
|
|
806
816
|
continue # Skip this configuration and continue with the next
|
|
807
817
|
|
|
808
818
|
# Add model to the configuration and append to the list
|
autogen/oai/together.py
CHANGED
|
@@ -33,12 +33,13 @@ import copy
|
|
|
33
33
|
import os
|
|
34
34
|
import time
|
|
35
35
|
import warnings
|
|
36
|
-
from typing import Any, Literal
|
|
36
|
+
from typing import Any, Literal
|
|
37
37
|
|
|
38
38
|
from pydantic import Field
|
|
39
|
+
from typing_extensions import Unpack
|
|
39
40
|
|
|
40
41
|
from ..import_utils import optional_import_block, require_optional_import
|
|
41
|
-
from ..llm_config import LLMConfigEntry,
|
|
42
|
+
from ..llm_config.entry import LLMConfigEntry, LLMConfigEntryDict
|
|
42
43
|
from .client_utils import should_hide_tools, validate_parameter
|
|
43
44
|
from .oai_models import ChatCompletion, ChatCompletionMessage, ChatCompletionMessageToolCall, Choice, CompletionUsage
|
|
44
45
|
|
|
@@ -46,22 +47,36 @@ with optional_import_block():
|
|
|
46
47
|
from together import Together
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
class TogetherEntryDict(LLMConfigEntryDict, total=False):
|
|
51
|
+
api_type: Literal["together"]
|
|
52
|
+
|
|
53
|
+
stream: bool
|
|
54
|
+
top_k: int | None
|
|
55
|
+
repetition_penalty: float | None
|
|
56
|
+
presence_penalty: float | None
|
|
57
|
+
frequency_penalty: float | None
|
|
58
|
+
min_p: float | None
|
|
59
|
+
safety_model: str | None
|
|
60
|
+
hide_tools: Literal["if_all_run", "if_any_run", "never"]
|
|
61
|
+
price: list[float] | None
|
|
62
|
+
tool_choice: str | dict[str, str | dict[str, str]] | None
|
|
63
|
+
|
|
64
|
+
|
|
50
65
|
class TogetherLLMConfigEntry(LLMConfigEntry):
|
|
51
66
|
api_type: Literal["together"] = "together"
|
|
67
|
+
|
|
52
68
|
max_tokens: int = Field(default=512, ge=0)
|
|
69
|
+
|
|
53
70
|
stream: bool = False
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
min_p: Optional[float] = Field(default=None, ge=0, le=1)
|
|
61
|
-
safety_model: Optional[str] = None
|
|
71
|
+
top_k: int | None = Field(default=None)
|
|
72
|
+
repetition_penalty: float | None = Field(default=None)
|
|
73
|
+
presence_penalty: float | None = Field(default=None, ge=-2, le=2)
|
|
74
|
+
frequency_penalty: float | None = Field(default=None, ge=-2, le=2)
|
|
75
|
+
min_p: float | None = Field(default=None, ge=0, le=1)
|
|
76
|
+
safety_model: str | None = None
|
|
62
77
|
hide_tools: Literal["if_all_run", "if_any_run", "never"] = "never"
|
|
63
|
-
price:
|
|
64
|
-
tool_choice:
|
|
78
|
+
price: list[float] | None = Field(default=None, min_length=2, max_length=2)
|
|
79
|
+
tool_choice: str | dict[str, str | dict[str, str]] | None = (
|
|
65
80
|
None # dict is the tool to call: {"type": "function", "function": {"name": "my_function"}}
|
|
66
81
|
)
|
|
67
82
|
|
|
@@ -72,7 +87,7 @@ class TogetherLLMConfigEntry(LLMConfigEntry):
|
|
|
72
87
|
class TogetherClient:
|
|
73
88
|
"""Client for Together.AI's API."""
|
|
74
89
|
|
|
75
|
-
def __init__(self, **kwargs):
|
|
90
|
+
def __init__(self, **kwargs: Unpack[TogetherEntryDict]):
|
|
76
91
|
"""Requires api_key or environment variable to be set
|
|
77
92
|
|
|
78
93
|
Args:
|
autogen/retrieve_utils.py
CHANGED
|
@@ -9,7 +9,8 @@ import hashlib
|
|
|
9
9
|
import logging
|
|
10
10
|
import os
|
|
11
11
|
import re
|
|
12
|
-
from
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from typing import Any
|
|
13
14
|
from urllib.parse import urlparse
|
|
14
15
|
|
|
15
16
|
import requests
|
|
@@ -158,11 +159,11 @@ def extract_text_from_pdf(file: str) -> str:
|
|
|
158
159
|
|
|
159
160
|
|
|
160
161
|
def split_files_to_chunks(
|
|
161
|
-
files: list[
|
|
162
|
+
files: list[tuple[str, str] | str],
|
|
162
163
|
max_tokens: int = 4000,
|
|
163
164
|
chunk_mode: str = "multi_lines",
|
|
164
165
|
must_break_at_empty_line: bool = True,
|
|
165
|
-
custom_text_split_function:
|
|
166
|
+
custom_text_split_function: Callable[[str], list[str]] | None = None,
|
|
166
167
|
) -> tuple[list[str], list[dict[str, Any]]]:
|
|
167
168
|
"""Split a list of files into chunks of max_tokens."""
|
|
168
169
|
chunks = []
|
|
@@ -200,9 +201,7 @@ def split_files_to_chunks(
|
|
|
200
201
|
return chunks, sources
|
|
201
202
|
|
|
202
203
|
|
|
203
|
-
def get_files_from_dir(
|
|
204
|
-
dir_path: Union[str, list[str]], types: list[str] = TEXT_FORMATS, recursive: bool = True
|
|
205
|
-
) -> list[Any]:
|
|
204
|
+
def get_files_from_dir(dir_path: str | list[str], types: list[str] = TEXT_FORMATS, recursive: bool = True) -> list[Any]:
|
|
206
205
|
"""Return a list of all the files in a given directory, a url, a file path or a list of them."""
|
|
207
206
|
if len(types) == 0:
|
|
208
207
|
raise ValueError("types cannot be empty.")
|
|
@@ -343,7 +342,7 @@ def is_url(string: str):
|
|
|
343
342
|
|
|
344
343
|
@require_optional_import("chromadb", "retrievechat")
|
|
345
344
|
def create_vector_db_from_dir(
|
|
346
|
-
dir_path:
|
|
345
|
+
dir_path: str | list[str],
|
|
347
346
|
max_tokens: int = 4000,
|
|
348
347
|
client: "API" = None,
|
|
349
348
|
db_path: str = "tmp/chromadb.db",
|
autogen/runtime_logging.py
CHANGED
|
@@ -9,7 +9,8 @@ from __future__ import annotations
|
|
|
9
9
|
import logging
|
|
10
10
|
import sqlite3
|
|
11
11
|
import uuid
|
|
12
|
-
from
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Literal, TypeVar
|
|
13
14
|
|
|
14
15
|
from .logger.base_logger import BaseLogger, LLMConfig
|
|
15
16
|
from .logger.logger_factory import LoggerFactory
|
|
@@ -38,9 +39,9 @@ F = TypeVar("F", bound=Callable[..., Any])
|
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
def start(
|
|
41
|
-
logger:
|
|
42
|
+
logger: BaseLogger | None = None,
|
|
42
43
|
logger_type: Literal["sqlite", "file"] = "sqlite",
|
|
43
|
-
config:
|
|
44
|
+
config: dict[str, Any] | None = None,
|
|
44
45
|
) -> str:
|
|
45
46
|
"""Start logging for the runtime.
|
|
46
47
|
|
|
@@ -71,7 +72,7 @@ def log_chat_completion(
|
|
|
71
72
|
wrapper_id: int,
|
|
72
73
|
agent: str | Agent,
|
|
73
74
|
request: dict[str, float | str | list[dict[str, str]]],
|
|
74
|
-
response: str |
|
|
75
|
+
response: str | ChatCompletion,
|
|
75
76
|
is_cached: int,
|
|
76
77
|
cost: float,
|
|
77
78
|
start_time: str,
|
autogen/token_count_utils.py
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import json
|
|
9
9
|
import logging
|
|
10
10
|
import re
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any
|
|
12
12
|
|
|
13
13
|
import tiktoken
|
|
14
14
|
|
|
@@ -63,6 +63,9 @@ def get_max_token_limit(model: str = "gpt-3.5-turbo-0613") -> int:
|
|
|
63
63
|
"gpt-4o-2024-11-20": 128000,
|
|
64
64
|
"gpt-4o-mini": 128000,
|
|
65
65
|
"gpt-4o-mini-2024-07-18": 128000,
|
|
66
|
+
"gpt-5": 128000,
|
|
67
|
+
"gpt-5-mini": 128000,
|
|
68
|
+
"gpt-5-nano": 128000,
|
|
66
69
|
}
|
|
67
70
|
return max_token_limit[model]
|
|
68
71
|
|
|
@@ -71,7 +74,7 @@ def percentile_used(input, model="gpt-3.5-turbo-0613"):
|
|
|
71
74
|
return count_token(input) / get_max_token_limit(model)
|
|
72
75
|
|
|
73
76
|
|
|
74
|
-
def token_left(input:
|
|
77
|
+
def token_left(input: str | list[str] | dict[str, Any], model="gpt-3.5-turbo-0613") -> int:
|
|
75
78
|
"""Count number of tokens left for an OpenAI model.
|
|
76
79
|
|
|
77
80
|
Args:
|
|
@@ -84,7 +87,7 @@ def token_left(input: Union[str, list[str], dict[str, Any]], model="gpt-3.5-turb
|
|
|
84
87
|
return get_max_token_limit(model) - count_token(input, model=model)
|
|
85
88
|
|
|
86
89
|
|
|
87
|
-
def count_token(input:
|
|
90
|
+
def count_token(input: str | list[str] | dict[str, Any], model: str = "gpt-3.5-turbo-0613") -> int:
|
|
88
91
|
"""Count number of tokens used by an OpenAI model.
|
|
89
92
|
|
|
90
93
|
Args:
|
|
@@ -112,7 +115,7 @@ def _num_token_from_text(text: str, model: str = "gpt-3.5-turbo-0613"):
|
|
|
112
115
|
return len(encoding.encode(text))
|
|
113
116
|
|
|
114
117
|
|
|
115
|
-
def _num_token_from_messages(messages:
|
|
118
|
+
def _num_token_from_messages(messages: list[str] | dict[str, Any], model="gpt-3.5-turbo-0613"):
|
|
116
119
|
"""Return the number of tokens used by a list of messages.
|
|
117
120
|
|
|
118
121
|
retrieved from https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb/
|
|
@@ -6,8 +6,9 @@ import functools
|
|
|
6
6
|
import inspect
|
|
7
7
|
import sys
|
|
8
8
|
from abc import ABC
|
|
9
|
+
from collections.abc import Callable, Iterable
|
|
9
10
|
from functools import wraps
|
|
10
|
-
from typing import TYPE_CHECKING, Any,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, TypeVar, get_type_hints
|
|
11
12
|
|
|
12
13
|
from ..agentchat import Agent
|
|
13
14
|
from ..doc_utils import export_module
|
|
@@ -67,7 +68,7 @@ class ChatContext(BaseContext):
|
|
|
67
68
|
return self._agent.chat_messages
|
|
68
69
|
|
|
69
70
|
@property
|
|
70
|
-
def last_message(self) ->
|
|
71
|
+
def last_message(self) -> dict[str, Any] | None:
|
|
71
72
|
"""The last message in the chat.
|
|
72
73
|
|
|
73
74
|
Returns:
|
|
@@ -102,7 +103,7 @@ def Depends(x: Any) -> Any: # noqa: N802
|
|
|
102
103
|
return FastDepends(x)
|
|
103
104
|
|
|
104
105
|
|
|
105
|
-
def get_context_params(func: Callable[..., Any], subclass:
|
|
106
|
+
def get_context_params(func: Callable[..., Any], subclass: type[BaseContext] | type[ChatContext]) -> list[str]:
|
|
106
107
|
"""Gets the names of the context parameters in a function signature.
|
|
107
108
|
|
|
108
109
|
Args:
|
|
@@ -116,9 +117,7 @@ def get_context_params(func: Callable[..., Any], subclass: Union[type[BaseContex
|
|
|
116
117
|
return [p.name for p in sig.parameters.values() if _is_context_param(p, subclass=subclass)]
|
|
117
118
|
|
|
118
119
|
|
|
119
|
-
def _is_context_param(
|
|
120
|
-
param: inspect.Parameter, subclass: Union[type[BaseContext], type[ChatContext]] = BaseContext
|
|
121
|
-
) -> bool:
|
|
120
|
+
def _is_context_param(param: inspect.Parameter, subclass: type[BaseContext] | type[ChatContext] = BaseContext) -> bool:
|
|
122
121
|
# param.annotation.__args__[0] is used to handle Annotated[MyContext, Depends(MyContext(b=2))]
|
|
123
122
|
param_annotation = param.annotation.__args__[0] if hasattr(param.annotation, "__args__") else param.annotation
|
|
124
123
|
try:
|