ag2 0.8.1__tar.gz → 0.8.2rc0__tar.gz

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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ag2
3
- Version: 0.8.1
3
+ Version: 0.8.2rc0
4
4
  Summary: Alias package for pyautogen
5
5
  Home-page: https://github.com/ag2ai/ag2
6
6
  Author: Chi Wang & Qingyun Wu
@@ -25,6 +25,7 @@ Provides-Extra: graph-rag-falkor-db
25
25
  Provides-Extra: rag
26
26
  Provides-Extra: crawl4ai
27
27
  Provides-Extra: browser-use
28
+ Provides-Extra: google-search
28
29
  Provides-Extra: neo4j
29
30
  Provides-Extra: twilio
30
31
  Provides-Extra: interop-crewai
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ag2
3
- Version: 0.8.1
3
+ Version: 0.8.2rc0
4
4
  Summary: Alias package for pyautogen
5
5
  Home-page: https://github.com/ag2ai/ag2
6
6
  Author: Chi Wang & Qingyun Wu
@@ -25,6 +25,7 @@ Provides-Extra: graph-rag-falkor-db
25
25
  Provides-Extra: rag
26
26
  Provides-Extra: crawl4ai
27
27
  Provides-Extra: browser-use
28
+ Provides-Extra: google-search
28
29
  Provides-Extra: neo4j
29
30
  Provides-Extra: twilio
30
31
  Provides-Extra: interop-crewai
@@ -0,0 +1,154 @@
1
+ pyautogen==0.8.2rc0
2
+
3
+ [anthropic]
4
+ pyautogen[anthropic]==0.8.2rc0
5
+
6
+ [autobuild]
7
+ pyautogen[autobuild]==0.8.2rc0
8
+
9
+ [bedrock]
10
+ pyautogen[bedrock]==0.8.2rc0
11
+
12
+ [blendsearch]
13
+ pyautogen[blendsearch]==0.8.2rc0
14
+
15
+ [browser-use]
16
+ pyautogen[browser-use]==0.8.2rc0
17
+
18
+ [captainagent]
19
+ pyautogen[captainagent]==0.8.2rc0
20
+
21
+ [cerebras]
22
+ pyautogen[cerebras]==0.8.2rc0
23
+
24
+ [cohere]
25
+ pyautogen[cohere]==0.8.2rc0
26
+
27
+ [commsagent-discord]
28
+ pyautogen[commsagent-discord]==0.8.2rc0
29
+
30
+ [commsagent-slack]
31
+ pyautogen[commsagent-slack]==0.8.2rc0
32
+
33
+ [commsagent-telegram]
34
+ pyautogen[commsagent-telegram]==0.8.2rc0
35
+
36
+ [cosmosdb]
37
+ pyautogen[cosmosdb]==0.8.2rc0
38
+
39
+ [crawl4ai]
40
+ pyautogen[crawl4ai]==0.8.2rc0
41
+
42
+ [deepseek]
43
+ pyautogen[deepseek]==0.8.2rc0
44
+
45
+ [dev]
46
+ pyautogen[dev]==0.8.2rc0
47
+
48
+ [docs]
49
+ pyautogen[docs]==0.8.2rc0
50
+
51
+ [flaml]
52
+ pyautogen[flaml]==0.8.2rc0
53
+
54
+ [gemini]
55
+ pyautogen[gemini]==0.8.2rc0
56
+
57
+ [gemini-realtime]
58
+ pyautogen[gemini-realtime]==0.8.2rc0
59
+
60
+ [google-search]
61
+ pyautogen[google-search]==0.8.2rc0
62
+
63
+ [graph]
64
+ pyautogen[graph]==0.8.2rc0
65
+
66
+ [graph-rag-falkor-db]
67
+ pyautogen[graph-rag-falkor-db]==0.8.2rc0
68
+
69
+ [groq]
70
+ pyautogen[groq]==0.8.2rc0
71
+
72
+ [interop]
73
+ pyautogen[interop]==0.8.2rc0
74
+
75
+ [interop-crewai]
76
+ pyautogen[interop-crewai]==0.8.2rc0
77
+
78
+ [interop-langchain]
79
+ pyautogen[interop-langchain]==0.8.2rc0
80
+
81
+ [interop-pydantic-ai]
82
+ pyautogen[interop-pydantic-ai]==0.8.2rc0
83
+
84
+ [jupyter-executor]
85
+ pyautogen[jupyter-executor]==0.8.2rc0
86
+
87
+ [lint]
88
+ pyautogen[lint]==0.8.2rc0
89
+
90
+ [lmm]
91
+ pyautogen[lmm]==0.8.2rc0
92
+
93
+ [long-context]
94
+ pyautogen[long-context]==0.8.2rc0
95
+
96
+ [mathchat]
97
+ pyautogen[mathchat]==0.8.2rc0
98
+
99
+ [mistral]
100
+ pyautogen[mistral]==0.8.2rc0
101
+
102
+ [neo4j]
103
+ pyautogen[neo4j]==0.8.2rc0
104
+
105
+ [ollama]
106
+ pyautogen[ollama]==0.8.2rc0
107
+
108
+ [openai]
109
+ pyautogen[openai]==0.8.2rc0
110
+
111
+ [openai-realtime]
112
+ pyautogen[openai-realtime]==0.8.2rc0
113
+
114
+ [rag]
115
+ pyautogen[rag]==0.8.2rc0
116
+
117
+ [redis]
118
+ pyautogen[redis]==0.8.2rc0
119
+
120
+ [retrievechat]
121
+ pyautogen[retrievechat]==0.8.2rc0
122
+
123
+ [retrievechat-couchbase]
124
+ pyautogen[retrievechat-couchbase]==0.8.2rc0
125
+
126
+ [retrievechat-mongodb]
127
+ pyautogen[retrievechat-mongodb]==0.8.2rc0
128
+
129
+ [retrievechat-pgvector]
130
+ pyautogen[retrievechat-pgvector]==0.8.2rc0
131
+
132
+ [retrievechat-qdrant]
133
+ pyautogen[retrievechat-qdrant]==0.8.2rc0
134
+
135
+ [teachable]
136
+ pyautogen[teachable]==0.8.2rc0
137
+
138
+ [test]
139
+ pyautogen[test]==0.8.2rc0
140
+
141
+ [together]
142
+ pyautogen[together]==0.8.2rc0
143
+
144
+ [twilio]
145
+ pyautogen[twilio]==0.8.2rc0
146
+
147
+ [types]
148
+ pyautogen[types]==0.8.2rc0
149
+
150
+ [websockets]
151
+ pyautogen[websockets]==0.8.2rc0
152
+
153
+ [websurfer]
154
+ pyautogen[websurfer]==0.8.2rc0
@@ -60,8 +60,9 @@ dependencies = [
60
60
  "docker",
61
61
  "packaging",
62
62
  "asyncer==0.0.8",
63
- "fast-depends>=2.4.12,<3",
63
+ # "fast-depends>=2.4.12,<3", # integrated into the package
64
64
  "httpx>=0.28.1,<1",
65
+ "anyio>=3.0.0,<5.0.0" # needed by the internal fast-depends
65
66
  ]
