waldiez 0.5.8__py3-none-any.whl → 0.5.10__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.
- waldiez/_version.py +1 -1
- waldiez/cli.py +112 -24
- waldiez/exporting/agent/exporter.py +3 -0
- waldiez/exporting/agent/extras/captain_agent_extras.py +44 -7
- waldiez/exporting/agent/extras/handoffs/condition.py +3 -1
- waldiez/exporting/chats/utils/common.py +25 -23
- waldiez/exporting/core/__init__.py +0 -2
- waldiez/exporting/core/context.py +13 -13
- waldiez/exporting/core/protocols.py +0 -141
- waldiez/exporting/core/result.py +5 -5
- waldiez/exporting/flow/merger.py +2 -2
- waldiez/exporting/flow/orchestrator.py +1 -0
- waldiez/exporting/flow/utils/common.py +2 -2
- waldiez/exporting/flow/utils/importing.py +1 -0
- waldiez/exporting/flow/utils/logging.py +6 -7
- waldiez/exporting/tools/exporter.py +5 -0
- waldiez/exporting/tools/factory.py +4 -0
- waldiez/exporting/tools/processor.py +5 -1
- waldiez/io/_ws.py +13 -5
- waldiez/io/models/content/image.py +1 -0
- waldiez/io/models/user_input.py +4 -4
- waldiez/io/models/user_response.py +1 -0
- waldiez/io/mqtt.py +1 -1
- waldiez/io/structured.py +17 -17
- waldiez/io/utils.py +1 -1
- waldiez/io/ws.py +9 -11
- waldiez/logger.py +180 -63
- waldiez/models/agents/agent/update_system_message.py +0 -2
- waldiez/models/agents/doc_agent/doc_agent.py +8 -1
- waldiez/models/common/dict_utils.py +169 -40
- waldiez/models/flow/flow.py +6 -6
- waldiez/models/flow/info.py +5 -1
- waldiez/models/model/_llm.py +28 -14
- waldiez/models/model/model.py +4 -1
- waldiez/models/model/model_data.py +18 -5
- waldiez/models/tool/predefined/_config.py +5 -1
- waldiez/models/tool/predefined/_duckduckgo.py +4 -0
- waldiez/models/tool/predefined/_email.py +474 -0
- waldiez/models/tool/predefined/_google.py +8 -6
- waldiez/models/tool/predefined/_perplexity.py +3 -0
- waldiez/models/tool/predefined/_searxng.py +3 -0
- waldiez/models/tool/predefined/_tavily.py +4 -1
- waldiez/models/tool/predefined/_wikipedia.py +4 -1
- waldiez/models/tool/predefined/_youtube.py +4 -1
- waldiez/models/tool/predefined/protocol.py +3 -0
- waldiez/models/tool/tool.py +22 -4
- waldiez/models/waldiez.py +12 -0
- waldiez/runner.py +37 -54
- waldiez/running/__init__.py +6 -0
- waldiez/running/base_runner.py +310 -353
- waldiez/running/environment.py +1 -0
- waldiez/running/exceptions.py +9 -0
- waldiez/running/post_run.py +4 -4
- waldiez/running/pre_run.py +51 -40
- waldiez/running/protocol.py +21 -101
- waldiez/running/run_results.py +1 -1
- waldiez/running/standard_runner.py +84 -277
- waldiez/running/step_by_step/__init__.py +46 -0
- waldiez/running/step_by_step/breakpoints_mixin.py +188 -0
- waldiez/running/step_by_step/step_by_step_models.py +224 -0
- waldiez/running/step_by_step/step_by_step_runner.py +745 -0
- waldiez/running/subprocess_runner/__base__.py +282 -0
- waldiez/running/subprocess_runner/__init__.py +16 -0
- waldiez/running/subprocess_runner/_async_runner.py +362 -0
- waldiez/running/subprocess_runner/_sync_runner.py +455 -0
- waldiez/running/subprocess_runner/runner.py +561 -0
- waldiez/running/timeline_processor.py +1 -1
- waldiez/running/utils.py +376 -1
- waldiez/utils/version.py +2 -6
- waldiez/ws/__init__.py +70 -0
- waldiez/ws/__main__.py +15 -0
- waldiez/ws/_file_handler.py +201 -0
- waldiez/ws/cli.py +211 -0
- waldiez/ws/client_manager.py +835 -0
- waldiez/ws/errors.py +416 -0
- waldiez/ws/models.py +971 -0
- waldiez/ws/reloader.py +342 -0
- waldiez/ws/server.py +469 -0
- waldiez/ws/session_manager.py +393 -0
- waldiez/ws/session_stats.py +83 -0
- waldiez/ws/utils.py +385 -0
- {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/METADATA +74 -74
- {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/RECORD +87 -65
- waldiez/running/patch_io_stream.py +0 -210
- {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/WHEEL +0 -0
- {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/entry_points.txt +0 -0
- {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/licenses/NOTICE.md +0 -0
waldiez/running/environment.py
CHANGED
|
@@ -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"
|
waldiez/running/post_run.py
CHANGED
|
@@ -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
|
|
@@ -52,7 +52,7 @@ def after_run(
|
|
|
52
52
|
flow_name=flow_name,
|
|
53
53
|
mmd_dir=mmd_dir,
|
|
54
54
|
)
|
|
55
|
-
if skip_timeline is False:
|
|
55
|
+
if skip_timeline is False: # pragma: no branch
|
|
56
56
|
_make_timeline_json(temp_dir=temp_dir)
|
|
57
57
|
if output_file:
|
|
58
58
|
destination_dir = output_file.parent
|
|
@@ -103,7 +103,7 @@ def _make_timeline_json(
|
|
|
103
103
|
events_csv_path = temp_dir / "logs" / "events.csv"
|
|
104
104
|
if events_csv_path.exists():
|
|
105
105
|
log_files = TimelineProcessor.get_files(temp_dir / "logs")
|
|
106
|
-
if any(log_files.values()):
|
|
106
|
+
if any(log_files.values()): # pragma: no branch
|
|
107
107
|
output_file = temp_dir / "timeline.json"
|
|
108
108
|
# pylint: disable=too-many-try-statements
|
|
109
109
|
try:
|
|
@@ -171,7 +171,7 @@ def copy_results(
|
|
|
171
171
|
if output_file.is_file():
|
|
172
172
|
if output_file.suffix == ".waldiez":
|
|
173
173
|
output_file = output_file.with_suffix(".py")
|
|
174
|
-
if output_file.suffix == ".py":
|
|
174
|
+
if output_file.suffix == ".py": # pragma: no branch
|
|
175
175
|
src = temp_dir / output_file.name
|
|
176
176
|
if src.exists():
|
|
177
177
|
dst = destination_dir / output_file.name
|
waldiez/running/pre_run.py
CHANGED
|
@@ -9,10 +9,53 @@ import subprocess
|
|
|
9
9
|
import sys
|
|
10
10
|
from typing import Callable
|
|
11
11
|
|
|
12
|
+
from waldiez.models import Waldiez
|
|
13
|
+
|
|
12
14
|
from .environment import in_virtualenv, is_root
|
|
13
15
|
from .utils import strip_ansi
|
|
14
16
|
|
|
15
17
|
|
|
18
|
+
class RequirementsMixin:
|
|
19
|
+
"""Mixin class to handle requirements installation."""
|
|
20
|
+
|
|
21
|
+
_waldiez: Waldiez
|
|
22
|
+
_called_install_requirements: bool
|
|
23
|
+
|
|
24
|
+
def gather_requirements(self) -> set[str]:
|
|
25
|
+
"""Gather extra requirements to install before running the flow.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
set[str]
|
|
30
|
+
A set of requirements that are not already installed and do not
|
|
31
|
+
include 'waldiez' in their name.
|
|
32
|
+
"""
|
|
33
|
+
extra_requirements = {
|
|
34
|
+
req
|
|
35
|
+
for req in self._waldiez.requirements
|
|
36
|
+
if req not in sys.modules and "waldiez" not in req
|
|
37
|
+
}
|
|
38
|
+
if "python-dotenv" not in extra_requirements: # pragma: no branch
|
|
39
|
+
extra_requirements.add("python-dotenv")
|
|
40
|
+
return extra_requirements
|
|
41
|
+
|
|
42
|
+
def install_requirements(self) -> None:
|
|
43
|
+
"""Install the requirements for the flow."""
|
|
44
|
+
if not self._called_install_requirements: # pragma: no branch
|
|
45
|
+
self._called_install_requirements = True
|
|
46
|
+
extra_requirements = self.gather_requirements()
|
|
47
|
+
if extra_requirements: # pragma: no branch
|
|
48
|
+
install_requirements(extra_requirements)
|
|
49
|
+
|
|
50
|
+
async def a_install_requirements(self) -> None:
|
|
51
|
+
"""Install the requirements for the flow asynchronously."""
|
|
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
|
+
await a_install_requirements(extra_requirements)
|
|
57
|
+
|
|
58
|
+
|
|
16
59
|
# noinspection PyUnresolvedReferences
|
|
17
60
|
def install_requirements(
|
|
18
61
|
extra_requirements: set[str],
|
|
@@ -34,7 +77,7 @@ def install_requirements(
|
|
|
34
77
|
printer(f"Installing requirements: {requirements_string}")
|
|
35
78
|
pip_install = [sys.executable, "-m", "pip", "install"]
|
|
36
79
|
break_system_packages = ""
|
|
37
|
-
if not in_virtualenv(): # it should
|
|
80
|
+
if not in_virtualenv(): # it should # pragma: no cover
|
|
38
81
|
# if not, let's try to install as user
|
|
39
82
|
# not sure if --break-system-packages is safe,
|
|
40
83
|
# but it might fail if we don't
|
|
@@ -42,7 +85,7 @@ def install_requirements(
|
|
|
42
85
|
os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
|
|
43
86
|
if not is_root():
|
|
44
87
|
pip_install.append("--user")
|
|
45
|
-
if upgrade:
|
|
88
|
+
if upgrade: # pragma: no cover
|
|
46
89
|
pip_install.append("--upgrade")
|
|
47
90
|
pip_install.extend(extra_requirements)
|
|
48
91
|
# pylint: disable=too-many-try-statements
|
|
@@ -52,14 +95,14 @@ def install_requirements(
|
|
|
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
100
|
printer(strip_ansi(line.strip()))
|
|
58
|
-
if proc.stderr:
|
|
101
|
+
if proc.stderr: # pragma: no branch
|
|
59
102
|
for line in io.TextIOWrapper(proc.stderr, encoding="utf-8"):
|
|
60
103
|
printer(strip_ansi(line.strip()))
|
|
61
104
|
finally:
|
|
62
|
-
if not in_virtualenv():
|
|
105
|
+
if not in_virtualenv(): # pragma: no cover
|
|
63
106
|
# restore the old env var
|
|
64
107
|
if break_system_packages:
|
|
65
108
|
os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = break_system_packages
|
|
@@ -87,12 +130,12 @@ async def a_install_requirements(
|
|
|
87
130
|
printer(f"Installing requirements: {requirements_string}")
|
|
88
131
|
pip_install = [sys.executable, "-m", "pip", "install"]
|
|
89
132
|
break_system_packages = ""
|
|
90
|
-
if not in_virtualenv():
|
|
133
|
+
if not in_virtualenv(): # pragma: no cover
|
|
91
134
|
break_system_packages = os.environ.get("PIP_BREAK_SYSTEM_PACKAGES", "")
|
|
92
135
|
os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
|
|
93
136
|
if not is_root():
|
|
94
137
|
pip_install.extend(["--user"])
|
|
95
|
-
if upgrade:
|
|
138
|
+
if upgrade: # pragma: no cover
|
|
96
139
|
pip_install.append("--upgrade")
|
|
97
140
|
pip_install.extend(extra_requirements)
|
|
98
141
|
# pylint: disable=too-many-try-statements
|
|
@@ -109,40 +152,8 @@ async def a_install_requirements(
|
|
|
109
152
|
async for line in proc.stderr:
|
|
110
153
|
printer(strip_ansi(line.decode().strip()))
|
|
111
154
|
finally:
|
|
112
|
-
if not in_virtualenv():
|
|
155
|
+
if not in_virtualenv(): # pragma: no cover
|
|
113
156
|
if break_system_packages:
|
|
114
157
|
os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = break_system_packages
|
|
115
158
|
else:
|
|
116
159
|
del os.environ["PIP_BREAK_SYSTEM_PACKAGES"]
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def install_waldiez(
|
|
120
|
-
upgrade: bool = True,
|
|
121
|
-
printer: Callable[..., None] = print,
|
|
122
|
-
) -> None:
|
|
123
|
-
"""Install Waldiez.
|
|
124
|
-
|
|
125
|
-
Parameters
|
|
126
|
-
----------
|
|
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.
|
|
131
|
-
"""
|
|
132
|
-
install_requirements({"waldiez"}, upgrade, printer)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
async def a_install_waldiez(
|
|
136
|
-
upgrade: bool = True,
|
|
137
|
-
printer: Callable[..., None] = print,
|
|
138
|
-
) -> None:
|
|
139
|
-
"""Install Waldiez asynchronously.
|
|
140
|
-
|
|
141
|
-
Parameters
|
|
142
|
-
----------
|
|
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.
|
|
147
|
-
"""
|
|
148
|
-
await a_install_requirements({"waldiez"}, upgrade, printer)
|
waldiez/running/protocol.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
"""
|
waldiez/running/run_results.py
CHANGED