waldiez 0.4.6__py3-none-any.whl → 0.4.8__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 waldiez might be problematic. Click here for more details.

Files changed (244) hide show
  1. waldiez/__init__.py +5 -5
  2. waldiez/_version.py +1 -1
  3. waldiez/cli.py +112 -73
  4. waldiez/exporter.py +61 -19
  5. waldiez/exporting/__init__.py +25 -6
  6. waldiez/exporting/agent/__init__.py +7 -3
  7. waldiez/exporting/agent/code_execution.py +114 -0
  8. waldiez/exporting/agent/exporter.py +354 -0
  9. waldiez/exporting/agent/extras/__init__.py +15 -0
  10. waldiez/exporting/agent/extras/captain_agent_extras.py +315 -0
  11. waldiez/exporting/agent/extras/group/target.py +178 -0
  12. waldiez/exporting/agent/extras/group_manager_agent_extas.py +500 -0
  13. waldiez/exporting/agent/extras/group_member_extras.py +181 -0
  14. waldiez/exporting/agent/extras/handoffs/__init__.py +19 -0
  15. waldiez/exporting/agent/extras/handoffs/after_work.py +78 -0
  16. waldiez/exporting/agent/extras/handoffs/available.py +74 -0
  17. waldiez/exporting/agent/extras/handoffs/condition.py +158 -0
  18. waldiez/exporting/agent/extras/handoffs/handoff.py +171 -0
  19. waldiez/exporting/agent/extras/handoffs/target.py +189 -0
  20. waldiez/exporting/agent/extras/rag/__init__.py +10 -0
  21. waldiez/exporting/agent/{utils/rag_user/chroma_utils.py → extras/rag/chroma_extras.py} +16 -15
  22. waldiez/exporting/agent/{utils/rag_user/mongo_utils.py → extras/rag/mongo_extras.py} +10 -10
  23. waldiez/exporting/agent/{utils/rag_user/pgvector_utils.py → extras/rag/pgvector_extras.py} +13 -13
  24. waldiez/exporting/agent/{utils/rag_user/qdrant_utils.py → extras/rag/qdrant_extras.py} +13 -13
  25. waldiez/exporting/agent/{utils/rag_user/vector_db.py → extras/rag/vector_db_extras.py} +59 -46
  26. waldiez/exporting/agent/extras/rag_user_proxy_agent_extras.py +245 -0
  27. waldiez/exporting/agent/extras/reasoning_agent_extras.py +88 -0
  28. waldiez/exporting/agent/factory.py +95 -0
  29. waldiez/exporting/agent/processor.py +150 -0
  30. waldiez/exporting/agent/system_message.py +36 -0
  31. waldiez/exporting/agent/termination.py +50 -0
  32. waldiez/exporting/chats/__init__.py +7 -3
  33. waldiez/exporting/chats/exporter.py +97 -0
  34. waldiez/exporting/chats/factory.py +65 -0
  35. waldiez/exporting/chats/processor.py +226 -0
  36. waldiez/exporting/chats/utils/__init__.py +6 -5
  37. waldiez/exporting/chats/utils/common.py +11 -45
  38. waldiez/exporting/chats/utils/group.py +55 -0
  39. waldiez/exporting/chats/utils/nested.py +37 -52
  40. waldiez/exporting/chats/utils/sequential.py +72 -61
  41. waldiez/exporting/chats/utils/{single_chat.py → single.py} +48 -50
  42. waldiez/exporting/core/__init__.py +196 -0
  43. waldiez/exporting/core/constants.py +17 -0
  44. waldiez/exporting/core/content.py +69 -0
  45. waldiez/exporting/core/context.py +244 -0
  46. waldiez/exporting/core/enums.py +89 -0
  47. waldiez/exporting/core/errors.py +19 -0
  48. waldiez/exporting/core/exporter.py +390 -0
  49. waldiez/exporting/core/exporters.py +67 -0
  50. waldiez/exporting/core/extras/__init__.py +39 -0
  51. waldiez/exporting/core/extras/agent_extras/__init__.py +27 -0
  52. waldiez/exporting/core/extras/agent_extras/captain_extras.py +57 -0
  53. waldiez/exporting/core/extras/agent_extras/group_manager_extras.py +102 -0
  54. waldiez/exporting/core/extras/agent_extras/rag_user_extras.py +53 -0
  55. waldiez/exporting/core/extras/agent_extras/reasoning_extras.py +68 -0
  56. waldiez/exporting/core/extras/agent_extras/standard_extras.py +263 -0
  57. waldiez/exporting/core/extras/base.py +241 -0
  58. waldiez/exporting/core/extras/chat_extras.py +118 -0
  59. waldiez/exporting/core/extras/flow_extras.py +70 -0
  60. waldiez/exporting/core/extras/model_extras.py +73 -0
  61. waldiez/exporting/core/extras/path_resolver.py +93 -0
  62. waldiez/exporting/core/extras/serializer.py +138 -0
  63. waldiez/exporting/core/extras/tool_extras.py +82 -0
  64. waldiez/exporting/core/protocols.py +259 -0
  65. waldiez/exporting/core/result.py +705 -0
  66. waldiez/exporting/core/types.py +329 -0
  67. waldiez/exporting/core/utils/__init__.py +11 -0
  68. waldiez/exporting/core/utils/comment.py +33 -0
  69. waldiez/exporting/core/utils/llm_config.py +117 -0
  70. waldiez/exporting/core/validation.py +96 -0
  71. waldiez/exporting/flow/__init__.py +6 -2
  72. waldiez/exporting/flow/execution_generator.py +193 -0
  73. waldiez/exporting/flow/exporter.py +107 -0
  74. waldiez/exporting/flow/factory.py +94 -0
  75. waldiez/exporting/flow/file_generator.py +214 -0
  76. waldiez/exporting/flow/merger.py +387 -0
  77. waldiez/exporting/flow/orchestrator.py +411 -0
  78. waldiez/exporting/flow/utils/__init__.py +9 -36
  79. waldiez/exporting/flow/utils/common.py +206 -0
  80. waldiez/exporting/flow/utils/importing.py +373 -0
  81. waldiez/exporting/flow/utils/linting.py +200 -0
  82. waldiez/exporting/flow/utils/{logging_utils.py → logging.py} +23 -9
  83. waldiez/exporting/models/__init__.py +3 -1
  84. waldiez/exporting/models/exporter.py +233 -0
  85. waldiez/exporting/models/factory.py +66 -0
  86. waldiez/exporting/models/processor.py +139 -0
  87. waldiez/exporting/tools/__init__.py +11 -0
  88. waldiez/exporting/tools/exporter.py +207 -0
  89. waldiez/exporting/tools/factory.py +57 -0
  90. waldiez/exporting/tools/processor.py +248 -0
  91. waldiez/exporting/tools/registration.py +133 -0
  92. waldiez/io/__init__.py +128 -0
  93. waldiez/io/_ws.py +199 -0
  94. waldiez/io/models/__init__.py +60 -0
  95. waldiez/io/models/base.py +66 -0
  96. waldiez/io/models/constants.py +78 -0
  97. waldiez/io/models/content/__init__.py +23 -0
  98. waldiez/io/models/content/audio.py +43 -0
  99. waldiez/io/models/content/base.py +45 -0
  100. waldiez/io/models/content/file.py +43 -0
  101. waldiez/io/models/content/image.py +96 -0
  102. waldiez/io/models/content/text.py +37 -0
  103. waldiez/io/models/content/video.py +43 -0
  104. waldiez/io/models/user_input.py +269 -0
  105. waldiez/io/models/user_response.py +215 -0
  106. waldiez/io/mqtt.py +681 -0
  107. waldiez/io/redis.py +782 -0
  108. waldiez/io/structured.py +419 -0
  109. waldiez/io/utils.py +184 -0
  110. waldiez/io/ws.py +298 -0
  111. waldiez/logger.py +481 -0
  112. waldiez/models/__init__.py +108 -51
  113. waldiez/models/agents/__init__.py +34 -70
  114. waldiez/models/agents/agent/__init__.py +10 -4
  115. waldiez/models/agents/agent/agent.py +466 -65
  116. waldiez/models/agents/agent/agent_data.py +119 -47
  117. waldiez/models/agents/agent/agent_type.py +13 -2
  118. waldiez/models/agents/agent/code_execution.py +12 -12
  119. waldiez/models/agents/agent/human_input_mode.py +8 -0
  120. waldiez/models/agents/agent/{linked_skill.py → linked_tool.py} +7 -7
  121. waldiez/models/agents/agent/nested_chat.py +35 -7
  122. waldiez/models/agents/agent/termination_message.py +30 -22
  123. waldiez/models/agents/{swarm_agent → agent}/update_system_message.py +22 -22
  124. waldiez/models/agents/agents.py +58 -63
  125. waldiez/models/agents/assistant/assistant.py +4 -4
  126. waldiez/models/agents/assistant/assistant_data.py +13 -1
  127. waldiez/models/agents/{captain_agent → captain}/captain_agent.py +5 -5
  128. waldiez/models/agents/{captain_agent → captain}/captain_agent_data.py +5 -5
  129. waldiez/models/agents/extra_requirements.py +11 -16
  130. waldiez/models/agents/group_manager/group_manager.py +103 -13
  131. waldiez/models/agents/group_manager/group_manager_data.py +36 -14
  132. waldiez/models/agents/group_manager/speakers.py +77 -24
  133. waldiez/models/agents/{rag_user → rag_user_proxy}/__init__.py +16 -16
  134. waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +64 -0
  135. waldiez/models/agents/{rag_user/rag_user_data.py → rag_user_proxy/rag_user_proxy_data.py} +6 -5
  136. waldiez/models/agents/{rag_user → rag_user_proxy}/retrieve_config.py +182 -114
  137. waldiez/models/agents/{rag_user → rag_user_proxy}/vector_db_config.py +13 -13
  138. waldiez/models/agents/reasoning/reasoning_agent.py +6 -6
  139. waldiez/models/agents/reasoning/reasoning_agent_data.py +110 -63
  140. waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +38 -10
  141. waldiez/models/agents/user_proxy/user_proxy.py +11 -7
  142. waldiez/models/agents/user_proxy/user_proxy_data.py +2 -2
  143. waldiez/models/chat/__init__.py +2 -1
  144. waldiez/models/chat/chat.py +166 -87
  145. waldiez/models/chat/chat_data.py +99 -136
  146. waldiez/models/chat/chat_message.py +33 -23
  147. waldiez/models/chat/chat_nested.py +31 -30
  148. waldiez/models/chat/chat_summary.py +10 -8
  149. waldiez/models/common/__init__.py +52 -2
  150. waldiez/models/common/ag2_version.py +1 -1
  151. waldiez/models/common/base.py +38 -7
  152. waldiez/models/common/dict_utils.py +42 -17
  153. waldiez/models/common/handoff.py +459 -0
  154. waldiez/models/common/id_generator.py +19 -0
  155. waldiez/models/common/method_utils.py +130 -68
  156. waldiez/{exporting/base/utils → models/common}/naming.py +38 -61
  157. waldiez/models/common/waldiez_version.py +37 -0
  158. waldiez/models/flow/__init__.py +9 -2
  159. waldiez/models/flow/connection.py +18 -0
  160. waldiez/models/flow/flow.py +311 -215
  161. waldiez/models/flow/flow_data.py +207 -40
  162. waldiez/models/flow/info.py +85 -0
  163. waldiez/models/flow/naming.py +131 -0
  164. waldiez/models/model/__init__.py +7 -1
  165. waldiez/models/model/extra_requirements.py +3 -12
  166. waldiez/models/model/model.py +76 -21
  167. waldiez/models/model/model_data.py +108 -20
  168. waldiez/models/tool/__init__.py +16 -0
  169. waldiez/models/tool/extra_requirements.py +36 -0
  170. waldiez/models/{skill/skill.py → tool/tool.py} +88 -88
  171. waldiez/models/tool/tool_data.py +51 -0
  172. waldiez/models/tool/tool_type.py +8 -0
  173. waldiez/models/waldiez.py +97 -80
  174. waldiez/runner.py +114 -49
  175. waldiez/running/__init__.py +1 -1
  176. waldiez/running/environment.py +49 -68
  177. waldiez/running/gen_seq_diagram.py +16 -14
  178. waldiez/running/running.py +53 -34
  179. waldiez/utils/__init__.py +0 -4
  180. waldiez/utils/cli_extras/jupyter.py +5 -3
  181. waldiez/utils/cli_extras/runner.py +6 -4
  182. waldiez/utils/cli_extras/studio.py +6 -4
  183. waldiez/utils/conflict_checker.py +15 -9
  184. waldiez/utils/flaml_warnings.py +5 -5
  185. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/METADATA +235 -91
  186. waldiez-0.4.8.dist-info/RECORD +200 -0
  187. waldiez/exporting/agent/agent_exporter.py +0 -297
  188. waldiez/exporting/agent/utils/__init__.py +0 -23
  189. waldiez/exporting/agent/utils/captain_agent.py +0 -263
  190. waldiez/exporting/agent/utils/code_execution.py +0 -65
  191. waldiez/exporting/agent/utils/group_manager.py +0 -220
  192. waldiez/exporting/agent/utils/rag_user/__init__.py +0 -7
  193. waldiez/exporting/agent/utils/rag_user/rag_user.py +0 -209
  194. waldiez/exporting/agent/utils/reasoning.py +0 -36
  195. waldiez/exporting/agent/utils/swarm_agent.py +0 -469
  196. waldiez/exporting/agent/utils/teachability.py +0 -41
  197. waldiez/exporting/agent/utils/termination_message.py +0 -44
  198. waldiez/exporting/base/__init__.py +0 -25
  199. waldiez/exporting/base/agent_position.py +0 -75
  200. waldiez/exporting/base/base_exporter.py +0 -118
  201. waldiez/exporting/base/export_position.py +0 -48
  202. waldiez/exporting/base/import_position.py +0 -23
  203. waldiez/exporting/base/mixin.py +0 -137
  204. waldiez/exporting/base/utils/__init__.py +0 -18
  205. waldiez/exporting/base/utils/comments.py +0 -96
  206. waldiez/exporting/base/utils/path_check.py +0 -68
  207. waldiez/exporting/base/utils/to_string.py +0 -84
  208. waldiez/exporting/chats/chats_exporter.py +0 -240
  209. waldiez/exporting/chats/utils/swarm.py +0 -210
  210. waldiez/exporting/flow/flow_exporter.py +0 -528
  211. waldiez/exporting/flow/utils/agent_utils.py +0 -204
  212. waldiez/exporting/flow/utils/chat_utils.py +0 -71
  213. waldiez/exporting/flow/utils/def_main.py +0 -77
  214. waldiez/exporting/flow/utils/flow_content.py +0 -202
  215. waldiez/exporting/flow/utils/flow_names.py +0 -116
  216. waldiez/exporting/flow/utils/importing_utils.py +0 -227
  217. waldiez/exporting/models/models_exporter.py +0 -199
  218. waldiez/exporting/models/utils.py +0 -174
  219. waldiez/exporting/skills/__init__.py +0 -9
  220. waldiez/exporting/skills/skills_exporter.py +0 -176
  221. waldiez/exporting/skills/utils.py +0 -369
  222. waldiez/models/agents/agent/teachability.py +0 -70
  223. waldiez/models/agents/rag_user/rag_user.py +0 -60
  224. waldiez/models/agents/swarm_agent/__init__.py +0 -50
  225. waldiez/models/agents/swarm_agent/after_work.py +0 -179
  226. waldiez/models/agents/swarm_agent/on_condition.py +0 -105
  227. waldiez/models/agents/swarm_agent/on_condition_available.py +0 -142
  228. waldiez/models/agents/swarm_agent/on_condition_target.py +0 -40
  229. waldiez/models/agents/swarm_agent/swarm_agent.py +0 -107
  230. waldiez/models/agents/swarm_agent/swarm_agent_data.py +0 -124
  231. waldiez/models/flow/utils.py +0 -232
  232. waldiez/models/skill/__init__.py +0 -16
  233. waldiez/models/skill/extra_requirements.py +0 -36
  234. waldiez/models/skill/skill_data.py +0 -53
  235. waldiez/models/skill/skill_type.py +0 -8
  236. waldiez/utils/pysqlite3_checker.py +0 -308
  237. waldiez/utils/rdps_checker.py +0 -122
  238. waldiez-0.4.6.dist-info/RECORD +0 -149
  239. /waldiez/models/agents/{captain_agent → captain}/__init__.py +0 -0
  240. /waldiez/models/agents/{captain_agent → captain}/captain_agent_lib_entry.py +0 -0
  241. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/WHEEL +0 -0
  242. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/entry_points.txt +0 -0
  243. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/licenses/LICENSE +0 -0
  244. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/licenses/NOTICE.md +0 -0
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
- """Common utility functions."""
3
+ """Running related functions."""
4
4
 