66
67
 
67
68
  [project.optional-dependencies]
@@ -76,7 +77,7 @@ flaml = [
76
77
  # public distributions
77
78
 
78
79
  openai = [
79
- "openai>=1.58",
80
+ "openai>=1.66.2",
80
81
  ]
81
82
 
82
83
  openai-realtime = [
@@ -156,6 +157,10 @@ browser-use = [
156
157
  "browser-use==0.1.37",
157
158
  ]
158
159
 
160
+ google-search = [
161
+ "google-api-python-client>=2.163.0,<3.0",
162
+ ]
163
+
159
164
  neo4j = [
160
165
  "docx2txt==0.8",
161
166
  "llama-index==0.12.22",
@@ -181,8 +186,7 @@ interop =[
181
186
  "pyautogen[interop-crewai, interop-langchain, interop-pydantic-ai]",
182
187
  ]
183
188
 
184
- # pysqlite3-binary used so it doesn't need to compile pysqlite3
185
- autobuild = ["chromadb", "sentence-transformers", "huggingface-hub", "pysqlite3-binary"]
189
+ autobuild = ["chromadb", "sentence-transformers", "huggingface-hub"]
186
190
 
187
191
  blendsearch = ["flaml[blendsearch]"]
188
192
  mathchat = ["sympy", "wolframalpha"]
@@ -237,6 +241,7 @@ test = [
237
241
  "mock==5.1.0",
238
242
  "pandas==2.2.3",
239
243
  "fastapi==0.115.11",
244
+ "dirty-equals==0.9.0",
240
245
  ]
241
246
 
242
247
  docs = [
@@ -341,6 +346,7 @@ markers = [
341
346
  "interop",
342
347
  "browser_use",
343
348
  "crawl4ai",
349
+ "google_search",
344
350
  "websockets",
345
351
  "commsagent_discord",
346
352
  "commsagent_slack",
@@ -438,6 +444,7 @@ files = [
438
444
  "autogen/agents",
439
445
  "autogen/coding",
440
446
  "autogen/exception_utils.py",
447
+ "autogen/fast_depends",
441
448
  "autogen/import_utils.py",
442
449
  "autogen/interop",
443
450
  "autogen/io",
@@ -454,6 +461,7 @@ files = [
454
461
  "test/agentchat/realtime_agent",
455
462
  "test/agents",
456
463
  "test/conftest.py",
464
+ # "test/fast_depends",
457
465
  "test/interop",
458
466
  "test/io",
459
467
  "test/messages",
@@ -41,6 +41,7 @@ setuptools.setup(
41
41
  "rag": ["pyautogen[rag]==" + __version__],
42
42
  "crawl4ai": ["pyautogen[crawl4ai]==" + __version__],
43
43
  "browser-use": ["pyautogen[browser-use]==" + __version__],
44
+ "google-search": ["pyautogen[google-search]==" + __version__],
44
45
  "neo4j": ["pyautogen[neo4j]==" + __version__],
45
46
  "twilio": ["pyautogen[twilio]==" + __version__],
46
47
  "interop-crewai": ["pyautogen[interop-crewai]==" + __version__],
@@ -0,0 +1,451 @@
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
+ import sys
7
+ from types import ModuleType
8
+ from typing import Any, Iterable, Iterator, Optional, Type, Union
9
+
10
+ import pytest
11
+
12
+ from autogen.import_utils import ModuleInfo, get_missing_imports, optional_import_block, require_optional_import
13
+
14
+
15
+ @pytest.fixture
16
+ def mock_module() -> Iterator[ModuleType]:
17
+ module_name = "mock_module"
18
+ module = ModuleType(module_name)
19
+ module.__version__ = "1.0.0" # type: ignore[attr-defined]
20
+ sys.modules[module_name] = module
21
+ yield module
22
+ del sys.modules[module_name]
23
+
24
+
25
+ @pytest.fixture
26
+ def mock_module_without_version() -> Iterator[ModuleType]:
27
+ module_name = "mock_module"
28
+ module = ModuleType(module_name)
29
+ sys.modules[module_name] = module
30
+ yield module
31
+ del sys.modules[module_name]
32
+
33
+
34
+ class MockModule:
35
+ def __init__(self, name: str, version: str):
36
+ self.__name__ = name
37
+ self.__version__ = version
38
+
39
+
40
+ @pytest.fixture
41
+ def mock_modules() -> Iterator[dict[str, ModuleType]]:
42
+ modules = {
43
+ "module_a": MockModule("module_a", "1.0.0"),
44
+ "module_b": MockModule("module_b", "2.0.0"),
45
+ "module_c": MockModule("module_c", "3.0.0"),
46
+ }
47
+ original_sys_modules = sys.modules.copy()
48
+ sys.modules.update(modules) # type: ignore[arg-type]
49
+ assert all(module in sys.modules for module in modules)
50
+ try:
51
+ yield modules # type: ignore[misc]
52
+ finally:
53
+ sys.modules.clear()
54
+ sys.modules.update(original_sys_modules)
55
+
56
+
57
+ class TestmoduleInfo:
58
+ @pytest.mark.parametrize(
59
+ "module_info, expected",
60
+ [
61
+ (
62
+ "jupyter-client>=8.6.0,<9.0.0",
63
+ ModuleInfo(
64
+ name="jupyter-client",
65
+ min_version="8.6.0",
66
+ max_version="9.0.0",
67
+ min_inclusive=True,
68
+ max_inclusive=False,
69
+ ),
70
+ ),
71
+ (
72
+ "jupyter-client>=8.6.0",
73
+ ModuleInfo(
74
+ name="jupyter-client",
75
+ min_version="8.6.0",
76
+ max_version=None,
77
+ min_inclusive=True,
78
+ max_inclusive=False,
79
+ ),
80
+ ),
81
+ (
82
+ "jupyter-client<9.0.0",
83
+ ModuleInfo(
84
+ name="jupyter-client",
85
+ min_version=None,
86
+ max_version="9.0.0",
87
+ min_inclusive=False,
88
+ max_inclusive=False,
89
+ ),
90
+ ),
91
+ (
92
+ "jupyter-client",
93
+ ModuleInfo(
94
+ name="jupyter-client", min_version=None, max_version=None, min_inclusive=False, max_inclusive=False
95
+ ),
96
+ ),
97
+ ],
98
+ )
99
+ def test_from_str_success(self, module_info: str, expected: ModuleInfo) -> None:
100
+ result = ModuleInfo.from_str(module_info)
101
+ assert result == expected
102
+
103
+ def test_from_str_with_invalid_format(self) -> None:
104
+ module_info = "jupyter-client>="
105
+ with pytest.raises(ValueError, match="Invalid module information: jupyter-client>="):
106
+ ModuleInfo.from_str(module_info)
107
+
108
+ @pytest.mark.parametrize(
109
+ "module_info, expected",
110
+ [
111
+ (ModuleInfo(name="mock_module"), None),
112
+ (ModuleInfo(name="non_existent_module"), "'non_existent_module' is not installed."),
113
+ (ModuleInfo(name="mock_module", min_version="1.0.0", min_inclusive=True), None),
114
+ (
115
+ ModuleInfo(name="mock_module", min_version="1.0.0", min_inclusive=False),
116
+ "'mock_module' is installed, but the installed version 1.0.0 is too low (required 'mock_module>1.0.0').",
117
+ ),
118
+ (ModuleInfo(name="mock_module", min_version="0.9.0", min_inclusive=True), None),
119
+ (
120
+ ModuleInfo(name="mock_module", min_version="1.1.0", min_inclusive=True),
121
+ "'mock_module' is installed, but the installed version 1.0.0 is too low (required 'mock_module>=1.1.0').",
122
+ ),
123
+ (ModuleInfo(name="mock_module", max_version="1.0.0", max_inclusive=True), None),
124
+ (
125
+ ModuleInfo(name="mock_module", max_version="1.0.0", max_inclusive=False),
126
+ "'mock_module' is installed, but the installed version 1.0.0 is too high (required 'mock_module<1.0.0').",
127
+ ),
128
+ (ModuleInfo(name="mock_module", max_version="1.1.0", max_inclusive=True), None),
129
+ (
130
+ ModuleInfo(name="mock_module", max_version="0.9.0", max_inclusive=True),
131
+ "'mock_module' is installed, but the installed version 1.0.0 is too high (required 'mock_module<=0.9.0').",
132
+ ),
133
+ (
134
+ ModuleInfo(
135
+ name="mock_module", min_version="0.9.0", max_version="1.1.0", min_inclusive=True, max_inclusive=True
136
+ ),
137
+ None,
138
+ ),
139
+ (
140
+ ModuleInfo(
141
+ name="mock_module", min_version="1.0.0", max_version="1.0.0", min_inclusive=True, max_inclusive=True
142
+ ),
143
+ None,
144
+ ),
145
+ (
146
+ ModuleInfo(
147
+ name="mock_module",
148
+ min_version="1.0.0",
149
+ max_version="1.0.0",
150
+ min_inclusive=False,
151
+ max_inclusive=False,
152
+ ),
153
+ "'mock_module' is installed, but the installed version 1.0.0 is too low (required 'mock_module>1.0.0<1.0.0').",
154
+ ),
155
+ ],
156
+ )
157
+ def test_is_in_sys_modules(self, mock_module: ModuleType, module_info: ModuleInfo, expected: Optional[str]) -> None:
158
+ assert module_info.is_in_sys_modules() == expected
159
+
160
+ @pytest.mark.parametrize(
161
+ "module_info, expected",
162
+ [
163
+ (ModuleInfo(name="mock_module"), None),
164
+ (
165
+ ModuleInfo(name="mock_module", min_version="1.0.0", min_inclusive=True),
166
+ "'mock_module' is installed, but the version is not available.",
167
+ ),
168
+ ],
169
+ )
170
+ def test_is_in_sys_modules_without_version(
171
+ self, mock_module_without_version: ModuleType, module_info: ModuleInfo, expected: Optional[str]
172
+ ) -> None:
173
+ assert module_info.is_in_sys_modules() == expected
174
+
175
+
176
+ class TestOptionalImportBlock:
177
+ def test_optional_import_block(self) -> None:
178
+ with optional_import_block():
179
+ import ast
180
+
181
+ import some_module
182
+ import some_other_module
183
+
184
+ assert ast is not None
185
+ with pytest.raises(
186
+ UnboundLocalError,
187
+ match=r"(local variable 'some_module' referenced before assignment|cannot access local variable 'some_module' where it is not associated with a value)",
188
+ ):
189
+ some_module
190
+
191
+ with pytest.raises(
192
+ UnboundLocalError,
193
+ match=r"(local variable 'some_other_module' referenced before assignment|cannot access local variable 'some_other_module' where it is not associated with a value)",
194
+ ):
195
+ some_other_module
196
+
197
+
198
+ class TestRequiresOptionalImportCallables:
199
+ def test_version_too_high(self, mock_module: ModuleInfo) -> None:
200
+ assert mock_module.__name__ in sys.modules # type: ignore[attr-defined]
201
+ mock_info = f"{mock_module.__name__}>{mock_module.__version__}" # type: ignore[attr-defined]
202
+
203
+ @require_optional_import(mock_info, "mock-module")
204
+ def dummy_function() -> None:
205
+ """Dummy function to test requires_optional_import"""
206
+ pass
207
+
208
+ with pytest.raises(
209
+ ImportError,
210
+ match=re.escape("""A module needed for test.test_import_utils.dummy_function is missing:
211
+ - 'mock_module' is installed, but the installed version 1.0.0 is too low (required 'mock_module>1.0.0').
212
+ Please install it using:
213
+ 'pip install ag2[mock-module]'"""),
214
+ ):
215
+ dummy_function()
216
+
217
+ @pytest.mark.parametrize("except_for", [None, "dummy_function", ["dummy_function"]])
218
+ def test_function_attributes(self, except_for: Optional[Union[str, list[str]]]) -> None:
219
+ def dummy_function() -> None:
220
+ """Dummy function to test requires_optional_import"""
221
+ pass
222
+
223
+ dummy_function.__module__ = "some_random_module.dummy_stuff"
224
+
225
+ actual = require_optional_import("some_optional_module", "optional_dep", except_for=except_for)(dummy_function)
226
+
227
+ assert actual is not None
228
+ assert actual.__module__ == "some_random_module.dummy_stuff"
229
+ assert actual.__name__ == "dummy_function"
230
+ assert actual.__doc__ == "Dummy function to test requires_optional_import"
231
+
232
+ if not except_for:
233
+ with pytest.raises(
234
+ ImportError,
235
+ match=re.escape("""A module needed for some_random_module.dummy_stuff.dummy_function is missing:
236
+ - 'some_optional_module' is not installed.
237
+ Please install it using:
238
+ 'pip install ag2[optional_dep]"""),
239
+ ):
240
+ actual()
241
+ else:
242
+ actual()
243
+
244
+ @pytest.mark.parametrize("except_for", [None, "dummy_function", ["dummy_function"]])
245
+ def test_function_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
246
+ @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
247
+ def dummy_function() -> None:
248
+ """Dummy function to test requires_optional_import"""
249
+ pass
250
+
251
+ if not except_for:
252
+ with pytest.raises(
253
+ ImportError,
254
+ match=re.escape("""A module needed for test.test_import_utils.dummy_function is missing:
255
+ - 'some_optional_module' is not installed.
256
+ Please install it using:
257
+ 'pip install ag2[optional_dep]'"""),
258
+ ):
259
+ dummy_function()
260
+ else:
261
+ dummy_function()
262
+
263
+ @pytest.mark.parametrize("except_for", [None, "dummy_method", ["dummy_method"]])
264
+ def test_method_attributes(self, except_for: Optional[Union[str, list[str]]]) -> None:
265
+ class DummyClass:
266
+ def dummy_method(self) -> None:
267
+ """Dummy method to test requires_optional_import"""
268
+ pass
269
+
270
+ assert hasattr(DummyClass.dummy_method, "__module__")
271
+ assert DummyClass.dummy_method.__module__ == "test.test_import_utils"
272
+
273
+ DummyClass.__module__ = "some_random_module.dummy_stuff"
274
+ DummyClass.dummy_method.__module__ = "some_random_module.dummy_stuff"
275
+
276
+ DummyClass.dummy_method = require_optional_import( # type: ignore[method-assign]
277
+ "some_optional_module", "optional_dep", except_for=except_for
278
+ )(DummyClass.dummy_method)
279
+
280
+ assert DummyClass.dummy_method is not None
281
+ assert DummyClass.dummy_method.__module__ == "some_random_module.dummy_stuff"
282
+ assert DummyClass.dummy_method.__name__ == "dummy_method"
283
+ assert DummyClass.dummy_method.__doc__ == "Dummy method to test requires_optional_import"
284
+
285
+ dummy = DummyClass()
286
+
287
+ if not except_for:
288
+ with pytest.raises(
289
+ ImportError,
290
+ match=re.escape("""A module needed for some_random_module.dummy_stuff.dummy_method is missing:
291
+ - 'some_optional_module' is not installed.
292
+ Please install it using:
293
+ 'pip install ag2[optional_dep]'"""),
294
+ ):
295
+ dummy.dummy_method()
296
+ else:
297
+ dummy.dummy_method()
298
+
299
+ @pytest.mark.parametrize("except_for", [None, "dummy_method", ["dummy_method"]])
300
+ def test_method_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
301
+ class DummyClass:
302
+ @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
303
+ def dummy_method(self) -> None:
304
+ """Dummy method to test requires_optional_import"""
305
+ pass
306
+
307
+ dummy = DummyClass()
308
+
309
+ if not except_for:
310
+ with pytest.raises(
311
+ ImportError,
312
+ match=re.escape("""A module needed for test.test_import_utils.dummy_method is missing:
313
+ - 'some_optional_module' is not installed.
314
+ Please install it using:
315
+ 'pip install ag2[optional_dep]'"""),
316
+ ):
317
+ dummy.dummy_method()
318
+ else:
319
+ dummy.dummy_method()
320
+
321
+ @pytest.mark.parametrize("except_for", [None, "dummy_static_function", ["dummy_static_function"]])
322
+ def test_static_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
323
+ class DummyClass:
324
+ @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
325
+ @staticmethod
326
+ def dummy_static_function() -> None:
327
+ """Dummy static function to test requires_optional_import"""
328
+ pass
329
+
330
+ dummy = DummyClass()
331
+
332
+ if not except_for:
333
+ with pytest.raises(
334
+ ImportError,
335
+ match=re.escape("""A module needed for test.test_import_utils.dummy_static_function is missing:
336
+ - 'some_optional_module' is not installed.
337
+ Please install it using:
338
+ 'pip install ag2[optional_dep]'"""),
339
+ ):
340
+ dummy.dummy_static_function()
341
+ else:
342
+ dummy.dummy_static_function()
343
+
344
+ @pytest.mark.parametrize("except_for", [None, "dummy_property", ["dummy_property"]])
345
+ def test_property_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
346
+ class DummyClass:
347
+ @property
348
+ @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
349
+ def dummy_property(self) -> int:
350
+ """Dummy property to test requires_optional_import"""
351
+ return 4
352
+
353
+ dummy = DummyClass()
354
+
355
+ if not except_for:
356
+ with pytest.raises(
357
+ ImportError,
358
+ match=re.escape("""A module needed for test.test_import_utils.dummy_property is missing:
359
+ - 'some_optional_module' is not installed.
360
+ Please install it using:
361
+ 'pip install ag2[optional_dep]'"""),
362
+ ):
363
+ dummy.dummy_property
364
+
365
+ else:
366
+ dummy.dummy_property
367
+
368
+
369
+ class TestRequiresOptionalImportClasses:
370
+ @pytest.fixture
371
+ def dummy_cls(self) -> Type[Any]:
372
+ @require_optional_import("some_optional_module", "optional_dep")
373
+ class DummyClass:
374
+ def dummy_method(self) -> None:
375
+ """Dummy method to test requires_optional_import"""
376
+ pass
377
+
378
+ @staticmethod
379
+ def dummy_static_method() -> None:
380
+ """Dummy static method to test requires_optional_import"""
381
+ pass
382
+
383
+ @classmethod
384
+ def dummy_class_method(cls) -> None:
385
+ """Dummy class method to test requires_optional_import"""
386
+ pass
387
+
388
+ @property
389
+ def dummy_property(self) -> int:
390
+ """Dummy property to test requires_optional_import"""
391
+ return 4
392
+
393
+ return DummyClass
394
+
395
+ def test_class_init_call(self, dummy_cls: Type[Any]) -> None:
396
+ with pytest.raises(
397
+ ImportError,
398
+ match=re.escape("""A module needed for __init__ is missing:
399
+ - 'some_optional_module' is not installed.
400
+ Please install it using:\n'pip install ag2[optional_dep]'"""),
401
+ ):
402
+ dummy_cls()
403
+
404
+
405
+ class TestGetMissingImports:
406
+ @pytest.mark.parametrize(
407
+ "modules, expected_missing",
408
+ [
409
+ (["module_a", "module_b", "module_c"], {}),
410
+ (["module_a>=1.0.0", "module_b>=2.0.0", "module_c>=3.0.0"], {}),
411
+ (
412
+ ["module_a>=1.0.1", "module_b>=2.0.0", "module_c>=3.0.0"],
413
+ {
414
+ "module_a": "'module_a' is installed, but the installed version 1.0.0 is too low (required 'module_a>=1.0.1')."
415
+ },
416
+ ),
417
+ (
418
+ ["module_a>=1.0.0", "module_b>=2.1.0", "module_c>=3.0.0"],
419
+ {
420
+ "module_b": "'module_b' is installed, but the installed version 2.0.0 is too low (required 'module_b>=2.1.0')."
421
+ },
422
+ ),
423
+ (
424
+ ["module_a>=1.0.0", "module_b>=2.0.0", "module_c>=3.1.0"],
425
+ {
426
+ "module_c": "'module_c' is installed, but the installed version 3.0.0 is too low (required 'module_c>=3.1.0')."
427
+ },
428
+ ),
429
+ (["module_a>=1.0.0", "module_b>=2.0.0", "module_d"], {"module_d": "'module_d' is not installed."}),
430
+ (
431
+ ["module_a>=1.0.0", "module_b>=2.0.0", "module_c<3.0.0"],
432
+ {
433
+ "module_c": "'module_c' is installed, but the installed version 3.0.0 is too high (required 'module_c<3.0.0')."
434
+ },
435
+ ),
436
+ (["module_a>=1.0.0", "module_b>=2.0.0", "module_c<=3.0.0"], {}),
437
+ (
438
+ ["module_a>=1.0.0", "module_b>=2.0.0", "module_c>3.0.0"],
439
+ {
440
+ "module_c": "'module_c' is installed, but the installed version 3.0.0 is too low (required 'module_c>3.0.0')."
441
+ },
442
+ ),
443
+ (["module_a>=1.0.0", "module_b>=2.0.0", "module_c<3.1.0"], {}),
444
+ ],
445
+ )
446
+ def test_get_missing_imports(
447
+ self, mock_modules: dict[str, MockModule], modules: Union[str, Iterable[str]], expected_missing: dict[str, str]
448
+ ) -> None:
449
+ assert mock_modules
450
+ missing = get_missing_imports(modules)
451
+ assert missing == expected_missing
@@ -1,151 +0,0 @@
1
- pyautogen==0.8.1
2
-
3
- [anthropic]
4
- pyautogen[anthropic]==0.8.1
5
-
6
- [autobuild]
7
- pyautogen[autobuild]==0.8.1
8
-
9
- [bedrock]
10
- pyautogen[bedrock]==0.8.1
11
-
12
- [blendsearch]
13
- pyautogen[blendsearch]==0.8.1
14
-
15
- [browser-use]
16
- pyautogen[browser-use]==0.8.1
17
-
18
- [captainagent]
19
- pyautogen[captainagent]==0.8.1
20
-
21
- [cerebras]
22
- pyautogen[cerebras]==0.8.1
23
-
24
- [cohere]
25
- pyautogen[cohere]==0.8.1
26
-
27
- [commsagent-discord]
28
- pyautogen[commsagent-discord]==0.8.1
29
-
30
- [commsagent-slack]
31
- pyautogen[commsagent-slack]==0.8.1
32
-
33
- [commsagent-telegram]
34
- pyautogen[commsagent-telegram]==0.8.1
35
-
36
- [cosmosdb]
37
- pyautogen[cosmosdb]==0.8.1
38
-
39
- [crawl4ai]
40
- pyautogen[crawl4ai]==0.8.1
41
-
42
- [deepseek]
43
- pyautogen[deepseek]==0.8.1
44
-
45
- [dev]
46
- pyautogen[dev]==0.8.1
47
-
48
- [docs]
49
- pyautogen[docs]==0.8.1
50
-
51
- [flaml]
52
- pyautogen[flaml]==0.8.1
53
-
54
- [gemini]
55
- pyautogen[gemini]==0.8.1
56
-
57
- [gemini-realtime]
58
- pyautogen[gemini-realtime]==0.8.1
59
-
60
- [graph]
61
- pyautogen[graph]==0.8.1
62
-
63
- [graph-rag-falkor-db]
64
- pyautogen[graph-rag-falkor-db]==0.8.1
65
-
66
- [groq]
67
- pyautogen[groq]==0.8.1
68
-
69
- [interop]
70
- pyautogen[interop]==0.8.1
71
-
72
- [interop-crewai]
73
- pyautogen[interop-crewai]==0.8.1
74
-
75
- [interop-langchain]
76
- pyautogen[interop-langchain]==0.8.1
77
-
78
- [interop-pydantic-ai]
79
- pyautogen[interop-pydantic-ai]==0.8.1
80
-
81
- [jupyter-executor]
82
- pyautogen[jupyter-executor]==0.8.1
83
-
84
- [lint]
85
- pyautogen[lint]==0.8.1
86
-
87
- [lmm]
88
- pyautogen[lmm]==0.8.1
89
-
90
- [long-context]
91
- pyautogen[long-context]==0.8.1
92
-
93
- [mathchat]
94
- pyautogen[mathchat]==0.8.1
95
-
96
- [mistral]
97
- pyautogen[mistral]==0.8.1
98
-
99
- [neo4j]
100
- pyautogen[neo4j]==0.8.1
101
-
102
- [ollama]
103
- pyautogen[ollama]==0.8.1
104
-
105
- [openai]
106
- pyautogen[openai]==0.8.1
107
-
108
- [openai-realtime]
109
- pyautogen[openai-realtime]==0.8.1
110
-
111
- [rag]
112
- pyautogen[rag]==0.8.1
113
-
114
- [redis]
115
- pyautogen[redis]==0.8.1
116
-
117
- [retrievechat]
118
- pyautogen[retrievechat]==0.8.1
119
-
120
- [retrievechat-couchbase]
121
- pyautogen[retrievechat-couchbase]==0.8.1
122
-
123
- [retrievechat-mongodb]
124
- pyautogen[retrievechat-mongodb]==0.8.1
125
-
126
- [retrievechat-pgvector]
127
- pyautogen[retrievechat-pgvector]==0.8.1
128
-
129
- [retrievechat-qdrant]
130
- pyautogen[retrievechat-qdrant]==0.8.1
131
-
132
- [teachable]
133
- pyautogen[teachable]==0.8.1
134
-
135
- [test]
136
- pyautogen[test]==0.8.1
137
-
138
- [together]
139
- pyautogen[together]==0.8.1
140
-
141
- [twilio]
142
- pyautogen[twilio]==0.8.1
143
-
144
- [types]
145
- pyautogen[types]==0.8.1
146
-
147
- [websockets]
148
- pyautogen[websockets]==0.8.1
149
-
150
- [websurfer]
151
- pyautogen[websurfer]==0.8.1
@@ -1,200 +0,0 @@
1
- # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from typing import Any, Optional, Type, Union
6
-
7
- import pytest
8
-
9
- from autogen.import_utils import optional_import_block, require_optional_import
10
-
11
-
12
- class TestOptionalImportBlock:
13
- def test_optional_import_block(self) -> None:
14
- with optional_import_block():
15
- import ast
16
-
17
- import some_module
18
- import some_other_module
19
-
20
- assert ast is not None
21
- with pytest.raises(
22
- UnboundLocalError,
23
- match=r"(local variable 'some_module' referenced before assignment|cannot access local variable 'some_module' where it is not associated with a value)",
24
- ):
25
- some_module
26
-
27
- with pytest.raises(
28
- UnboundLocalError,
29
- match=r"(local variable 'some_other_module' referenced before assignment|cannot access local variable 'some_other_module' where it is not associated with a value)",
30
- ):
31
- some_other_module
32
-
33
-
34
- class TestRequiresOptionalImportCallables:
35
- @pytest.mark.parametrize("except_for", [None, "dummy_function", ["dummy_function"]])
36
- def test_function_attributes(self, except_for: Optional[Union[str, list[str]]]) -> None:
37
- def dummy_function() -> None:
38
- """Dummy function to test requires_optional_import"""
39
- pass
40
-
41
- dummy_function.__module__ = "some_random_module.dummy_stuff"
42
-
43
- actual = require_optional_import("some_optional_module", "optional_dep", except_for=except_for)(dummy_function)
44
-
45
- assert actual is not None
46
- assert actual.__module__ == "some_random_module.dummy_stuff"
47
- assert actual.__name__ == "dummy_function"
48
- assert actual.__doc__ == "Dummy function to test requires_optional_import"
49
-
50
- if not except_for:
51
- with pytest.raises(
52
- ImportError,
53
- match=r"Module 'some_optional_module' needed for some_random_module.dummy_stuff.dummy_function is missing, please install it using 'pip install ag2\[optional_dep\]'",
54
- ):
55
- actual()
56
- else:
57
- actual()
58
-
59
- @pytest.mark.parametrize("except_for", [None, "dummy_function", ["dummy_function"]])
60
- def test_function_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
61
- @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
62
- def dummy_function() -> None:
63
- """Dummy function to test requires_optional_import"""
64
- pass
65
-
66
- if not except_for:
67
- with pytest.raises(
68
- ImportError,
69
- match=r"Module 'some_optional_module' needed for test.test_import_utils.dummy_function is missing, please install it using 'pip install ag2\[optional_dep\]'",
70
- ):
71
- dummy_function()
72
- else:
73
- dummy_function()
74
-
75
- @pytest.mark.parametrize("except_for", [None, "dummy_method", ["dummy_method"]])
76
- def test_method_attributes(self, except_for: Optional[Union[str, list[str]]]) -> None:
77
- class DummyClass:
78
- def dummy_method(self) -> None:
79
- """Dummy method to test requires_optional_import"""
80
- pass
81
-
82
- assert hasattr(DummyClass.dummy_method, "__module__")
83
- assert DummyClass.dummy_method.__module__ == "test.test_import_utils"
84
-
85
- DummyClass.__module__ = "some_random_module.dummy_stuff"
86
- DummyClass.dummy_method.__module__ = "some_random_module.dummy_stuff"
87
-
88
- DummyClass.dummy_method = require_optional_import( # type: ignore[method-assign]
89
- "some_optional_module", "optional_dep", except_for=except_for
90
- )(DummyClass.dummy_method)
91
-
92
- assert DummyClass.dummy_method is not None
93
- assert DummyClass.dummy_method.__module__ == "some_random_module.dummy_stuff"
94
- assert DummyClass.dummy_method.__name__ == "dummy_method"
95
- assert DummyClass.dummy_method.__doc__ == "Dummy method to test requires_optional_import"
96
-
97
- dummy = DummyClass()
98
-
99
- if not except_for:
100
- with pytest.raises(
101
- ImportError,
102
- match=r"Module 'some_optional_module' needed for some_random_module.dummy_stuff.dummy_method is missing, please install it using 'pip install ag2\[optional_dep\]",
103
- ):
104
- dummy.dummy_method()
105
- else:
106
- dummy.dummy_method()
107
-
108
- @pytest.mark.parametrize("except_for", [None, "dummy_method", ["dummy_method"]])
109
- def test_method_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
110
- class DummyClass:
111
- @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
112
- def dummy_method(self) -> None:
113
- """Dummy method to test requires_optional_import"""
114
- pass
115
-
116
- dummy = DummyClass()
117
-
118
- if not except_for:
119
- with pytest.raises(
120
- ImportError,
121
- match=r"Module 'some_optional_module' needed for test.test_import_utils.dummy_method is missing, please install it using 'pip install ag2\[optional_dep\]'",
122
- ):
123
- dummy.dummy_method()
124
- else:
125
- dummy.dummy_method()
126
-
127
- @pytest.mark.parametrize("except_for", [None, "dummy_static_function", ["dummy_static_function"]])
128
- def test_static_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
129
- class DummyClass:
130
- @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
131
- @staticmethod
132
- def dummy_static_function() -> None:
133
- """Dummy static function to test requires_optional_import"""
134
- pass
135
-
136
- dummy = DummyClass()
137
-
138
- if not except_for:
139
- with pytest.raises(
140
- ImportError,
141
- match=r"Module 'some_optional_module' needed for test.test_import_utils.dummy_static_function is missing, please install it using 'pip install ag2\[optional_dep\]'",
142
- ):
143
- dummy.dummy_static_function()
144
- else:
145
- dummy.dummy_static_function()
146
-
147
- @pytest.mark.parametrize("except_for", [None, "dummy_property", ["dummy_property"]])
148
- def test_property_call(self, except_for: Optional[Union[str, list[str]]]) -> None:
149
- class DummyClass:
150
- @property
151
- @require_optional_import("some_optional_module", "optional_dep", except_for=except_for)
152
- def dummy_property(self) -> int:
153
- """Dummy property to test requires_optional_import"""
154
- return 4
155
-
156
- dummy = DummyClass()
157
-
158
- if not except_for:
159
- with pytest.raises(
160
- ImportError,
161
- match=r"Module 'some_optional_module' needed for test.test_import_utils.dummy_property is missing, please install it using 'pip install ag2\[optional_dep\]'",
162
- ):
163
- dummy.dummy_property
164
-
165
- else:
166
- dummy.dummy_property
167
-
168
-
169
- class TestRequiresOptionalImportClasses:
170
- @pytest.fixture
171
- def dummy_cls(self) -> Type[Any]:
172
- @require_optional_import("some_optional_module", "optional_dep")
173
- class DummyClass:
174
- def dummy_method(self) -> None:
175
- """Dummy method to test requires_optional_import"""
176
- pass
177
-
178
- @staticmethod
179
- def dummy_static_method() -> None:
180
- """Dummy static method to test requires_optional_import"""
181
- pass
182
-
183
- @classmethod
184
- def dummy_class_method(cls) -> None:
185
- """Dummy class method to test requires_optional_import"""
186
- pass
187
-
188
- @property
189
- def dummy_property(self) -> int:
190
- """Dummy property to test requires_optional_import"""
191
- return 4
192
-
193
- return DummyClass
194
-
195
- def test_class_init_call(self, dummy_cls: Type[Any]) -> None:
196
- with pytest.raises(
197
- ImportError,
198
- match=r"Module 'some_optional_module' needed for __init__ is missing, please install it using 'pip install ag2\[optional_dep\]'",
199
- ):
200
- dummy_cls()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes