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.

Files changed (236) hide show
  1. {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/METADATA +102 -75
  2. ag2-0.9.9.dist-info/RECORD +387 -0
  3. autogen/__init__.py +1 -2
  4. autogen/_website/generate_api_references.py +4 -5
  5. autogen/_website/generate_mkdocs.py +9 -15
  6. autogen/_website/notebook_processor.py +13 -14
  7. autogen/_website/process_notebooks.py +10 -10
  8. autogen/_website/utils.py +5 -4
  9. autogen/agentchat/agent.py +13 -13
  10. autogen/agentchat/assistant_agent.py +7 -6
  11. autogen/agentchat/contrib/agent_eval/agent_eval.py +3 -3
  12. autogen/agentchat/contrib/agent_eval/critic_agent.py +3 -3
  13. autogen/agentchat/contrib/agent_eval/quantifier_agent.py +3 -3
  14. autogen/agentchat/contrib/agent_eval/subcritic_agent.py +3 -3
  15. autogen/agentchat/contrib/agent_optimizer.py +3 -3
  16. autogen/agentchat/contrib/capabilities/generate_images.py +11 -11
  17. autogen/agentchat/contrib/capabilities/teachability.py +15 -15
  18. autogen/agentchat/contrib/capabilities/transforms.py +17 -18
  19. autogen/agentchat/contrib/capabilities/transforms_util.py +5 -5
  20. autogen/agentchat/contrib/capabilities/vision_capability.py +4 -3
  21. autogen/agentchat/contrib/captainagent/agent_builder.py +30 -30
  22. autogen/agentchat/contrib/captainagent/captainagent.py +22 -21
  23. autogen/agentchat/contrib/captainagent/tool_retriever.py +2 -3
  24. autogen/agentchat/contrib/gpt_assistant_agent.py +9 -9
  25. autogen/agentchat/contrib/graph_rag/document.py +3 -3
  26. autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +3 -3
  27. autogen/agentchat/contrib/graph_rag/falkor_graph_rag_capability.py +6 -6
  28. autogen/agentchat/contrib/graph_rag/graph_query_engine.py +3 -3
  29. autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +5 -11
  30. autogen/agentchat/contrib/graph_rag/neo4j_graph_rag_capability.py +6 -6
  31. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_query_engine.py +7 -7
  32. autogen/agentchat/contrib/graph_rag/neo4j_native_graph_rag_capability.py +6 -6
  33. autogen/agentchat/contrib/img_utils.py +1 -1
  34. autogen/agentchat/contrib/llamaindex_conversable_agent.py +11 -11
  35. autogen/agentchat/contrib/llava_agent.py +18 -4
  36. autogen/agentchat/contrib/math_user_proxy_agent.py +11 -11
  37. autogen/agentchat/contrib/multimodal_conversable_agent.py +8 -8
  38. autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +6 -5
  39. autogen/agentchat/contrib/rag/chromadb_query_engine.py +22 -26
  40. autogen/agentchat/contrib/rag/llamaindex_query_engine.py +14 -17
  41. autogen/agentchat/contrib/rag/mongodb_query_engine.py +27 -37
  42. autogen/agentchat/contrib/rag/query_engine.py +7 -5
  43. autogen/agentchat/contrib/retrieve_assistant_agent.py +5 -5
  44. autogen/agentchat/contrib/retrieve_user_proxy_agent.py +8 -7
  45. autogen/agentchat/contrib/society_of_mind_agent.py +15 -14
  46. autogen/agentchat/contrib/swarm_agent.py +76 -98
  47. autogen/agentchat/contrib/text_analyzer_agent.py +7 -7
  48. autogen/agentchat/contrib/vectordb/base.py +10 -18
  49. autogen/agentchat/contrib/vectordb/chromadb.py +2 -1
  50. autogen/agentchat/contrib/vectordb/couchbase.py +18 -20
  51. autogen/agentchat/contrib/vectordb/mongodb.py +6 -5
  52. autogen/agentchat/contrib/vectordb/pgvectordb.py +40 -41
  53. autogen/agentchat/contrib/vectordb/qdrant.py +5 -5
  54. autogen/agentchat/contrib/web_surfer.py +20 -19
  55. autogen/agentchat/conversable_agent.py +292 -290
  56. autogen/agentchat/group/context_str.py +1 -3
  57. autogen/agentchat/group/context_variables.py +15 -25
  58. autogen/agentchat/group/group_tool_executor.py +10 -10
  59. autogen/agentchat/group/group_utils.py +15 -15
  60. autogen/agentchat/group/guardrails.py +7 -7
  61. autogen/agentchat/group/handoffs.py +19 -36
  62. autogen/agentchat/group/multi_agent_chat.py +7 -7
  63. autogen/agentchat/group/on_condition.py +4 -7
  64. autogen/agentchat/group/on_context_condition.py +4 -7
  65. autogen/agentchat/group/patterns/auto.py +8 -7
  66. autogen/agentchat/group/patterns/manual.py +7 -6
  67. autogen/agentchat/group/patterns/pattern.py +13 -12
  68. autogen/agentchat/group/patterns/random.py +3 -3
  69. autogen/agentchat/group/patterns/round_robin.py +3 -3
  70. autogen/agentchat/group/reply_result.py +2 -4
  71. autogen/agentchat/group/speaker_selection_result.py +5 -5
  72. autogen/agentchat/group/targets/group_chat_target.py +7 -6
  73. autogen/agentchat/group/targets/group_manager_target.py +4 -4
  74. autogen/agentchat/group/targets/transition_target.py +2 -1
  75. autogen/agentchat/groupchat.py +60 -63
  76. autogen/agentchat/realtime/experimental/audio_adapters/twilio_audio_adapter.py +4 -4
  77. autogen/agentchat/realtime/experimental/audio_adapters/websocket_audio_adapter.py +4 -4
  78. autogen/agentchat/realtime/experimental/clients/gemini/client.py +7 -7
  79. autogen/agentchat/realtime/experimental/clients/oai/base_client.py +8 -8
  80. autogen/agentchat/realtime/experimental/clients/oai/rtc_client.py +6 -6
  81. autogen/agentchat/realtime/experimental/clients/realtime_client.py +10 -9
  82. autogen/agentchat/realtime/experimental/realtime_agent.py +10 -9
  83. autogen/agentchat/realtime/experimental/realtime_observer.py +3 -3
  84. autogen/agentchat/realtime/experimental/realtime_swarm.py +44 -44
  85. autogen/agentchat/user_proxy_agent.py +10 -9
  86. autogen/agentchat/utils.py +3 -3
  87. autogen/agents/contrib/time/time_reply_agent.py +6 -5
  88. autogen/agents/contrib/time/time_tool_agent.py +2 -1
  89. autogen/agents/experimental/deep_research/deep_research.py +3 -3
  90. autogen/agents/experimental/discord/discord.py +2 -2
  91. autogen/agents/experimental/document_agent/chroma_query_engine.py +29 -44
  92. autogen/agents/experimental/document_agent/docling_doc_ingest_agent.py +9 -14
  93. autogen/agents/experimental/document_agent/document_agent.py +15 -16
  94. autogen/agents/experimental/document_agent/document_conditions.py +3 -3
  95. autogen/agents/experimental/document_agent/document_utils.py +5 -9
  96. autogen/agents/experimental/document_agent/inmemory_query_engine.py +14 -20
  97. autogen/agents/experimental/document_agent/parser_utils.py +4 -4
  98. autogen/agents/experimental/document_agent/url_utils.py +14 -23
  99. autogen/agents/experimental/reasoning/reasoning_agent.py +33 -33
  100. autogen/agents/experimental/slack/slack.py +2 -2
  101. autogen/agents/experimental/telegram/telegram.py +2 -3
  102. autogen/agents/experimental/websurfer/websurfer.py +4 -4
  103. autogen/agents/experimental/wikipedia/wikipedia.py +5 -7
  104. autogen/browser_utils.py +8 -8
  105. autogen/cache/abstract_cache_base.py +5 -5
  106. autogen/cache/cache.py +12 -12
  107. autogen/cache/cache_factory.py +4 -4
  108. autogen/cache/cosmos_db_cache.py +9 -9
  109. autogen/cache/disk_cache.py +6 -6
  110. autogen/cache/in_memory_cache.py +4 -4
  111. autogen/cache/redis_cache.py +4 -4
  112. autogen/code_utils.py +18 -18
  113. autogen/coding/base.py +6 -6
  114. autogen/coding/docker_commandline_code_executor.py +9 -9
  115. autogen/coding/func_with_reqs.py +7 -6
  116. autogen/coding/jupyter/base.py +3 -3
  117. autogen/coding/jupyter/docker_jupyter_server.py +3 -4
  118. autogen/coding/jupyter/import_utils.py +3 -3
  119. autogen/coding/jupyter/jupyter_client.py +5 -5
  120. autogen/coding/jupyter/jupyter_code_executor.py +3 -4
  121. autogen/coding/jupyter/local_jupyter_server.py +2 -6
  122. autogen/coding/local_commandline_code_executor.py +8 -7
  123. autogen/coding/markdown_code_extractor.py +1 -2
  124. autogen/coding/utils.py +1 -2
  125. autogen/doc_utils.py +3 -2
  126. autogen/environments/docker_python_environment.py +19 -29
  127. autogen/environments/python_environment.py +8 -17
  128. autogen/environments/system_python_environment.py +3 -4
  129. autogen/environments/venv_python_environment.py +8 -12
  130. autogen/environments/working_directory.py +1 -2
  131. autogen/events/agent_events.py +106 -109
  132. autogen/events/base_event.py +6 -5
  133. autogen/events/client_events.py +15 -14
  134. autogen/events/helpers.py +1 -1
  135. autogen/events/print_event.py +4 -5
  136. autogen/fast_depends/_compat.py +10 -15
  137. autogen/fast_depends/core/build.py +17 -36
  138. autogen/fast_depends/core/model.py +64 -113
  139. autogen/fast_depends/dependencies/model.py +2 -1
  140. autogen/fast_depends/dependencies/provider.py +3 -2
  141. autogen/fast_depends/library/model.py +4 -4
  142. autogen/fast_depends/schema.py +7 -7
  143. autogen/fast_depends/use.py +17 -25
  144. autogen/fast_depends/utils.py +10 -30
  145. autogen/formatting_utils.py +6 -6
  146. autogen/graph_utils.py +1 -4
  147. autogen/import_utils.py +38 -27
  148. autogen/interop/crewai/crewai.py +2 -2
  149. autogen/interop/interoperable.py +2 -2
  150. autogen/interop/langchain/langchain_chat_model_factory.py +3 -2
  151. autogen/interop/langchain/langchain_tool.py +2 -6
  152. autogen/interop/litellm/litellm_config_factory.py +6 -7
  153. autogen/interop/pydantic_ai/pydantic_ai.py +4 -7
  154. autogen/interop/registry.py +2 -1
  155. autogen/io/base.py +5 -5
  156. autogen/io/run_response.py +33 -32
  157. autogen/io/websockets.py +6 -5
  158. autogen/json_utils.py +1 -2
  159. autogen/llm_config/__init__.py +11 -0
  160. autogen/llm_config/client.py +58 -0
  161. autogen/llm_config/config.py +384 -0
  162. autogen/llm_config/entry.py +154 -0
  163. autogen/logger/base_logger.py +4 -3
  164. autogen/logger/file_logger.py +2 -1
  165. autogen/logger/logger_factory.py +2 -2
  166. autogen/logger/logger_utils.py +2 -2
  167. autogen/logger/sqlite_logger.py +2 -1
  168. autogen/math_utils.py +4 -5
  169. autogen/mcp/__main__.py +6 -6
  170. autogen/mcp/helpers.py +4 -4
  171. autogen/mcp/mcp_client.py +170 -29
  172. autogen/mcp/mcp_proxy/fastapi_code_generator_helpers.py +3 -4
  173. autogen/mcp/mcp_proxy/mcp_proxy.py +23 -26
  174. autogen/mcp/mcp_proxy/operation_grouping.py +4 -5
  175. autogen/mcp/mcp_proxy/operation_renaming.py +6 -10
  176. autogen/mcp/mcp_proxy/security.py +2 -3
  177. autogen/messages/agent_messages.py +96 -98
  178. autogen/messages/base_message.py +6 -5
  179. autogen/messages/client_messages.py +15 -14
  180. autogen/messages/print_message.py +4 -5
  181. autogen/oai/__init__.py +1 -2
  182. autogen/oai/anthropic.py +42 -41
  183. autogen/oai/bedrock.py +68 -57
  184. autogen/oai/cerebras.py +26 -25
  185. autogen/oai/client.py +113 -139
  186. autogen/oai/client_utils.py +3 -3
  187. autogen/oai/cohere.py +34 -11
  188. autogen/oai/gemini.py +39 -17
  189. autogen/oai/gemini_types.py +11 -12
  190. autogen/oai/groq.py +22 -10
  191. autogen/oai/mistral.py +17 -11
  192. autogen/oai/oai_models/__init__.py +14 -2
  193. autogen/oai/oai_models/_models.py +2 -2
  194. autogen/oai/oai_models/chat_completion.py +13 -14
  195. autogen/oai/oai_models/chat_completion_message.py +11 -9
  196. autogen/oai/oai_models/chat_completion_message_tool_call.py +26 -3
  197. autogen/oai/oai_models/chat_completion_token_logprob.py +3 -4
  198. autogen/oai/oai_models/completion_usage.py +8 -9
  199. autogen/oai/ollama.py +19 -9
  200. autogen/oai/openai_responses.py +40 -17
  201. autogen/oai/openai_utils.py +48 -38
  202. autogen/oai/together.py +29 -14
  203. autogen/retrieve_utils.py +6 -7
  204. autogen/runtime_logging.py +5 -4
  205. autogen/token_count_utils.py +7 -4
  206. autogen/tools/contrib/time/time.py +0 -1
  207. autogen/tools/dependency_injection.py +5 -6
  208. autogen/tools/experimental/browser_use/browser_use.py +10 -10
  209. autogen/tools/experimental/code_execution/python_code_execution.py +5 -7
  210. autogen/tools/experimental/crawl4ai/crawl4ai.py +12 -15
  211. autogen/tools/experimental/deep_research/deep_research.py +9 -8
  212. autogen/tools/experimental/duckduckgo/duckduckgo_search.py +5 -11
  213. autogen/tools/experimental/firecrawl/firecrawl_tool.py +98 -115
  214. autogen/tools/experimental/google/authentication/credentials_local_provider.py +1 -1
  215. autogen/tools/experimental/google/drive/drive_functions.py +4 -4
  216. autogen/tools/experimental/google/drive/toolkit.py +5 -5
  217. autogen/tools/experimental/google_search/google_search.py +5 -5
  218. autogen/tools/experimental/google_search/youtube_search.py +5 -5
  219. autogen/tools/experimental/messageplatform/discord/discord.py +8 -12
  220. autogen/tools/experimental/messageplatform/slack/slack.py +14 -20
  221. autogen/tools/experimental/messageplatform/telegram/telegram.py +8 -12
  222. autogen/tools/experimental/perplexity/perplexity_search.py +18 -29
  223. autogen/tools/experimental/reliable/reliable.py +68 -74
  224. autogen/tools/experimental/searxng/searxng_search.py +20 -19
  225. autogen/tools/experimental/tavily/tavily_search.py +12 -19
  226. autogen/tools/experimental/web_search_preview/web_search_preview.py +13 -7
  227. autogen/tools/experimental/wikipedia/wikipedia.py +7 -10
  228. autogen/tools/function_utils.py +7 -7
  229. autogen/tools/tool.py +8 -6
  230. autogen/types.py +2 -2
  231. autogen/version.py +1 -1
  232. ag2-0.9.7.dist-info/RECORD +0 -421
  233. autogen/llm_config.py +0 -385
  234. {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/WHEEL +0 -0
  235. {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/licenses/LICENSE +0 -0
  236. {ag2-0.9.7.dist-info → ag2-0.9.9.dist-info}/licenses/NOTICE.md +0 -0
@@ -6,13 +6,13 @@
6
6
  # SPDX-License-Identifier: MIT
7
7
 
8
8
  from abc import ABC
9
- from typing import Any, Dict, Optional, TypeVar
9
+ from typing import Any, TypeVar
10
10
 
11
11
  Cls = TypeVar("Cls", bound="CustomField")
12
12
 
13
13
 
14
14
  class CustomField(ABC):
15
- param_name: Optional[str]
15
+ param_name: str | None
16
16
  cast: bool
17
17
  required: bool
18
18
 
@@ -38,9 +38,9 @@ class CustomField(ABC):
38
38
  self.param_name = name
39
39
  return self
40
40
 
41
- def use(self, /, **kwargs: Any) -> Dict[str, Any]:
41
+ def use(self, /, **kwargs: Any) -> dict[str, Any]:
42
42
  assert self.param_name, "You should specify `param_name` before using"
43
43
  return kwargs
44
44
 
45
- def use_field(self, kwargs: Dict[str, Any]) -> None:
45
+ def use_field(self, kwargs: dict[str, Any]) -> None:
46
46
  raise NotImplementedError("You should implement `use_field` method.")
@@ -5,7 +5,7 @@
5
5
  # Portions derived from https://github.com/https://github.com/Lancetnik/FastDepends are under the MIT License.
6
6
  # SPDX-License-Identifier: MIT
7
7
 
8
- from typing import Any, Dict, List, Optional
8
+ from typing import Any
9
9
 
10
10
  from ._compat import PYDANTIC_V2, create_model, model_schema
11
11
  from .core import CallModel
@@ -15,13 +15,13 @@ def get_schema(
15
15
  call: CallModel[Any, Any],
16
16
  embed: bool = False,
17
17
  resolve_refs: bool = False,
18
- ) -> Dict[str, Any]:
18
+ ) -> dict[str, Any]:
19
19
  assert call.model, "Call should has a model"
20
20
  params_model = create_model( # type: ignore[call-overload]
21
21
  call.model.__name__, **call.flat_params
22
22
  )
23
23
 
24
- body: Dict[str, Any] = model_schema(params_model)
24
+ body: dict[str, Any] = model_schema(params_model)
25
25
 
26
26
  if not call.flat_params:
27
27
  body = {"title": body["title"], "type": "null"}
@@ -37,8 +37,8 @@ def get_schema(
37
37
  return body
38
38
 
39
39
 
40
- def _move_pydantic_refs(original: Any, key: str, refs: Optional[Dict[str, Any]] = None) -> Any:
41
- if not isinstance(original, Dict):
40
+ def _move_pydantic_refs(original: Any, key: str, refs: dict[str, Any] | None = None) -> Any:
41
+ if not isinstance(original, dict):
42
42
  return original
43
43
 
44
44
  data = original.copy()
@@ -47,7 +47,7 @@ def _move_pydantic_refs(original: Any, key: str, refs: Optional[Dict[str, Any]]
47
47
  raw_refs = data.get(key, {})
48
48
  refs = _move_pydantic_refs(raw_refs, key, raw_refs)
49
49
 
50
- name: Optional[str] = None
50
+ name: str | None = None
51
51
  for k in data:
52
52
  if k == "$ref":
53
53
  name = data[k].replace(f"#/{key}/", "")
@@ -55,7 +55,7 @@ def _move_pydantic_refs(original: Any, key: str, refs: Optional[Dict[str, Any]]
55
55
  elif isinstance(data[k], dict):
56
56
  data[k] = _move_pydantic_refs(data[k], key, refs)
57
57
 
58
- elif isinstance(data[k], List):
58
+ elif isinstance(data[k], list):
59
59
  for i in range(len(data[k])):
60
60
  data[k][i] = _move_pydantic_refs(data[k][i], key, refs)
61
61
 
@@ -5,18 +5,13 @@
5
5
  # Portions derived from https://github.com/https://github.com/Lancetnik/FastDepends are under the MIT License.
6
6
  # SPDX-License-Identifier: MIT
7
7
 
8
+ from collections.abc import AsyncIterator, Callable, Iterator, Sequence
8
9
  from contextlib import AsyncExitStack, ExitStack
9
10
  from functools import partial, wraps
10
11
  from typing import (
11
12
  Any,
12
- AsyncIterator,
13
- Callable,
14
- Iterator,
15
- Optional,
16
13
  Protocol,
17
- Sequence,
18
14
  TypeVar,
19
- Union,
20
15
  cast,
21
16
  overload,
22
17
  )
@@ -48,7 +43,7 @@ class _InjectWrapper(Protocol[P, T]):
48
43
  def __call__(
49
44
  self,
50
45
  func: Callable[P, T],
51
- model: Optional[CallModel[P, T]] = None,
46
+ model: CallModel[P, T] | None = None,
52
47
  ) -> Callable[P, T]: ...
53
48
 
54
49
 
@@ -58,8 +53,8 @@ def inject( # pragma: no cover
58
53
  *,
59
54
  cast: bool = True,
60
55
  extra_dependencies: Sequence[model.Depends] = (),
61
- pydantic_config: Optional[ConfigDict] = None,
62
- dependency_overrides_provider: Optional[Any] = dependency_provider,
56
+ pydantic_config: ConfigDict | None = None,
57
+ dependency_overrides_provider: Any | None = dependency_provider,
63
58
  wrap_model: Callable[[CallModel[P, T]], CallModel[P, T]] = lambda x: x,
64
59
  ) -> _InjectWrapper[P, T]: ...
65
60
 
@@ -70,24 +65,21 @@ def inject( # pragma: no cover
70
65
  *,
71
66
  cast: bool = True,
72
67
  extra_dependencies: Sequence[model.Depends] = (),
73
- pydantic_config: Optional[ConfigDict] = None,
74
- dependency_overrides_provider: Optional[Any] = dependency_provider,
68
+ pydantic_config: ConfigDict | None = None,
69
+ dependency_overrides_provider: Any | None = dependency_provider,
75
70
  wrap_model: Callable[[CallModel[P, T]], CallModel[P, T]] = lambda x: x,
76
71
  ) -> Callable[P, T]: ...
77
72
 
78
73
 
79
74
  def inject(
80
- func: Optional[Callable[P, T]] = None,
75
+ func: Callable[P, T] | None = None,
81
76
  *,
82
77
  cast: bool = True,
83
78
  extra_dependencies: Sequence[model.Depends] = (),
84
- pydantic_config: Optional[ConfigDict] = None,
85
- dependency_overrides_provider: Optional[Any] = dependency_provider,
79
+ pydantic_config: ConfigDict | None = None,
80
+ dependency_overrides_provider: Any | None = dependency_provider,
86
81
  wrap_model: Callable[[CallModel[P, T]], CallModel[P, T]] = lambda x: x,
87
- ) -> Union[
88
- Callable[P, T],
89
- _InjectWrapper[P, T],
90
- ]:
82
+ ) -> Callable[P, T] | _InjectWrapper[P, T]:
91
83
  decorator = _wrap_inject(
92
84
  dependency_overrides_provider=dependency_overrides_provider,
93
85
  wrap_model=wrap_model,
@@ -104,14 +96,14 @@ def inject(
104
96
 
105
97
 
106
98
  def _wrap_inject(
107
- dependency_overrides_provider: Optional[Any],
99
+ dependency_overrides_provider: Any | None,
108
100
  wrap_model: Callable[
109
101
  [CallModel[P, T]],
110
102
  CallModel[P, T],
111
103
  ],
112
104
  extra_dependencies: Sequence[model.Depends],
113
105
  cast: bool,
114
- pydantic_config: Optional[ConfigDict],
106
+ pydantic_config: ConfigDict | None,
115
107
  ) -> _InjectWrapper[P, T]:
116
108
  if (
117
109
  dependency_overrides_provider
@@ -123,7 +115,7 @@ def _wrap_inject(
123
115
 
124
116
  def func_wrapper(
125
117
  func: Callable[P, T],
126
- model: Optional[CallModel[P, T]] = None,
118
+ model: CallModel[P, T] | None = None,
127
119
  ) -> Callable[P, T]:
128
120
  if model is None:
129
121
  real_model = wrap_model(
@@ -187,12 +179,12 @@ def _wrap_inject(
187
179
 
188
180
 
189
181
  class solve_async_gen: # noqa: N801
190
- _iter: Optional[AsyncIterator[Any]] = None
182
+ _iter: AsyncIterator[Any] | None = None
191
183
 
192
184
  def __init__(
193
185
  self,
194
186
  model: "CallModel[..., Any]",
195
- overrides: Optional[Any],
187
+ overrides: Any | None,
196
188
  *args: Any,
197
189
  **kwargs: Any,
198
190
  ):
@@ -234,12 +226,12 @@ class solve_async_gen: # noqa: N801
234
226
 
235
227
 
236
228
  class solve_gen: # noqa: N801
237
- _iter: Optional[Iterator[Any]] = None
229
+ _iter: Iterator[Any] | None = None
238
230
 
239
231
  def __init__(
240
232
  self,
241
233
  model: "CallModel[..., Any]",
242
- overrides: Optional[Any],
234
+ overrides: Any | None,
243
235
  *args: Any,
244
236
  **kwargs: Any,
245
237
  ):
@@ -8,30 +8,13 @@
8
8
  import asyncio
9
9
  import functools
10
10
  import inspect
11
- from contextlib import AsyncExitStack, ExitStack, asynccontextmanager, contextmanager
12
- from typing import (
13
- TYPE_CHECKING,
14
- Any,
15
- AsyncGenerator,
16
- AsyncIterable,
17
- Awaitable,
18
- Callable,
19
- ContextManager,
20
- Dict,
21
- ForwardRef,
22
- List,
23
- Tuple,
24
- TypeVar,
25
- Union,
26
- cast,
27
- )
11
+ from collections.abc import AsyncGenerator, AsyncIterable, Awaitable, Callable
12
+ from contextlib import AbstractContextManager, AsyncExitStack, ExitStack, asynccontextmanager, contextmanager
13
+ from typing import TYPE_CHECKING, Annotated, Any, ForwardRef, TypeVar, cast, get_args, get_origin
28
14
 
29
15
  import anyio
30
16
  from typing_extensions import (
31
- Annotated,
32
17
  ParamSpec,
33
- get_args,
34
- get_origin,
35
18
  )
36
19
 
37
20
  from ._compat import evaluate_forwardref
@@ -44,10 +27,7 @@ T = TypeVar("T")
44
27
 
45
28
 
46
29
  async def run_async(
47
- func: Union[
48
- Callable[P, T],
49
- Callable[P, Awaitable[T]],
50
- ],
30
+ func: Callable[P, T] | Callable[P, Awaitable[T]],
51
31
  *args: P.args,
52
32
  **kwargs: P.kwargs,
53
33
  ) -> T:
@@ -78,7 +58,7 @@ def solve_generator_sync(*sub_args: Any, call: Callable[..., Any], stack: ExitSt
78
58
  return stack.enter_context(cm)
79
59
 
80
60
 
81
- def get_typed_signature(call: Callable[..., Any]) -> Tuple[inspect.Signature, Any]:
61
+ def get_typed_signature(call: Callable[..., Any]) -> tuple[inspect.Signature, Any]:
82
62
  signature = inspect.signature(call)
83
63
 
84
64
  locals = collect_outer_stack_locals()
@@ -108,10 +88,10 @@ def get_typed_signature(call: Callable[..., Any]) -> Tuple[inspect.Signature, An
108
88
  )
109
89
 
110
90
 
111
- def collect_outer_stack_locals() -> Dict[str, Any]:
91
+ def collect_outer_stack_locals() -> dict[str, Any]:
112
92
  frame = inspect.currentframe()
113
93
 
114
- frames: List[FrameType] = []
94
+ frames: list[FrameType] = []
115
95
  while frame is not None:
116
96
  if "fast_depends" not in frame.f_code.co_filename:
117
97
  frames.append(frame)
@@ -126,8 +106,8 @@ def collect_outer_stack_locals() -> Dict[str, Any]:
126
106
 
127
107
  def get_typed_annotation(
128
108
  annotation: Any,
129
- globalns: Dict[str, Any],
130
- locals: Dict[str, Any],
109
+ globalns: dict[str, Any],
110
+ locals: dict[str, Any],
131
111
  ) -> Any:
132
112
  if isinstance(annotation, str):
133
113
  annotation = ForwardRef(annotation)
@@ -144,7 +124,7 @@ def get_typed_annotation(
144
124
 
145
125
  @asynccontextmanager
146
126
  async def contextmanager_in_threadpool(
147
- cm: ContextManager[T],
127
+ cm: AbstractContextManager[T],
148
128
  ) -> AsyncGenerator[T, None]:
149
129
  exit_limiter = anyio.CapacityLimiter(1)
150
130
  try:
@@ -7,7 +7,7 @@
7
7
  from __future__ import annotations
8
8
 
9
9
  from collections.abc import Iterable
10
- from typing import Literal, Optional
10
+ from typing import Literal
11
11
 
12
12
  from .import_utils import optional_import_block
13
13
 
@@ -70,12 +70,12 @@ if not result.is_successful:
70
70
 
71
71
  def colored(
72
72
  text: object,
73
- color: Optional[Color] = None,
74
- on_color: Optional[Highlight] = None,
75
- attrs: Optional[Iterable[Attribute]] = None,
73
+ color: Color | None = None,
74
+ on_color: Highlight | None = None,
75
+ attrs: Iterable[Attribute] | None = None,
76
76
  *,
77
- no_color: Optional[bool] = None,
78
- force_color: Optional[bool] = None,
77
+ no_color: bool | None = None,
78
+ force_color: bool | None = None,
79
79
  ) -> str:
80
80
  return str(text)
81
81
 
autogen/graph_utils.py CHANGED
@@ -6,7 +6,6 @@
6
6
  # SPDX-License-Identifier: MIT
7
7
 
8
8
  import logging
9
- from typing import Optional
10
9
 
11
10
  from .agentchat import Agent
12
11
  from .import_utils import optional_import_block, require_optional_import
@@ -25,7 +24,6 @@ def has_self_loops(allowed_speaker_transitions: dict[str, list[Agent]]) -> bool:
25
24
  Returns:
26
25
  True if there are self loops in the allowed_speaker_transitions_Dict.
27
26
  """
28
-
29
27
  return any([key in value for key, value in allowed_speaker_transitions.items()])
30
28
 
31
29
 
@@ -144,7 +142,7 @@ def invert_disallowed_to_allowed(
144
142
 
145
143
  @require_optional_import(["matplotlib", "networkx"], "graph")
146
144
  def visualize_speaker_transitions_dict(
147
- speaker_transitions_dict: dict[str, list[Agent]], agents: list[Agent], export_path: Optional[str] = None
145
+ speaker_transitions_dict: dict[str, list[Agent]], agents: list[Agent], export_path: str | None = None
148
146
  ) -> None:
149
147
  """Visualize the speaker_transitions_dict using networkx.
150
148
 
@@ -158,7 +156,6 @@ def visualize_speaker_transitions_dict(
158
156
 
159
157
 
160
158
  """
161
-
162
159
  g = nx.DiGraph()
163
160
 
164
161
  # Add nodes
autogen/import_utils.py CHANGED
@@ -6,12 +6,15 @@ import inspect
6
6
  import re
7
7
  import sys
8
8
  from abc import ABC, abstractmethod
9
+ from collections.abc import Callable, Generator, Iterable
9
10
  from contextlib import contextmanager, suppress
10
11
  from dataclasses import dataclass
11
12
  from functools import wraps
12
13
  from logging import getLogger
13
14
  from pathlib import Path
14
- from typing import Any, Callable, Generator, Generic, Iterable, Optional, TypeVar, Union
15
+ from typing import Any, Generic, Optional, TypeVar
16
+
17
+ from packaging import version
15
18
 
16
19
  __all__ = [
17
20
  "optional_import_block",
@@ -27,12 +30,12 @@ logger = getLogger(__name__)
27
30
  @dataclass
28
31
  class ModuleInfo:
29
32
  name: str
30
- min_version: Optional[str] = None
31
- max_version: Optional[str] = None
33
+ min_version: str | None = None
34
+ max_version: str | None = None
32
35
  min_inclusive: bool = False
33
36
  max_inclusive: bool = False
34
37
 
35
- def is_in_sys_modules(self) -> Optional[str]:
38
+ def is_in_sys_modules(self) -> str | None:
36
39
  """Check if the module is installed and satisfies the version constraints
37
40
 
38
41
  Returns:
@@ -52,25 +55,34 @@ class ModuleInfo:
52
55
  # Aka similarly named module in the autogen or test directory
53
56
  return f"'{self.name}' is not installed."
54
57
 
55
- installed_version = (
58
+ # Ensure that the retrieved version is a string. Some packages might unexpectedly
59
+ # have a __version__ attribute that is not a string (e.g., a module).
60
+ raw_version_attr = (
56
61
  sys.modules[self.name].__version__ if hasattr(sys.modules[self.name], "__version__") else None
57
62
  )
63
+ installed_version = raw_version_attr if isinstance(raw_version_attr, str) else None
58
64
  if installed_version is None and (self.min_version or self.max_version):
59
65
  return f"'{self.name}' is installed, but the version is not available."
60
66
 
61
- if self.min_version:
62
- msg = f"'{self.name}' is installed, but the installed version {installed_version} is too low (required '{self}')."
63
- if not self.min_inclusive and installed_version == self.min_version:
64
- return msg
65
- if self.min_inclusive and installed_version < self.min_version: # type: ignore[operator]
66
- return msg
67
-
68
- if self.max_version:
69
- msg = f"'{self.name}' is installed, but the installed version {installed_version} is too high (required '{self}')."
70
- if not self.max_inclusive and installed_version == self.max_version:
71
- return msg
72
- if self.max_inclusive and installed_version > self.max_version: # type: ignore[operator]
73
- return msg
67
+ if installed_version:
68
+ # Convert to version object for comparison
69
+ installed_ver = version.parse(installed_version)
70
+
71
+ if self.min_version:
72
+ min_ver = version.parse(self.min_version)
73
+ msg = f"'{self.name}' is installed, but the installed version {installed_version} is too low (required '{self}')."
74
+ if not self.min_inclusive and installed_ver == min_ver:
75
+ return msg
76
+ if self.min_inclusive and installed_ver < min_ver:
77
+ return msg
78
+
79
+ if self.max_version:
80
+ max_ver = version.parse(self.max_version)
81
+ msg = f"'{self.name}' is installed, but the installed version {installed_version} is too high (required '{self}')."
82
+ if not self.max_inclusive and installed_ver == max_ver:
83
+ return msg
84
+ if self.max_inclusive and installed_ver > max_ver:
85
+ return msg
74
86
 
75
87
  return None
76
88
 
@@ -95,7 +107,6 @@ class ModuleInfo:
95
107
  Raises:
96
108
  ValueError: If the module information is invalid
97
109
  """
98
-
99
110
  pattern = re.compile(r"^(?P<name>[a-zA-Z0-9-_]+)(?P<constraint>.*)$")
100
111
  match = pattern.match(module_info.strip())
101
112
 
@@ -140,7 +151,7 @@ class ModuleInfo:
140
151
 
141
152
  class Result:
142
153
  def __init__(self) -> None:
143
- self._failed: Optional[bool] = None
154
+ self._failed: bool | None = None
144
155
 
145
156
  @property
146
157
  def is_successful(self) -> bool:
@@ -173,7 +184,7 @@ def optional_import_block() -> Generator[Result, None, None]:
173
184
  result._failed = True
174
185
 
175
186
 
176
- def get_missing_imports(modules: Union[str, Iterable[str]]) -> dict[str, str]:
187
+ def get_missing_imports(modules: str | Iterable[str]) -> dict[str, str]:
177
188
  """Get missing modules from a list of module names
178
189
 
179
190
  Args:
@@ -191,7 +202,7 @@ def get_missing_imports(modules: Union[str, Iterable[str]]) -> dict[str, str]:
191
202
 
192
203
 
193
204
  T = TypeVar("T")
194
- G = TypeVar("G", bound=Union[Callable[..., Any], type])
205
+ G = TypeVar("G", bound=Callable[..., Any] | type)
195
206
  F = TypeVar("F", bound=Callable[..., Any])
196
207
 
197
208
 
@@ -401,7 +412,7 @@ def patch_object(
401
412
  missing_modules: dict[str, str],
402
413
  dep_target: str,
403
414
  fail_if_not_patchable: bool = True,
404
- except_for: Optional[Union[str, Iterable[str]]] = None,
415
+ except_for: str | Iterable[str] | None = None,
405
416
  ) -> T:
406
417
  patcher = PatchObject.create(o, missing_modules=missing_modules, dep_target=dep_target)
407
418
  if fail_if_not_patchable and patcher is None:
@@ -414,10 +425,10 @@ def patch_object(
414
425
 
415
426
 
416
427
  def require_optional_import(
417
- modules: Union[str, Iterable[str]],
428
+ modules: str | Iterable[str],
418
429
  dep_target: str,
419
430
  *,
420
- except_for: Optional[Union[str, Iterable[str]]] = None,
431
+ except_for: str | Iterable[str] | None = None,
421
432
  ) -> Callable[[T], T]:
422
433
  """Decorator to handle optional module dependencies
423
434
 
@@ -453,7 +464,7 @@ def _mark_object(o: T, dep_target: str) -> T:
453
464
  return pytest_mark_o # type: ignore[no-any-return]
454
465
 
455
466
 
456
- def run_for_optional_imports(modules: Union[str, Iterable[str]], dep_target: str) -> Callable[[G], G]:
467
+ def run_for_optional_imports(modules: str | Iterable[str], dep_target: str) -> Callable[[G], G]:
457
468
  """Decorator to run a test if and only if optional modules are installed
458
469
 
459
470
  Args:
@@ -497,7 +508,7 @@ def run_for_optional_imports(modules: Union[str, Iterable[str]], dep_target: str
497
508
  return decorator
498
509
 
499
510
 
500
- def skip_on_missing_imports(modules: Union[str, Iterable[str]], dep_target: str) -> Callable[[T], T]:
511
+ def skip_on_missing_imports(modules: str | Iterable[str], dep_target: str) -> Callable[[T], T]:
501
512
  """Decorator to skip a test if an optional module is missing
502
513
 
503
514
  Args:
@@ -4,7 +4,7 @@
4
4
 
5
5
  import re
6
6
  import sys
7
- from typing import Any, Optional
7
+ from typing import Any
8
8
 
9
9
  from ...doc_utils import export_module
10
10
  from ...import_utils import optional_import_block, require_optional_import
@@ -75,7 +75,7 @@ class CrewAIInteroperability:
75
75
  )
76
76
 
77
77
  @classmethod
78
- def get_unsupported_reason(cls) -> Optional[str]:
78
+ def get_unsupported_reason(cls) -> str | None:
79
79
  if sys.version_info < (3, 10) or sys.version_info >= (3, 13):
80
80
  return "This submodule is only supported for Python versions 3.10, 3.11, and 3.12"
81
81
 
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from typing import Any, Optional, Protocol, runtime_checkable
5
+ from typing import Any, Protocol, runtime_checkable
6
6
 
7
7
  from ..doc_utils import export_module
8
8
  from ..tools import Tool
@@ -35,7 +35,7 @@ class Interoperable(Protocol):
35
35
  ...
36
36
 
37
37
  @classmethod
38
- def get_unsupported_reason(cls) -> Optional[str]:
38
+ def get_unsupported_reason(cls) -> str | None:
39
39
  """Returns the reason for the tool being unsupported.
40
40
 
41
41
  This method should be implemented by any class adhering to the `Interoperable` protocol.
@@ -3,7 +3,8 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  from abc import ABC, abstractmethod
6
- from typing import Any, Callable, TypeVar, Union
6
+ from collections.abc import Callable
7
+ from typing import Any, TypeVar
7
8
 
8
9
  from ...doc_utils import export_module
9
10
  from ...import_utils import optional_import_block, require_optional_import
@@ -33,7 +34,7 @@ class LangChainChatModelFactory(ABC):
33
34
  _factories: set["LangChainChatModelFactory"] = set()
34
35
 
35
36
  @classmethod
36
- def create_base_chat_model(cls, llm_config: Union[LLMConfig, dict[str, Any]]) -> "BaseChatModel": # type: ignore [no-any-unimported]
37
+ def create_base_chat_model(cls, llm_config: LLMConfig | dict[str, Any]) -> "BaseChatModel": # type: ignore [no-any-unimported]
37
38
  first_llm_config = get_first_llm_config(llm_config)
38
39
  for factory in LangChainChatModelFactory._factories:
39
40
  if factory.accepts(first_llm_config):
@@ -2,8 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- import sys
6
- from typing import Any, Optional
5
+ from typing import Any
7
6
 
8
7
  from ...doc_utils import export_module
9
8
  from ...import_utils import optional_import_block, require_optional_import
@@ -67,10 +66,7 @@ class LangChainInteroperability:
67
66
  )
68
67
 
69
68
  @classmethod
70
- def get_unsupported_reason(cls) -> Optional[str]:
71
- if sys.version_info < (3, 9):
72
- return "This submodule is only supported for Python versions 3.9 and above"
73
-
69
+ def get_unsupported_reason(cls) -> str | None:
74
70
  with optional_import_block() as result:
75
71
  import langchain_core.tools # noqa: F401
76
72
 
@@ -4,7 +4,8 @@
4
4
 
5
5
  import os
6
6
  from abc import ABC, abstractmethod
7
- from typing import Any, Callable, Optional, TypeVar, Union
7
+ from collections.abc import Callable
8
+ from typing import Any, TypeVar
8
9
 
9
10
  from ...doc_utils import export_module
10
11
  from ...llm_config import LLMConfig
@@ -15,7 +16,7 @@ __all__ = ["LiteLLmConfigFactory"]
15
16
  T = TypeVar("T", bound="LiteLLmConfigFactory")
16
17
 
17
18
 
18
- def get_crawl4ai_version() -> Optional[str]:
19
+ def get_crawl4ai_version() -> str | None:
19
20
  """Get the installed crawl4ai version."""
20
21
  try:
21
22
  import crawl4ai
@@ -46,9 +47,8 @@ class LiteLLmConfigFactory(ABC):
46
47
  _factories: set["LiteLLmConfigFactory"] = set()
47
48
 
48
49
  @classmethod
49
- def create_lite_llm_config(cls, llm_config: Union[LLMConfig, dict[str, Any]]) -> dict[str, Any]:
50
- """
51
- Create a lite LLM config compatible with the installed crawl4ai version.
50
+ def create_lite_llm_config(cls, llm_config: LLMConfig | dict[str, Any]) -> dict[str, Any]:
51
+ """Create a lite LLM config compatible with the installed crawl4ai version.
52
52
 
53
53
  For crawl4ai >=0.5: Returns config with llmConfig parameter
54
54
  For crawl4ai <0.5: Returns config with provider parameter (legacy)
@@ -68,8 +68,7 @@ class LiteLLmConfigFactory(ABC):
68
68
 
69
69
  @classmethod
70
70
  def _adapt_for_crawl4ai_v05(cls, base_config: dict[str, Any]) -> dict[str, Any]:
71
- """
72
- Adapt the config for crawl4ai >=0.5 by moving deprecated parameters
71
+ """Adapt the config for crawl4ai >=0.5 by moving deprecated parameters
73
72
  into an llmConfig object.
74
73
  """
75
74
  adapted_config = base_config.copy()
@@ -3,11 +3,11 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
 
6
- import sys
7
6
  import warnings
7
+ from collections.abc import Callable
8
8
  from functools import wraps
9
9
  from inspect import signature
10
- from typing import Any, Callable, Optional
10
+ from typing import Any
11
11
 
12
12
  from ...doc_utils import export_module
13
13
  from ...import_utils import optional_import_block, require_optional_import
@@ -55,7 +55,7 @@ class PydanticAIInteroperability:
55
55
  Raises:
56
56
  ValueError: If the tool fails after the maximum number of retries.
57
57
  """
58
- ctx_typed: Optional[RunContext[Any]] = ctx # type: ignore[no-any-unimported]
58
+ ctx_typed: RunContext[Any] | None = ctx # type: ignore[no-any-unimported]
59
59
  tool_typed: PydanticAITool[Any] = tool # type: ignore[no-any-unimported]
60
60
 
61
61
  max_retries = tool_typed.max_retries if tool_typed.max_retries is not None else 1
@@ -155,10 +155,7 @@ class PydanticAIInteroperability:
155
155
  )
156
156
 
157
157
  @classmethod
158
- def get_unsupported_reason(cls) -> Optional[str]:
159
- if sys.version_info < (3, 9):
160
- return "This submodule is only supported for Python versions 3.9 and above"
161
-
158
+ def get_unsupported_reason(cls) -> str | None:
162
159
  with optional_import_block() as result:
163
160
  import pydantic_ai.tools # noqa: F401
164
161
 
@@ -2,7 +2,8 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from typing import Callable, TypeVar
5
+ from collections.abc import Callable
6
+ from typing import TypeVar
6
7
 
7
8
  from ..doc_utils import export_module
8
9
  from .interoperable import Interoperable