5
5
  from .environment import (
6
6
  in_virtualenv,
@@ -3,12 +3,9 @@
3
3
  # pylint: disable=import-outside-toplevel,reimported
4
4
  """Environment related utilities."""
5
5
 
6
- import importlib
7
6
  import os
8
- import site
9
7
  import sys
10
- import warnings
11
- from typing import Dict, Generator, List, Tuple
8
+ from typing import Generator
12
9
 
13
10
 
14
11
  def in_virtualenv() -> bool:
@@ -25,7 +22,7 @@ def in_virtualenv() -> bool:
25
22
  )
26
23
 
27
24
 
28
- def is_root() -> bool:
25
+ def is_root() -> bool: # pragma: no cover # os specific
29
26
  """Check if the script is running as root/administrator.
30
27
 
31
28
  Returns
@@ -33,13 +30,15 @@ def is_root() -> bool:
33
30
  bool
34
31
  True if running as root/administrator, False otherwise.
35
32
  """
36
- # pylint: disable=import-outside-toplevel,line-too-long
33
+ # pylint: disable=import-outside-toplevel,line-too-long,no-member
37
34
  if os.name == "nt":
35
+ # noinspection PyBroadException
36
+ # pylint: disable=broad-exception-caught
38
37
  try:
39
38
  import ctypes
