waldiez 0.5.9__py3-none-any.whl → 0.6.0__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 (109) hide show
  1. waldiez/_version.py +1 -1
  2. waldiez/cli.py +113 -24
  3. waldiez/exporting/agent/exporter.py +9 -6
  4. waldiez/exporting/agent/extras/captain_agent_extras.py +44 -7
  5. waldiez/exporting/agent/extras/group_manager_agent_extas.py +6 -1
  6. waldiez/exporting/agent/extras/handoffs/after_work.py +1 -0
  7. waldiez/exporting/agent/extras/handoffs/available.py +1 -0
  8. waldiez/exporting/agent/extras/handoffs/condition.py +3 -1
  9. waldiez/exporting/agent/extras/handoffs/handoff.py +1 -0
  10. waldiez/exporting/agent/extras/handoffs/target.py +1 -0
  11. waldiez/exporting/agent/termination.py +1 -0
  12. waldiez/exporting/chats/utils/common.py +25 -23
  13. waldiez/exporting/core/__init__.py +0 -2
  14. waldiez/exporting/core/constants.py +3 -1
  15. waldiez/exporting/core/context.py +13 -13
  16. waldiez/exporting/core/extras/serializer.py +12 -10
  17. waldiez/exporting/core/protocols.py +0 -141
  18. waldiez/exporting/core/result.py +5 -5
  19. waldiez/exporting/core/types.py +1 -0
  20. waldiez/exporting/core/utils/llm_config.py +2 -2
  21. waldiez/exporting/flow/execution_generator.py +1 -0
  22. waldiez/exporting/flow/merger.py +2 -2
  23. waldiez/exporting/flow/orchestrator.py +1 -0
  24. waldiez/exporting/flow/utils/common.py +3 -3
  25. waldiez/exporting/flow/utils/importing.py +1 -0
  26. waldiez/exporting/flow/utils/logging.py +7 -80
  27. waldiez/exporting/tools/exporter.py +5 -0
  28. waldiez/exporting/tools/factory.py +4 -0
  29. waldiez/exporting/tools/processor.py +5 -1
  30. waldiez/io/__init__.py +3 -1
  31. waldiez/io/_ws.py +15 -5
  32. waldiez/io/models/content/image.py +1 -0
  33. waldiez/io/models/user_input.py +4 -4
  34. waldiez/io/models/user_response.py +1 -0
  35. waldiez/io/mqtt.py +1 -1
  36. waldiez/io/structured.py +98 -45
  37. waldiez/io/utils.py +17 -11
  38. waldiez/io/ws.py +10 -12
  39. waldiez/logger.py +180 -63
  40. waldiez/models/agents/agent/agent.py +2 -1
  41. waldiez/models/agents/agent/update_system_message.py +0 -2
  42. waldiez/models/agents/doc_agent/doc_agent.py +8 -1
  43. waldiez/models/chat/chat.py +1 -0
  44. waldiez/models/chat/chat_data.py +0 -2
  45. waldiez/models/common/base.py +2 -0
  46. waldiez/models/common/dict_utils.py +169 -40
  47. waldiez/models/common/handoff.py +2 -0
  48. waldiez/models/common/method_utils.py +2 -0
  49. waldiez/models/flow/flow.py +6 -6
  50. waldiez/models/flow/info.py +5 -1
  51. waldiez/models/model/_llm.py +31 -14
  52. waldiez/models/model/model.py +4 -1
  53. waldiez/models/model/model_data.py +18 -5
  54. waldiez/models/tool/predefined/_config.py +5 -1
  55. waldiez/models/tool/predefined/_duckduckgo.py +4 -0
  56. waldiez/models/tool/predefined/_email.py +477 -0
  57. waldiez/models/tool/predefined/_google.py +4 -1
  58. waldiez/models/tool/predefined/_perplexity.py +4 -1
  59. waldiez/models/tool/predefined/_searxng.py +4 -1
  60. waldiez/models/tool/predefined/_tavily.py +4 -1
  61. waldiez/models/tool/predefined/_wikipedia.py +5 -2
  62. waldiez/models/tool/predefined/_youtube.py +4 -1
  63. waldiez/models/tool/predefined/protocol.py +3 -0
  64. waldiez/models/tool/tool.py +22 -4
  65. waldiez/models/waldiez.py +12 -0
  66. waldiez/runner.py +37 -54
  67. waldiez/running/__init__.py +6 -0
  68. waldiez/running/base_runner.py +381 -363
  69. waldiez/running/environment.py +1 -0
  70. waldiez/running/exceptions.py +9 -0
  71. waldiez/running/post_run.py +10 -4
  72. waldiez/running/pre_run.py +199 -66
  73. waldiez/running/protocol.py +21 -101
  74. waldiez/running/run_results.py +1 -1
  75. waldiez/running/standard_runner.py +83 -276
  76. waldiez/running/step_by_step/__init__.py +46 -0
  77. waldiez/running/step_by_step/breakpoints_mixin.py +512 -0
  78. waldiez/running/step_by_step/command_handler.py +151 -0
  79. waldiez/running/step_by_step/events_processor.py +199 -0
  80. waldiez/running/step_by_step/step_by_step_models.py +541 -0
  81. waldiez/running/step_by_step/step_by_step_runner.py +750 -0
  82. waldiez/running/subprocess_runner/__base__.py +279 -0
  83. waldiez/running/subprocess_runner/__init__.py +16 -0
  84. waldiez/running/subprocess_runner/_async_runner.py +362 -0
  85. waldiez/running/subprocess_runner/_sync_runner.py +456 -0
  86. waldiez/running/subprocess_runner/runner.py +570 -0
  87. waldiez/running/timeline_processor.py +1 -1
  88. waldiez/running/utils.py +492 -3
  89. waldiez/utils/version.py +2 -6
  90. waldiez/ws/__init__.py +71 -0
  91. waldiez/ws/__main__.py +15 -0
  92. waldiez/ws/_file_handler.py +199 -0
  93. waldiez/ws/_mock.py +74 -0
  94. waldiez/ws/cli.py +235 -0
  95. waldiez/ws/client_manager.py +851 -0
  96. waldiez/ws/errors.py +416 -0
  97. waldiez/ws/models.py +988 -0
  98. waldiez/ws/reloader.py +363 -0
  99. waldiez/ws/server.py +508 -0
  100. waldiez/ws/session_manager.py +393 -0
  101. waldiez/ws/session_stats.py +83 -0
  102. waldiez/ws/utils.py +410 -0
  103. {waldiez-0.5.9.dist-info → waldiez-0.6.0.dist-info}/METADATA +105 -96
  104. {waldiez-0.5.9.dist-info → waldiez-0.6.0.dist-info}/RECORD +108 -83
  105. waldiez/running/patch_io_stream.py +0 -210
  106. {waldiez-0.5.9.dist-info → waldiez-0.6.0.dist-info}/WHEEL +0 -0
  107. {waldiez-0.5.9.dist-info → waldiez-0.6.0.dist-info}/entry_points.txt +0 -0
  108. {waldiez-0.5.9.dist-info → waldiez-0.6.0.dist-info}/licenses/LICENSE +0 -0
  109. {waldiez-0.5.9.dist-info → waldiez-0.6.0.dist-info}/licenses/NOTICE.md +0 -0