40
39
 
41
40
  return ctypes.windll.shell32.IsUserAnAdmin() != 0 # type: ignore[unused-ignore,attr-defined] # noqa: E501
42
- except Exception: # pylint: disable=broad-exception-caught
41
+ except Exception:
43
42
  return False
44
43
  else:
45
44
  return os.getuid() == 0
@@ -47,75 +46,57 @@ def is_root() -> bool:
47
46
 
48
47
  def refresh_environment() -> None:
49
48
  """Refresh the environment."""
50
- with warnings.catch_warnings():
51
- warnings.filterwarnings(
52
- "ignore",
53
- module="flaml",
54
- message="^.*flaml.automl is not available.*$",
55
- )
56
- from autogen.io import IOStream # type: ignore
57
-
58
- default_io_stream = IOStream.get_default()
59
- site.main()
60
- # pylint: disable=import-outside-toplevel
61
- modules_to_reload = [mod for mod in sys.modules if "autogen" in mod]
62
- for mod in modules_to_reload:
63
- del sys.modules[mod]
64
- import autogen # type: ignore
65
- from autogen.io import IOStream
66
-
67
- importlib.reload(autogen)
68
- # restore the default IOStream
69
- IOStream.set_global_default(default_io_stream)
70
- # reload any other modules that may have been affected
71
- for mod in modules_to_reload:
72
- if mod not in sys.modules:
73
- importlib.import_module(mod)
74
- # a swarm chat without a user agent
75
- # creates a new user (this has a default code execution with docker)
76
- # captain also generates new agents that also have
77
- # default code execution with docker
78
- # temp (until we handle/detect docker setup)
79
- os.environ["AUTOGEN_USE_DOCKER"] = "0"
80
- # we might get:
81
- # module 'numpy' has no attribute '_no_nep50_warning'
82
- # in autogen/agentchat/contrib/captainagent/tool_retriever.py
83
- os.environ["NEP50_DEPRECATION_WARNING"] = "0"
84
- os.environ["NEP50_DISABLE_WARNING"] = "1"
85
- os.environ["NPY_PROMOTION_STATE"] = "weak"
86
- import numpy as np
87
-
88
- if not hasattr(np, "_no_pep50_warning"):
89
- import contextlib
90
-
91
- @contextlib.contextmanager
92
- def _np_no_nep50_warning() -> Generator[None, None, None]:
93
- """Avoid no_nep50 warning.
94
-
95
- Yields
96
- ------
97
- None
98
- Dummy value.
99
- """
100
- yield
101
-
102
- setattr(np, "_no_pep50_warning", _np_no_nep50_warning) # noqa
103
-
104
-
105
- def set_env_vars(flow_env_vars: List[Tuple[str, str]]) -> Dict[str, str]:
49
+ # a group chat without a user agent
50
+ # creates a new user (this has a default code execution with docker)
51
+ # captain also generates new agents that also have
52
+ # default code execution with docker
53
+ # temp (until we handle/detect docker setup)
54
+ os.environ["AUTOGEN_USE_DOCKER"] = "0"
55
+ try_handle_the_np_thing()
56
+
57
+
58
+ def try_handle_the_np_thing() -> None:
59
+ """Try to handle the numpy deprecation warning."""
60
+ # we might get:
61
+ # module 'numpy' has no attribute '_no_nep50_warning'
62
+ # (sentnence_transformers?)
63
+ # in autogen/agentchat/contrib/captainagent/tool_retriever.py
64
+ os.environ["NEP50_DEPRECATION_WARNING"] = "0"
65
+ os.environ["NEP50_DISABLE_WARNING"] = "1"
66
+ os.environ["NPY_PROMOTION_STATE"] = "weak"
67
+ import numpy as np
68
+
69
+ if not hasattr(np, "_no_pep50_warning"):
70
+ import contextlib
71
+
72
+ @contextlib.contextmanager
73
+ def _np_no_nep50_warning() -> Generator[None, None, None]:
74
+ """Avoid no_nep50 warning.
75
+
76
+ Yields
77
+ ------
78
+ None
79
+ Nothing.
80
+ """
81
+ yield # pragma: no cover
82
+
83
+ setattr(np, "_no_pep50_warning", _np_no_nep50_warning) # noqa
84
+
85
+
86
+ def set_env_vars(flow_env_vars: list[tuple[str, str]]) -> dict[str, str]:
106
87
  """Set environment variables and return the old ones (if any).
107
88
 
108
89
  Parameters
109
90
  ----------
110
- flow_env_vars : List[Tuple[str, str]]
91
+ flow_env_vars : list[tuple[str, str]]
111
92
  The environment variables to set.
112
93
 
113
94
  Returns
114
95
  -------
115
- Dict[str, str]
96
+ dict[str, str]
116
97
  The old environment variables.
117
98
  """
118
- old_vars: Dict[str, str] = {}
99
+ old_vars: dict[str, str] = {}
119
100
  for var_key, var_value in flow_env_vars:
120
101
  if var_key:
121
102
  current = os.environ.get(var_key, "")
@@ -124,12 +105,12 @@ def set_env_vars(flow_env_vars: List[Tuple[str, str]]) -> Dict[str, str]:
124
105
  return old_vars
125
106
 
126
107
 
127
- def reset_env_vars(old_vars: Dict[str, str]) -> None:
108
+ def reset_env_vars(old_vars: dict[str, str]) -> None:
128
109
  """Reset the environment variables.
129
110
 
130
111
  Parameters
131
112
  ----------
132
- old_vars : Dict[str, str]
113
+ old_vars : dict[str, str]
133
114
  The old environment variables.
134
115
  """
135
116
  for var_key, var_value in old_vars.items():
@@ -5,7 +5,7 @@
5
5
  import json
6
6
  import re
7
7
  from pathlib import Path
8
- from typing import Any, Dict, Set, Union
8
+ from typing import Any, Set, Union
9
9
 
10
10
  import pandas as pd
11
11
 
@@ -38,7 +38,7 @@ def escape_mermaid_text(text: str) -> str:
38
38
  return output
39
39
 