@@ -63,6 +63,7 @@ def refresh_environment() -> None:
63
63
 
64
64
 
65
65
  # pylint: disable=too-complex,too-many-try-statements,unused-import
66
+ # noinspection TryExceptPass
66
67
  def reload_autogen() -> None: # noqa: C901 # pragma: no cover
67
68
  """Reload the autogen package.
68
69
 
@@ -0,0 +1,9 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Custom exceptions for Waldiez runners."""
4
+
5
+
6
+ class StopRunningException(Exception):
7
+ """Exception to stop the running process."""
8
+
9
+ reason: str = "Execution stopped by user"
@@ -11,8 +11,8 @@ from pathlib import Path
11
11
  from typing import Optional, Union
12
12
 
13
13
  from .gen_seq_diagram import generate_sequence_diagram
14
- from .patch_io_stream import get_printer
15
14
  from .timeline_processor import TimelineProcessor
15
+ from .utils import get_printer
16
16
 
17
17
 
18
18
  # noinspection PyUnusedLocal
@@ -20,6 +20,7 @@ def after_run(
20
20
  temp_dir: Path,
21
21
  output_file: Optional[Union[str, Path]],
22
22
  flow_name: str,
23
+ waldiez_file: Path,
23
24
  uploads_root: Optional[Path] = None,
24
25
  skip_mmd: bool = False,
25
26
  skip_timeline: bool = False,
@@ -34,6 +35,8 @@ def after_run(
34
35
  The output file.
35
36
  flow_name : str
36
37
  The flow name.
38
+ waldiez_file : Path
39
+ The path of the waldiez file used (or dumped) for the run.
37
40
  uploads_root : Optional[Path], optional
38
41
  The runtime uploads root, by default None
39
42
  skip_mmd : bool, optional
@@ -52,7 +55,7 @@ def after_run(
52
55
  flow_name=flow_name,
53
56
  mmd_dir=mmd_dir,
54
57
  )
55
- if skip_timeline is False:
58
+ if skip_timeline is False: # pragma: no branch
56
59
  _make_timeline_json(temp_dir=temp_dir)
57
60
  if output_file:
58
61
  destination_dir = output_file.parent
@@ -69,6 +72,9 @@ def after_run(
69
72
  output_file=output_file,
70
73
  destination_dir=destination_dir,
71
74
  )
75
+ dst_waldiez = destination_dir / waldiez_file.name
76
+ if not dst_waldiez.exists() and waldiez_file.is_file():
77
+ shutil.copyfile(waldiez_file, dst_waldiez)
72
78
  shutil.rmtree(temp_dir)
73
79
 
74
80
 
@@ -103,7 +109,7 @@ def _make_timeline_json(
103
109
  events_csv_path = temp_dir / "logs" / "events.csv"
104
110
  if events_csv_path.exists():
105
111
  log_files = TimelineProcessor.get_files(temp_dir / "logs")
106
- if any(log_files.values()):
112
+ if any(log_files.values()): # pragma: no branch
107
113
  output_file = temp_dir / "timeline.json"
108
114
  # pylint: disable=too-many-try-statements
109
115
  try:
@@ -171,7 +177,7 @@ def copy_results(
171
177
  if output_file.is_file():
172
178
  if output_file.suffix == ".waldiez":
173
179
  output_file = output_file.with_suffix(".py")
174
- if output_file.suffix == ".py":
180
+ if output_file.suffix == ".py": # pragma: no branch
175
181
  src = temp_dir / output_file.name
176
182
  if src.exists():
177
183
  dst = destination_dir / output_file.name
@@ -7,10 +7,61 @@ import io
7
7
  import os
8
8
  import subprocess
9
9
  import sys
10
+ import tempfile
11
+ from pathlib import Path
10
12
  from typing import Callable
11
13
 
14
+ from waldiez.models import Waldiez
15
+
12
16
  from .environment import in_virtualenv, is_root
13
- from .utils import strip_ansi
17
+ from .utils import (
18
+ ensure_pip,
19
+ get_pip_install_location,
20
+ get_python_executable,
21
+ safe_filename,
22
+ strip_ansi,
23
+ )
24
+
25
+
26
+ class RequirementsMixin:
27
+ """Mixin class to handle requirements installation."""
28
+
29
+ _waldiez: Waldiez
30
+ _called_install_requirements: bool
31
+
32
+ def gather_requirements(self) -> set[str]:
33
+ """Gather extra requirements to install before running the flow.
34
+
35
+ Returns
36
+ -------
37
+ set[str]
38
+ A set of requirements that are not already installed and do not
39
+ include 'waldiez' in their name.
40
+ """
41
+ extra_requirements = {
42
+ req
43
+ for req in self._waldiez.requirements
44
+ if req not in sys.modules and "waldiez" not in req
45
+ }
46
+ if "python-dotenv" not in extra_requirements: # pragma: no branch
47
+ extra_requirements.add("python-dotenv")
48
+ return extra_requirements
49
+
50
+ def install_requirements(self) -> None:
51
+ """Install the requirements for the flow."""
52
+ if not self._called_install_requirements: # pragma: no branch
53
+ self._called_install_requirements = True
54
+ extra_requirements = self.gather_requirements()
55
+ if extra_requirements: # pragma: no branch
56
+ install_requirements(extra_requirements)
57
+
58
+ async def a_install_requirements(self) -> None:
59
+ """Install the requirements for the flow asynchronously."""
60
+ if not self._called_install_requirements: # pragma: no branch
61
+ self._called_install_requirements = True
62
+ extra_requirements = self.gather_requirements()
63
+ if extra_requirements: # pragma: no branch
64
+ await a_install_requirements(extra_requirements)
14
65
 
15
66
 
16
67
  # noinspection PyUnresolvedReferences
@@ -32,39 +83,40 @@ def install_requirements(
32
83
  """
33
84
  requirements_string = ", ".join(extra_requirements)
34
85
  printer(f"Installing requirements: {requirements_string}")
35
- pip_install = [sys.executable, "-m", "pip", "install"]
36
- break_system_packages = ""
37
- if not in_virtualenv(): # it should
38
- # if not, let's try to install as user
39
- # not sure if --break-system-packages is safe,
40
- # but it might fail if we don't
41
- break_system_packages = os.environ.get("PIP_BREAK_SYSTEM_PACKAGES", "")
42
- os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
43
- if not is_root():
44
- pip_install.append("--user")
45
- if upgrade:
46
- pip_install.append("--upgrade")
47
- pip_install.extend(extra_requirements)
48
- # pylint: disable=too-many-try-statements
86
+ ensure_pip()
87
+ pip_install, break_system_packages, install_location = _before_pip(
88
+ extra_requirements, upgrade
89
+ )
90
+
91
+ # pylint: disable=too-many-try-statements,broad-exception-caught
49
92
  try:
50
93
  with subprocess.Popen(
51
94
  pip_install,
52
95
  stdout=subprocess.PIPE,
53
96
  stderr=subprocess.PIPE,
54
97
  ) as proc:
55
- if proc.stdout:
98
+ if proc.stdout: # pragma: no branch
56
99
  for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
57
- printer(strip_ansi(line.strip()))
58
- if proc.stderr:
100
+ stripped_line = strip_ansi(line.strip())
101
+ if stripped_line: # Only print non-empty lines
102
+ printer(stripped_line)
103
+ if proc.stderr: # pragma: no branch
59
104
  for line in io.TextIOWrapper(proc.stderr, encoding="utf-8"):
60
- printer(strip_ansi(line.strip()))
105
+ stripped_line = strip_ansi(line.strip())
106
+ if stripped_line: # Only print non-empty lines
107
+ printer(stripped_line)
108
+
109
+ # Wait for process to complete and check return code
110
+ return_code = proc.wait()
111
+ if return_code != 0:
112
+ printer(
113
+ f"Package installation failed with exit code {return_code}"
114
+ )
115
+
116
+ except Exception as e:
117
+ printer(f"Failed to install requirements: {e}")
61
118
  finally:
62
- if not in_virtualenv():
63
- # restore the old env var
64
- if break_system_packages:
65
- os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = break_system_packages
66
- else:
67
- del os.environ["PIP_BREAK_SYSTEM_PACKAGES"]
119
+ _after_pip(break_system_packages, install_location)
68
120
 
69
121
 
70
122
  async def a_install_requirements(
@@ -83,66 +135,147 @@ async def a_install_requirements(
83
135
  printer : Callable[..., None]
84
136
  The printer function to use, defaults to print.
85
137
  """
138
+ pip_install, break_system_packages, install_location = _before_pip(
139
+ extra_requirements, upgrade=upgrade
140
+ )
86
141
  requirements_string = ", ".join(extra_requirements)
87
142
  printer(f"Installing requirements: {requirements_string}")
88
- pip_install = [sys.executable, "-m", "pip", "install"]
89
- break_system_packages = ""
90
- if not in_virtualenv():
91
- break_system_packages = os.environ.get("PIP_BREAK_SYSTEM_PACKAGES", "")
92
- os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
93
- if not is_root():
94
- pip_install.extend(["--user"])
95
- if upgrade:
96
- pip_install.append("--upgrade")
97
- pip_install.extend(extra_requirements)
98
- # pylint: disable=too-many-try-statements
143
+ # pylint: disable=too-many-try-statements,broad-exception-caught
99
144
  try:
100
145
  proc = await asyncio.create_subprocess_exec(
101
146
  *pip_install,
102
147
  stdout=asyncio.subprocess.PIPE,
103
148
  stderr=asyncio.subprocess.PIPE,
104
149
  )
105
- if proc.stdout:
106
- async for line in proc.stdout:
107
- printer(strip_ansi(line.decode().strip()))
108
- if proc.stderr:
109
- async for line in proc.stderr:
110
- printer(strip_ansi(line.decode().strip()))
150
+
151
+ async def _pump_stream(stream: asyncio.StreamReader | None) -> None:
152
+ if not stream:
153
+ return
154
+ async for raw in stream:
155
+ text = strip_ansi(raw.decode().rstrip())
156
+ if text:
157
+ printer(text)
158
+
159
+ # Create tasks for concurrent execution
160
+ tasks: list[asyncio.Task[int | None]] = [
161
+ asyncio.create_task(_pump_stream(proc.stdout)),
162
+ asyncio.create_task(_pump_stream(proc.stderr)),
163
+ asyncio.create_task(proc.wait()),
164
+ ]
165
+ await asyncio.gather(*tasks, return_exceptions=True)
166
+ if proc.returncode != 0:
167
+ printer(
168
+ f"Package installation failed with exit code {proc.returncode}"
169
+ )
170
+
171
+ except Exception as e:
172
+ printer(f"Failed to install requirements: {e}")
111
173
  finally:
112
- if not in_virtualenv():
113
- if break_system_packages:
114
- os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = break_system_packages
115
- else:
116
- del os.environ["PIP_BREAK_SYSTEM_PACKAGES"]
174
+ _after_pip(break_system_packages, install_location)
117
175
 
118
176
 
119
- def install_waldiez(
120
- upgrade: bool = True,
121
- printer: Callable[..., None] = print,
122
- ) -> None:
123
- """Install Waldiez.
177
+ def _before_pip(
178
+ packages: set[str],
179
+ upgrade: bool,
180
+ ) -> tuple[list[str], str, str | None]:
181
+ """Gather the pip command for installing requirements.
124
182
 
125
183
  Parameters
126
184
  ----------
127
- upgrade : bool, optional
128
- Whether to upgrade Waldiez, by default True.
129
- printer : Callable[..., None]
130
- The printer function to use, defaults to print.
185
+ packages : set[str]
186
+ The packages to install.
187
+ upgrade : bool
188
+ Whether to upgrade the packages.
189
+
190
+ Returns
191
+ -------
192
+ tuple[list[str], str, str | None]
193
+ The pip command, break_system_packages flag, and install location.
131
194
  """
132
- install_requirements({"waldiez"}, upgrade, printer)
195
+ ensure_pip()
196
+ pip_install = [
197
+ get_python_executable(),
198
+ "-m",
199
+ "pip",
200
+ "install",
201
+ "--disable-pip-version-check",
202
+ "--no-input",
203
+ ]
204
+ install_location = get_pip_install_location()
205
+ break_system_packages = ""
133
206
 
207
+ if install_location:
208
+ pip_install += ["--target", install_location]
209
+ elif not in_virtualenv(): # it should # pragma: no cover
210
+ # if not, let's try to install as user
211
+ # not sure if --break-system-packages is safe,
212
+ # but it might fail if we don't
213
+ break_system_packages = os.environ.get("PIP_BREAK_SYSTEM_PACKAGES", "")
214
+ os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
215
+ if not is_root():
216
+ pip_install.append("--user")
134
217
 
135
- async def a_install_waldiez(
136
- upgrade: bool = True,
137
- printer: Callable[..., None] = print,
218
+ if upgrade: # pragma: no cover
219
+ pip_install.append("--upgrade")
220
+
221
+ pip_install.extend(packages)
222
+ return pip_install, break_system_packages, install_location
223
+
224
+
225
+ def _after_pip(
226
+ break_system_packages: str, install_location: str | None
138
227
  ) -> None:
139
- """Install Waldiez asynchronously.
228
+ """Restore environment variables after pip installation.
140
229
 
141
230
  Parameters
142
231
  ----------
143
- upgrade : bool, optional
144
- Whether to upgrade Waldiez, by default True.
145
- printer : Callable[..., None]
146
- The printer function to use, defaults to print.
232
+ break_system_packages : str
233
+ The original value of PIP_BREAK_SYSTEM_PACKAGES.
234
+ install_location : str | None
235
+ The install location used (None if default).
236
+ """
237
+ if install_location is None and not in_virtualenv(): # pragma: no cover
238
+ # restore the old env var
239
+ if break_system_packages:
240
+ os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = break_system_packages
241
+ else:
242
+ # Use pop to avoid KeyError if the key doesn't exist
243
+ os.environ.pop("PIP_BREAK_SYSTEM_PACKAGES", None)
244
+
245
+
246
+ def dump_waldiez(waldiez: Waldiez, output_path: str | Path | None) -> Path:
247
+ """Dump waldiez flow to a file.
248
+
249
+ Parameters
250
+ ----------
251
+ waldiez : Waldiez
252
+ The waldiez instance to dump.
253
+ output_path : str | Path | None
254
+ Optional output path to determine the directory to save the flow to.
255
+
256
+ Returns
257
+ -------
258
+ Path
259
+ The path to the generated file.
147
260
  """
148
- await a_install_requirements({"waldiez"}, upgrade, printer)
261
+ file_path = Path(output_path) if output_path else None
262
+ if file_path:
263
+ file_name = file_path.name
264
+ if not file_name.endswith(".waldiez"):
265
+ file_path.with_suffix(".waldiez")
266
+
267
+ else:
268
+ full_name = waldiez.name
269
+ file_name = safe_filename(full_name, "waldiez")
270
+ file_dir: Path
271
+ if file_path:
272
+ file_dir = file_path if file_path.is_dir() else file_path.parent
273
+ else:
274
+ file_dir = Path(tempfile.mkdtemp())
275
+ file_dir.mkdir(parents=True, exist_ok=True)
276
+ output_path = file_dir / file_name
277
+ with output_path.open(
278
+ "w", encoding="utf-8", errors="replace", newline="\n"
279
+ ) as f_open:
280
+ f_open.write(waldiez.model_dump_json())
281
+ return output_path
@@ -51,98 +51,24 @@ class WaldiezRunnerProtocol(Protocol):
51
51
  The path to the temporary directory created for the run.
52
52
  """
53
53
 
54
- def start(
55
- self,
56
- output_path: str | Path | None,
57
- uploads_root: str | Path | None,
58
- structured_io: bool | None = None,
59
- skip_mmd: bool = False,
60
- skip_timeline: bool = False,
61
- dot_env: str | Path | None = None,
62
- **kwargs: Any,
63
- ) -> None:
64
- """Start running the Waldiez flow in a non-blocking way.
65
-
66
- To allow "stoping" it later.
67
-
68
- Parameters
69
- ----------
70
- output_path : str | Path | None
71
- The output path.
72
- uploads_root : str | Path | None
73
- The runtime uploads root.
74
- structured_io : bool
75
- Whether to use structured IO instead of the default 'input/print'.
76
- skip_mmd : bool
77
- Whether to skip generating the mermaid diagram.
78
- skip_timeline : bool
79
- Whether to skip generating the timeline JSON.
80
- dot_env : str | Path | None
81
- The path to the .env file, if any.
82
- **kwargs : Any
83
- Additional keyword arguments for the start method.
84
-
85
- Raises
86
- ------
87
- RuntimeError
88
- If the runner is already running.
89
- """
90
-
91
- async def a_start(
92
- self,
93
- output_path: str | Path | None,
94
- uploads_root: str | Path | None,
95
- structured_io: bool | None = None,
96
- skip_mmd: bool = False,
97
- skip_timeline: bool = False,
98
- dot_env: str | Path | None = None,
99
- **kwargs: Any,
100
- ) -> None:
101
- """Asynchronously start running the Waldiez flow in a non-blocking way.
102
-
103
- To allow "stoping" it later.
104
-
105
- Parameters
106
- ----------
107
- output_path : str | Path | None
108
- The output path.
109
- uploads_root : str | Path | None
110
- The runtime uploads root.
111
- structured_io : bool
112
- Whether to use structured IO instead of the default 'input/print'.
113
- skip_mmd : bool
114
- Whether to skip generating the mermaid diagram.
115
- skip_timeline : bool
116
- Whether to skip generating the timeline JSON.
117
- dot_env : str | Path | None
118
- The path to the .env file, if any.
119
- **kwargs : Any
120
- Additional keyword arguments for the start method.
121
-
122
- Raises
123
- ------
124
- RuntimeError
125
- If the runner is already running.
126
- """
127
-
128
54
  def run(
129
55
  self,
130
- output_path: str | Path | None,
131
- uploads_root: str | Path | None,
56
+ output_path: str | Path | None = None,
57
+ uploads_root: str | Path | None = None,
132
58
  structured_io: bool | None = None,
133
59
  skip_mmd: bool = False,
134
60
  skip_timeline: bool = False,
135
61
  dot_env: str | Path | None = None,
136
62
  **kwargs: Any,
137
63
  ) -> list[dict[str, Any]]:
138
- """Run the Waldiez flow in a blocking way.
64
+ """Run the Waldiez flow.
139
65
 
140
66
  Parameters
141
67
  ----------
142
68
  output_path : str | Path | None
143
69
  The output path, by default None.
144
70
  uploads_root : str | Path | None
145
- The runtime uploads root.
71
+ The runtime uploads root, by default None.
146
72
  structured_io : bool
147
73
  Whether to use structured IO instead of the default 'input/print'.
148
74
  skip_mmd : bool
@@ -157,20 +83,26 @@ class WaldiezRunnerProtocol(Protocol):
157
83
  Returns
158
84
  -------
159
85
  list[dict[str, Any]]
160
- The result of the run.
86
+ The results of the run.
87
+
88
+ Raises
89
+ ------
90
+ RuntimeError
91
+ If the runner is already running
92
+ or an error occurs during the run.
161
93
  """
162
94
 
163
95
  async def a_run(
164
96
  self,
165
- output_path: str | Path | None,
166
- uploads_root: str | Path | None,
97
+ output_path: str | Path | None = None,
98
+ uploads_root: str | Path | None = None,
167
99
  structured_io: bool | None = None,
168
100
  skip_mmd: bool = False,
169
101
  skip_timeline: bool = False,
170
102
  dot_env: str | Path | None = None,
171
103
  **kwargs: Any,
172
104
  ) -> list[dict[str, Any]]:
173
- """Run the Waldiez flow.
105
+ """Run the Waldiez flow asynchronously.
174
106
 
175
107
  Parameters
176
108
  ----------
@@ -192,7 +124,13 @@ class WaldiezRunnerProtocol(Protocol):
192
124
  Returns
193
125
  -------
194
126
  list[dict[str, Any]]
195
- The result of the run.
127
+ The results of the run.
128
+
129
+ Raises
130
+ ------
131
+ RuntimeError
132
+ If the runner is already running, the workflow is not async
133
+ or an error occurs during the run.
196
134
  """
197
135
 
198
136
  def after_run(
@@ -257,21 +195,3 @@ class WaldiezRunnerProtocol(Protocol):
257
195
  bool
258
196
  True if the runner is running, False otherwise.
259
197
  """
260
-
261
- def stop(self) -> None:
262
- """Stop the runner if it is running.
263
-
264
- Raises
265
- ------
266
- RuntimeError
267
- If the runner is not running.
268
- """
269
-
270
- async def a_stop(self) -> None:
271
- """Asynchronously stop the runner if it is running.
272
-
273
- Raises
274
- ------
275
- RuntimeError
276
- If the runner is not running.
277
- """
@@ -10,5 +10,5 @@ class WaldiezRunResults(TypedDict):
10
10
  """Results of the Waldiez run."""
11
11
 
12
12
  results: list[dict[str, Any]]
13
- exception: Exception | None
13
+ exception: BaseException | None
14
14
  completed: bool