40
40
 
41
- def get_json_state(json_state: Any) -> Dict[str, Any]:
41
+ def get_json_state(json_state: Any) -> dict[str, Any]:
42
42
  """Get the JSON state of the event.
43
43
 
44
44
  Parameters
@@ -52,7 +52,7 @@ def get_json_state(json_state: Any) -> Dict[str, Any]:
52
52
  The JSON state of the event.
53
53
  """
54
54
  if isinstance(json_state, dict):
55
- return json_state
55
+ return json_state # pyright: ignore
56
56
  if isinstance(json_state, str):
57
57
  try:
58
58
  return json.loads(json_state)
@@ -68,7 +68,7 @@ def process_events(df_events: pd.DataFrame) -> str:
68
68
  Parameters
69
69
  ----------
70
70
  df_events : pd.DataFrame
71
- The DataFrame containing the events data.
71
+ The DataFrame containing the events' data.
72
72
 
73
73
  Returns
74
74
  -------
@@ -83,7 +83,7 @@ def process_events(df_events: pd.DataFrame) -> str:
83
83
  seq_text = SEQ_TXT
84
84
 
85
85
  # Loop through each event in the DataFrame
86
- for i in range(len(df_events["json_state"])):
86
+ for i in range(len(df_events["json_state"])): # pyright: ignore
87
87
  # Parse the JSON state of the event
88
88
  df_j = get_json_state(df_events["json_state"][i])
89
89
  # Skip events that are not relevant (e.g., replies or missing messages)
@@ -91,26 +91,28 @@ def process_events(df_events: pd.DataFrame) -> str:
91
91
  df_events["event_name"][i] != "reply_func_executed"
92
92
  ):
93
93
  sender = df_j["sender"]
94
- recipient = df_events["source_name"][i]
94
+ # noinspection PyTypeChecker
95
+ recipient = df_events["source_name"][i] # pyright: ignore
95
96
 
96
97
  # Extract message content if available
97
98
  if (
98
99
  isinstance(df_j["message"], dict)
99
100
  and "content" in df_j["message"]
100
101
  ):
101
- message = "Content: " + str(df_j["message"]["content"])
102
+ content = str(df_j["message"]["content"]) # pyright: ignore
103
+ message = "Content: " + content
102
104
  else:
103
- message = str(df_j["message"])
105
+ message = str(df_j["message"]) # pyright: ignore
104
106
 
105
107
  # Escape the message for Mermaid compatibility and
106
108
  # truncate long messages
107
109
  message = escape_mermaid_text(message)
108
110
 
109
111
  # Add sender and recipient to participants set
110
- participants.add(recipient)
112
+ participants.add(recipient) # pyright: ignore
111
113
  participants.add(sender)
112
114
 
113
- # Split message into main message and context
115
+ # Split into the main message and the context
114
116
  # if "Content" is present
115
117
  if "Content: " in message:
116
118
  message_parts = message.split("Content: ")
@@ -155,7 +157,7 @@ def generate_sequence_diagram(
155
157
  Parameters
156
158
  ----------
157
159
  file_path : Union[str, Path]
158
- The path to the JSON or CSV file containing the events data.
160
+ The path to the JSON or CSV file containing the events' data.
159
161
  output_path : Union[str, Path]
160
162
  The path to save the Mermaid diagram.
161
163
 
@@ -176,10 +178,10 @@ def generate_sequence_diagram(
176
178
  is_csv = file_path.suffix == ".csv"
177
179
  try:
178
180
  if is_csv:
179
- df_events = pd.read_csv(file_path)
181
+ df_events = pd.read_csv(file_path) # pyright: ignore
180
182
  else:
181
- df_events = pd.read_json(file_path)
182
- except pd.errors.EmptyDataError:
183
+ df_events = pd.read_json(file_path) # pyright: ignore
184
+ except pd.errors.EmptyDataError: # pragma: no cover
183
185
  return
184
186
 
185
187
  # Generate the Mermaid sequence diagram text
@@ -6,20 +6,20 @@ import asyncio
6
6
  import datetime
7
7
  import io
8
8
  import os
9
+ import re
9
10
  import shutil
10
11
  import subprocess
11
12
  import sys
12
13
  import tempfile
13
- import warnings
14
14
  from contextlib import asynccontextmanager, contextmanager
15
15
  from pathlib import Path
16
16
  from typing import (
17
+ Any,
17
18
  AsyncIterator,
18
19
  Callable,
19
20
  Iterator,
20
21
  Optional,
21
22
  Set,
22
- Tuple,
23
23
  Union,
24
24
  )
25
25
 
@@ -73,6 +73,23 @@ async def a_chdir(to: Union[str, Path]) -> AsyncIterator[None]:
73
73
  os.chdir(old_cwd)
74
74
 
75
75
 
76
+ def strip_ansi(text: str) -> str:
77
+ """Remove ANSI escape sequences from text.
78
+
79
+ Parameters
80
+ ----------
81
+ text : str
82
+ The text to strip.
83
+
84
+ Returns
85
+ -------
86
+ str
87
+ The text without ANSI escape sequences.
88
+ """
89
+ ansi_pattern = re.compile(r"\x1b\[[0-9;]*m|\x1b\[.*?[@-~]")
90
+ return ansi_pattern.sub("", text)
91
+
92
+
76
93
  def before_run(
77
94
  output_path: Optional[Union[str, Path]],
78
95
  uploads_root: Optional[Union[str, Path]],
@@ -120,9 +137,10 @@ def install_requirements(
120
137
  requirements_string = ", ".join(extra_requirements)
121
138
  printer(f"Installing requirements: {requirements_string}")
122
139
  pip_install = [sys.executable, "-m", "pip", "install"]
140
+ break_system_packages = ""
123
141
  if not in_virtualenv(): # it should
124
142
  # if not, let's try to install as user
125
- # not sure if --break-system-packages is safe
143
+ # not sure if --break-system-packages is safe,
126
144
  # but it might fail if we don't
127
145
  break_system_packages = os.environ.get("PIP_BREAK_SYSTEM_PACKAGES", "")
128
146
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
@@ -138,10 +156,10 @@ def install_requirements(
138
156
  ) as proc:
139
157
  if proc.stdout:
140
158
  for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
141
- printer(line.strip())
159
+ printer(strip_ansi(line.strip()))
142
160
  if proc.stderr:
143
161
  for line in io.TextIOWrapper(proc.stderr, encoding="utf-8"):
144
- printer(line.strip())
162
+ printer(strip_ansi(line.strip()))
145
163
  finally:
146
164
  if not in_virtualenv():
147
165
  # restore the old env var
@@ -166,10 +184,12 @@ async def a_install_requirements(
166
184
  requirements_string = ", ".join(extra_requirements)
167
185
  printer(f"Installing requirements: {requirements_string}")
168
186
  pip_install = [sys.executable, "-m", "pip", "install"]
187
+ break_system_packages = ""
169
188
  if not in_virtualenv():
170
189
  break_system_packages = os.environ.get("PIP_BREAK_SYSTEM_PACKAGES", "")
171
190
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
172
- pip_install.extend(["--user"])
191
+ if not is_root():
192
+ pip_install.extend(["--user"])
173
193
  pip_install.extend(extra_requirements)
174
194
  # pylint: disable=too-many-try-statements
175
195
  try:
@@ -180,10 +200,10 @@ async def a_install_requirements(
180
200
  )
181
201
  if proc.stdout:
182
202
  async for line in proc.stdout:
183
- printer(line.decode().strip())
203
+ printer(strip_ansi(line.decode().strip()))
184
204
  if proc.stderr:
185
205
  async for line in proc.stderr:
186
- printer(line.decode().strip())
206
+ printer(strip_ansi(line.decode().strip()))
187
207
  finally:
188
208
  if not in_virtualenv():
189
209
  if break_system_packages:
@@ -213,7 +233,7 @@ def after_run(
213
233
  The flow name.
214
234
  skip_mmd : bool, optional
215
235
  Whether to skip the mermaid sequence diagram generation,
216
- by default False
236
+ by default, False
217
237
  """
218
238
  if isinstance(output_path, str):
219
239
  output_path = Path(output_path)
@@ -276,7 +296,7 @@ def copy_results(
276
296
  ):
277
297
  continue
278
298
  if item.is_file():
279
- # let's also copy the tree of thoughts image
299
+ # let's also copy the "tree of thoughts" image
280
300
  # to the output directory
281
301
  if item.name.endswith("tree_of_thoughts.png") or item.name.endswith(
282
302
  "reasoning_tree.json"
@@ -305,54 +325,53 @@ def get_printer() -> Callable[..., None]:
305
325
  Callable[..., None]
306
326
  The printer function.
307
327
  """
308
- with warnings.catch_warnings():
309
- warnings.filterwarnings(
310
- "ignore",
311
- module="flaml",
312
- message="^.*flaml.automl is not available.*$",
313
- )
314
- from autogen.io import IOStream # type: ignore
328
+ from autogen.io import IOStream # type: ignore
315
329
 
330
+ # noinspection PyUnboundLocalVariable
316
331
  printer = IOStream.get_default().print
317
332
 
318
- def safe_printer(*args: object, **kwargs: object) -> None:
333
+ def safe_printer(*args: Any, **kwargs: Any) -> None:
319
334
  try:
320
335
  printer(*args, **kwargs)
321
336
  except UnicodeEncodeError:
322
- # pylint: disable=too-many-try-statements
323
337
  try:
324
- msg, flush = get_what_to_print(*args, **kwargs)
325
- printer(msg, end="", flush=flush)
338
+ # Use the helper to get safely encoded message
339
+ safe_msg, flush = get_what_to_print(*args, **kwargs)
340
+ # Try printing the safe message
341
+ # (without end since it's already included)
342
+ printer(safe_msg, end="", flush=flush)
326
343
  except UnicodeEncodeError:
327
- sys.stdout = io.TextIOWrapper(
328
- sys.stdout.buffer, encoding="utf-8"
329
- )
330
- sys.stderr = io.TextIOWrapper(
331
- sys.stderr.buffer, encoding="utf-8"
332
- )
344
+ # pylint: disable=too-many-try-statements
333
345
  try:
334
- printer(*args, **kwargs)
335
- except UnicodeEncodeError:
336
- sys.stderr.write(
337
- "Could not print the message due to encoding issues.\n"
346
+ # If that still fails, write directly to buffer
347
+ msg, flush = get_what_to_print(*args, **kwargs)
348
+ safe_msg_bytes = msg.encode("utf-8", errors="replace")
349
+ sys.stdout.buffer.write(safe_msg_bytes)
350
+ if flush:
351
+ sys.stdout.buffer.flush()
352
+ except Exception: # pylint: disable=broad-exception-caught
353
+ error_msg = (
354
+ b"Could not print message due to encoding issues.\n"
338
355
  )
356
+ sys.stderr.buffer.write(error_msg)
357
+ sys.stderr.buffer.flush()
339
358
 
340
359
  return safe_printer
341
360
 
342
361
 
343
- def get_what_to_print(*args: object, **kwargs: object) -> Tuple[str, bool]:
362
+ def get_what_to_print(*args: object, **kwargs: object) -> tuple[str, bool]:
344
363
  """Get what to print.
345
364
 
346
365
  Parameters
347
366
  ----------
348
367
  args : object
349
- The arguments.
368
+ The print arguments.
350
369
  kwargs : object
351
370
  The keyword arguments.
352
371
 
353
372
  Returns
354
373
  -------
355
- Tuple[str, bool]
374
+ tuple[str, bool]
356
375
  The message and whether to flush.
357
376
  """
358
377
  sep = kwargs.get("sep", " ")
waldiez/utils/__init__.py CHANGED
@@ -5,13 +5,9 @@
5
5
  from .cli_extras import add_cli_extras
6
6
  from .conflict_checker import check_conflicts
7
7
  from .flaml_warnings import check_flaml_warnings
8
- from .pysqlite3_checker import check_pysqlite3
9
- from .rdps_checker import check_rpds_py
10
8
 
11
9
  __all__ = [
12
10
  "check_conflicts",
13
11
  "check_flaml_warnings",
14
12
  "add_cli_extras",
15
- "check_pysqlite3",
16
- "check_rpds_py",
17
13
  ]
@@ -11,12 +11,14 @@ import typer
11
11
  from typer.models import CommandInfo
12
12
  import subprocess # nosemgrep # nosec
13
13
 
14
- HAVE_JUPYTER = False
14
+ _have_jupyter = False
15
15
 
16
+ # noinspection PyBroadException
17
+ # pylint: disable=broad-exception-caught
16
18
  try:
17
19
  import waldiez_jupyter # type: ignore[unused-ignore, unused-import, import-not-found, import-untyped] # noqa
18
20
 
19
- HAVE_JUPYTER = True
21
+ _have_jupyter = True
20
22
  except BaseException:
21
23
  pass
22
24
 
@@ -34,7 +36,7 @@ def add_jupyter_cli(app: typer.Typer) -> None:
34
36
  typer.Typer
35
37
  The app with the extra command added
36
38
  """
37
- if HAVE_JUPYTER:
39
+ if _have_jupyter:
38
40
  jupyter_app = get_jupyter_app()
39
41
  app.registered_commands.append(
40
42
  CommandInfo(name="lab", callback=jupyter_app)
@@ -10,15 +10,17 @@ from typing import Any, Callable
10
10
  import typer
11
11
  from typer.models import CommandInfo
12
12
 
13
- HAVE_RUNNER = False
13
+ _have_runner = False
14
14
  runner_app: Callable[..., Any] | None = None
15
15
 
16
+ # noinspection PyBroadException
17
+ # pylint: disable=broad-exception-caught
16
18
  try:
17
19
  from waldiez_runner.cli import run # type: ignore[unused-ignore, import-not-found, import-untyped]
18
20
 
19
- runner_app = run
21
+ runner_app = run # pyright: ignore
20
22
 
21
- HAVE_RUNNER = True
23
+ _have_runner = True
22
24
  except BaseException:
23
25
  pass
24
26
 
@@ -31,7 +33,7 @@ def add_runner_cli(app: typer.Typer) -> None:
31
33
  app : typer.Typer
32
34
  The Typer app to add the runner command to.
33
35
  """
34
- if HAVE_RUNNER:
36
+ if _have_runner:
35
37
  app.registered_commands.append(
36
38
  CommandInfo(name="serve", callback=runner_app)
37
39
  )
@@ -10,15 +10,17 @@ from typing import Any, Callable
10
10
  import typer
11
11
  from typer.models import CommandInfo
12
12
 
13
- HAVE_STUDIO = False
13
+ _have_studio = False
14
14
  studio_app: Callable[..., Any] | None = None
15
15
 
16
+ # noinspection PyBroadException
17
+ # pylint: disable=broad-exception-caught
16
18
  try:
17
19
  from waldiez_studio.cli import run # type: ignore[unused-ignore, import-not-found, import-untyped]
18
20
 
19
- studio_app = run
21
+ studio_app = run # pyright: ignore
20
22
 
21
- HAVE_STUDIO = True
23
+ _have_studio = True
22
24
  except BaseException:
23
25
  pass
24
26
 
@@ -31,7 +33,7 @@ def add_studio_cli(app: typer.Typer) -> None:
31
33
  app : typer.Typer
32
34
  The Typer app to add the studio command to.
33
35
  """
34
- if HAVE_STUDIO:
36
+ if _have_studio:
35
37
  app.registered_commands.append(
36
38
  CommandInfo(name="studio", callback=studio_app)
37
39
  )
@@ -1,17 +1,18 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
- # pylint: disable=line-too-long
4
- """Check for conflicts with 'autogen-agentchat' package."""
3
+ # pylint: disable=line-too-long, broad-exception-caught,invalid-name
4
+ # pylint: disable=too-many-try-statements
5
+ """Check for conflicts between Waldiez and other packages."""
5
6
 
6
7
  import sys
7
8
  from importlib.metadata import PackageNotFoundError, version
8
9
 
9
- __WALDIEZ_CHECKED_FOR_CONFLICTS = False
10
+ # Global variable to track if conflicts have been checked
11
+ __waldiez_checked_conflicts = False
10
12
 
11
13
 
12
14
  # fmt: off
13
- def _check_conflicts() -> None: # pragma: no cover
14
- """Check for conflicts with 'autogen-agentchat' package."""
15
+ def _check_autogen_agentchat() -> None: # pragma: no cover
15
16
  try:
16
17
  version("autogen-agentchat")
17
18
  print(
@@ -30,10 +31,15 @@ def _check_conflicts() -> None: # pragma: no cover
30
31
  # fmt: on
31
32
 
32
33
 
34
+ def _check_conflicts() -> None: # pragma: no cover
35
+ """Check for conflicts."""
36
+ _check_autogen_agentchat()
37
+
38
+
33
39
  def check_conflicts() -> None: # pragma: no cover
34
- """Check for conflicts with 'autogen-agentchat' package."""
40
+ """Check for conflicts."""
35
41
  # pylint: disable=global-statement
36
- global __WALDIEZ_CHECKED_FOR_CONFLICTS
37
- if __WALDIEZ_CHECKED_FOR_CONFLICTS is False:
42
+ global __waldiez_checked_conflicts
43
+ if __waldiez_checked_conflicts is False:
44
+ __waldiez_checked_conflicts = True
38
45
  _check_conflicts()
39
- __WALDIEZ_CHECKED_FOR_CONFLICTS = True
@@ -1,17 +1,17 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
- """Try to suppress the annoying flaml.automl not being available warning."""
3
+ """Try to suppress the warning about flaml.automl not being available."""
4
4
 
5
5
  import logging
6
6
 
7
- __WALDIEZ_CHECKED_FLAML_WARNINGS = False
7
+ __waldiez_checked_flaml_warnings = False # pylint: disable=invalid-name
8
8
 
9
9
 
10
10
  def check_flaml_warnings() -> None: # pragma: no cover
11
11
  """Check for flaml warnings once."""
12
12
  # pylint: disable=global-statement
13
- global __WALDIEZ_CHECKED_FLAML_WARNINGS
14
- if __WALDIEZ_CHECKED_FLAML_WARNINGS is False:
13
+ global __waldiez_checked_flaml_warnings
14
+ if __waldiez_checked_flaml_warnings is False:
15
15
  flam_logger = logging.getLogger("flaml")
16
16
  flam_logger.setLevel(logging.ERROR)
17
- __WALDIEZ_CHECKED_FLAML_WARNINGS = True
17
+ __waldiez_checked_flaml_warnings = True