waldiez 0.5.10__py3-none-any.whl → 0.6.1__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/__init__.py +1 -1
- waldiez/_version.py +1 -1
- waldiez/cli.py +19 -7
- waldiez/cli_extras/jupyter.py +3 -0
- waldiez/cli_extras/runner.py +3 -1
- waldiez/cli_extras/studio.py +3 -1
- waldiez/exporter.py +9 -3
- waldiez/exporting/agent/exporter.py +15 -16
- waldiez/exporting/agent/extras/captain_agent_extras.py +6 -6
- waldiez/exporting/agent/extras/doc_agent_extras.py +6 -6
- waldiez/exporting/agent/extras/group_manager_agent_extas.py +40 -24
- waldiez/exporting/agent/extras/group_member_extras.py +6 -5
- waldiez/exporting/agent/extras/handoffs/after_work.py +2 -1
- waldiez/exporting/agent/extras/handoffs/available.py +2 -1
- waldiez/exporting/agent/extras/handoffs/condition.py +3 -2
- waldiez/exporting/agent/extras/handoffs/handoff.py +2 -1
- waldiez/exporting/agent/extras/handoffs/target.py +7 -4
- waldiez/exporting/agent/extras/rag/chroma_extras.py +27 -19
- waldiez/exporting/agent/extras/rag/mongo_extras.py +8 -8
- waldiez/exporting/agent/extras/rag/pgvector_extras.py +5 -5
- waldiez/exporting/agent/extras/rag/qdrant_extras.py +5 -4
- waldiez/exporting/agent/extras/rag/vector_db_extras.py +1 -1
- waldiez/exporting/agent/extras/rag_user_proxy_agent_extras.py +5 -7
- waldiez/exporting/agent/extras/reasoning_agent_extras.py +3 -5
- waldiez/exporting/agent/termination.py +1 -0
- waldiez/exporting/chats/exporter.py +4 -4
- waldiez/exporting/chats/processor.py +1 -2
- waldiez/exporting/chats/utils/common.py +89 -48
- waldiez/exporting/chats/utils/group.py +9 -9
- waldiez/exporting/chats/utils/nested.py +7 -7
- waldiez/exporting/chats/utils/sequential.py +1 -1
- waldiez/exporting/chats/utils/single.py +2 -2
- waldiez/exporting/core/constants.py +3 -1
- waldiez/exporting/core/content.py +7 -7
- waldiez/exporting/core/context.py +5 -3
- waldiez/exporting/core/exporter.py +5 -3
- waldiez/exporting/core/exporters.py +2 -2
- waldiez/exporting/core/extras/agent_extras/captain_extras.py +2 -2
- waldiez/exporting/core/extras/agent_extras/group_manager_extras.py +2 -2
- waldiez/exporting/core/extras/agent_extras/rag_user_extras.py +2 -2
- waldiez/exporting/core/extras/agent_extras/standard_extras.py +3 -8
- waldiez/exporting/core/extras/base.py +7 -5
- waldiez/exporting/core/extras/flow_extras.py +4 -5
- waldiez/exporting/core/extras/model_extras.py +2 -2
- waldiez/exporting/core/extras/path_resolver.py +1 -2
- waldiez/exporting/core/extras/serializer.py +13 -11
- waldiez/exporting/core/protocols.py +6 -5
- waldiez/exporting/core/result.py +25 -28
- waldiez/exporting/core/types.py +11 -10
- waldiez/exporting/core/utils/llm_config.py +4 -4
- waldiez/exporting/core/validation.py +10 -11
- waldiez/exporting/flow/execution_generator.py +99 -10
- waldiez/exporting/flow/exporter.py +2 -2
- waldiez/exporting/flow/factory.py +2 -2
- waldiez/exporting/flow/file_generator.py +4 -2
- waldiez/exporting/flow/merger.py +5 -3
- waldiez/exporting/flow/orchestrator.py +72 -2
- waldiez/exporting/flow/utils/common.py +6 -6
- waldiez/exporting/flow/utils/importing.py +7 -8
- waldiez/exporting/flow/utils/linting.py +25 -9
- waldiez/exporting/flow/utils/logging.py +5 -77
- waldiez/exporting/models/exporter.py +8 -8
- waldiez/exporting/models/processor.py +5 -5
- waldiez/exporting/tools/exporter.py +2 -2
- waldiez/exporting/tools/processor.py +7 -4
- waldiez/io/__init__.py +11 -5
- waldiez/io/_ws.py +12 -6
- waldiez/io/models/constants.py +10 -10
- waldiez/io/models/content/audio.py +1 -0
- waldiez/io/models/content/base.py +20 -18
- waldiez/io/models/content/file.py +1 -0
- waldiez/io/models/content/image.py +1 -0
- waldiez/io/models/content/text.py +1 -0
- waldiez/io/models/content/video.py +1 -0
- waldiez/io/models/user_input.py +10 -5
- waldiez/io/models/user_response.py +17 -16
- waldiez/io/mqtt.py +18 -31
- waldiez/io/redis.py +18 -22
- waldiez/io/structured.py +122 -70
- waldiez/io/utils.py +19 -10
- waldiez/io/ws.py +7 -3
- waldiez/logger.py +16 -3
- waldiez/models/agents/__init__.py +3 -0
- waldiez/models/agents/agent/agent.py +25 -17
- waldiez/models/agents/agent/agent_data.py +25 -22
- waldiez/models/agents/agent/code_execution.py +9 -11
- waldiez/models/agents/agent/termination_message.py +10 -12
- waldiez/models/agents/agent/update_system_message.py +2 -4
- waldiez/models/agents/agents.py +8 -8
- waldiez/models/agents/assistant/assistant.py +6 -3
- waldiez/models/agents/assistant/assistant_data.py +2 -2
- waldiez/models/agents/captain/captain_agent.py +7 -4
- waldiez/models/agents/captain/captain_agent_data.py +5 -7
- waldiez/models/agents/doc_agent/doc_agent.py +7 -4
- waldiez/models/agents/doc_agent/doc_agent_data.py +9 -10
- waldiez/models/agents/doc_agent/rag_query_engine.py +10 -12
- waldiez/models/agents/extra_requirements.py +3 -3
- waldiez/models/agents/group_manager/group_manager.py +12 -7
- waldiez/models/agents/group_manager/group_manager_data.py +13 -12
- waldiez/models/agents/group_manager/speakers.py +17 -19
- waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +7 -4
- waldiez/models/agents/rag_user_proxy/rag_user_proxy_data.py +4 -1
- waldiez/models/agents/rag_user_proxy/retrieve_config.py +69 -63
- waldiez/models/agents/rag_user_proxy/vector_db_config.py +19 -19
- waldiez/models/agents/reasoning/reasoning_agent.py +7 -4
- waldiez/models/agents/reasoning/reasoning_agent_data.py +3 -2
- waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +8 -8
- waldiez/models/agents/user_proxy/user_proxy.py +6 -3
- waldiez/models/agents/user_proxy/user_proxy_data.py +1 -1
- waldiez/models/chat/chat.py +28 -20
- waldiez/models/chat/chat_data.py +22 -21
- waldiez/models/chat/chat_message.py +9 -9
- waldiez/models/chat/chat_nested.py +9 -9
- waldiez/models/chat/chat_summary.py +6 -6
- waldiez/models/common/__init__.py +2 -0
- waldiez/models/common/ag2_version.py +2 -0
- waldiez/models/common/base.py +2 -0
- waldiez/models/common/dict_utils.py +8 -6
- waldiez/models/common/handoff.py +20 -17
- waldiez/models/common/method_utils.py +9 -7
- waldiez/models/common/naming.py +49 -0
- waldiez/models/flow/flow.py +11 -6
- waldiez/models/flow/flow_data.py +23 -17
- waldiez/models/flow/info.py +3 -3
- waldiez/models/flow/naming.py +2 -1
- waldiez/models/model/_aws.py +11 -13
- waldiez/models/model/_llm.py +8 -0
- waldiez/models/model/_price.py +2 -4
- waldiez/models/model/extra_requirements.py +1 -3
- waldiez/models/model/model.py +2 -2
- waldiez/models/model/model_data.py +21 -21
- waldiez/models/tool/extra_requirements.py +2 -4
- waldiez/models/tool/predefined/_duckduckgo.py +1 -0
- waldiez/models/tool/predefined/_email.py +4 -0
- waldiez/models/tool/predefined/_google.py +1 -0
- waldiez/models/tool/predefined/_perplexity.py +2 -1
- waldiez/models/tool/predefined/_searxng.py +2 -1
- waldiez/models/tool/predefined/_tavily.py +1 -0
- waldiez/models/tool/predefined/_wikipedia.py +2 -1
- waldiez/models/tool/predefined/_youtube.py +1 -0
- waldiez/models/tool/tool.py +8 -5
- waldiez/models/tool/tool_data.py +2 -2
- waldiez/models/waldiez.py +152 -4
- waldiez/runner.py +11 -5
- waldiez/running/async_utils.py +192 -0
- waldiez/running/base_runner.py +155 -241
- waldiez/running/dir_utils.py +52 -0
- waldiez/running/environment.py +10 -44
- waldiez/running/events_mixin.py +252 -0
- waldiez/running/exceptions.py +20 -0
- waldiez/running/gen_seq_diagram.py +18 -15
- waldiez/running/io_utils.py +216 -0
- waldiez/running/protocol.py +11 -5
- waldiez/running/requirements_mixin.py +65 -0
- waldiez/running/results_mixin.py +926 -0
- waldiez/running/standard_runner.py +24 -27
- waldiez/running/step_by_step/breakpoints_mixin.py +503 -47
- waldiez/running/step_by_step/command_handler.py +154 -0
- waldiez/running/step_by_step/events_processor.py +379 -0
- waldiez/running/step_by_step/step_by_step_models.py +425 -41
- waldiez/running/step_by_step/step_by_step_runner.py +437 -382
- waldiez/running/subprocess_runner/__base__.py +13 -8
- waldiez/running/subprocess_runner/_async_runner.py +6 -4
- waldiez/running/subprocess_runner/_sync_runner.py +11 -6
- waldiez/running/subprocess_runner/runner.py +48 -23
- waldiez/running/timeline_processor.py +1 -1
- waldiez/utils/__init__.py +2 -0
- waldiez/utils/conflict_checker.py +4 -4
- waldiez/utils/python_manager.py +415 -0
- waldiez/ws/__init__.py +8 -7
- waldiez/ws/_file_handler.py +18 -20
- waldiez/ws/_mock.py +75 -0
- waldiez/ws/cli.py +58 -10
- waldiez/ws/client_manager.py +77 -53
- waldiez/ws/errors.py +3 -0
- waldiez/ws/models.py +61 -53
- waldiez/ws/reloader.py +33 -4
- waldiez/ws/server.py +121 -52
- waldiez/ws/session_manager.py +8 -9
- waldiez/ws/session_stats.py +1 -1
- waldiez/ws/utils.py +33 -5
- {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/METADATA +107 -109
- waldiez-0.6.1.dist-info/RECORD +254 -0
- waldiez/running/post_run.py +0 -180
- waldiez/running/pre_run.py +0 -159
- waldiez/running/run_results.py +0 -14
- waldiez/running/utils.py +0 -511
- waldiez-0.5.10.dist-info/RECORD +0 -248
- {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/WHEEL +0 -0
- {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/entry_points.txt +0 -0
- {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/licenses/NOTICE.md +0 -0
waldiez/running/base_runner.py
CHANGED
|
@@ -2,79 +2,46 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
|
|
4
4
|
# pyright: reportUnknownMemberType=false, reportAttributeAccessIssue=false
|
|
5
|
-
# pyright: reportUnknownArgumentType=false
|
|
5
|
+
# pyright: reportUnknownArgumentType=false, reportUnusedParameter=false
|
|
6
6
|
"""Base runner for Waldiez workflows."""
|
|
7
7
|
|
|
8
8
|
import importlib.util
|
|
9
|
-
import
|
|
9
|
+
import json
|
|
10
10
|
import shutil
|
|
11
11
|
import sys
|
|
12
12
|
import tempfile
|
|
13
13
|
import threading
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
from types import ModuleType, TracebackType
|
|
16
|
-
from typing import
|
|
16
|
+
from typing import Any
|
|
17
17
|
|
|
18
18
|
from aiofiles.os import wrap
|
|
19
19
|
from anyio.from_thread import start_blocking_portal
|
|
20
|
-
from typing_extensions import Self
|
|
20
|
+
from typing_extensions import Self, override
|
|
21
21
|
|
|
22
22
|
from waldiez.exporter import WaldiezExporter
|
|
23
23
|
from waldiez.logger import WaldiezLogger, get_logger
|
|
24
24
|
from waldiez.models import Waldiez
|
|
25
25
|
|
|
26
|
-
from .
|
|
26
|
+
from .dir_utils import a_chdir, chdir
|
|
27
|
+
from .environment import reset_env_vars, set_env_vars
|
|
28
|
+
from .events_mixin import EventsMixin
|
|
27
29
|
from .exceptions import StopRunningException
|
|
28
|
-
from .post_run import after_run
|
|
29
|
-
from .pre_run import RequirementsMixin
|
|
30
30
|
from .protocol import WaldiezRunnerProtocol
|
|
31
|
-
from .
|
|
32
|
-
|
|
33
|
-
chdir,
|
|
34
|
-
input_async,
|
|
35
|
-
input_sync,
|
|
36
|
-
is_async_callable,
|
|
37
|
-
syncify,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
if TYPE_CHECKING:
|
|
41
|
-
from autogen.events import BaseEvent # type: ignore[import-untyped]
|
|
42
|
-
from autogen.messages import BaseMessage # type: ignore[import-untyped]
|
|
31
|
+
from .requirements_mixin import RequirementsMixin
|
|
32
|
+
from .results_mixin import ResultsMixin
|
|
43
33
|
|
|
44
34
|
|
|
45
35
|
# pylint: disable=too-many-public-methods
|
|
46
|
-
class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
47
|
-
"""Base runner for Waldiez.
|
|
48
|
-
|
|
49
|
-
Initialization parameters:
|
|
50
|
-
- waldiez: The Waldiez flow to run.
|
|
51
|
-
- output_path: Path to save the output file.
|
|
52
|
-
- uploads_root: Root directory for uploads.
|
|
53
|
-
- structured_io: Whether to use structured I/O.
|
|
54
|
-
- skip_patch_io: Whether to skip patching I/O functions.
|
|
55
|
-
- dot_env: Path to a .env file for environment variables.
|
|
56
|
-
|
|
57
|
-
Methods to possibly override:
|
|
58
|
-
- prepare: Prepare the environment and paths for running the flow.
|
|
59
|
-
- _before_run: Actions to perform before running the flow.
|
|
60
|
-
- a_prepare: Async version of the prepare method.
|
|
61
|
-
- _a_before_run: Async actions to perform before running the flow.
|
|
62
|
-
- _run: Actual implementation of the run logic.
|
|
63
|
-
- _a_run: Async implementation of the run logic.
|
|
64
|
-
- _after_run: Actions to perform after running the flow.
|
|
65
|
-
- _a_after_run: Async actions to perform after running the flow.
|
|
66
|
-
"""
|
|
36
|
+
class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin, ResultsMixin):
|
|
37
|
+
"""Base runner for Waldiez."""
|
|
67
38
|
|
|
68
39
|
_structured_io: bool
|
|
69
40
|
_output_path: str | Path | None
|
|
70
41
|
_uploads_root: str | Path | None
|
|
71
42
|
_dot_env_path: str | Path | None
|
|
72
|
-
_skip_patch_io: bool
|
|
73
43
|
_running: bool
|
|
74
|
-
|
|
75
|
-
_input: Callable[..., str] | Callable[..., Coroutine[Any, Any, str]]
|
|
76
|
-
_print: Callable[..., None]
|
|
77
|
-
_send: Callable[[Union["BaseEvent", "BaseMessage"]], None]
|
|
44
|
+
_waldiez_file: Path
|
|
78
45
|
|
|
79
46
|
def __init__(
|
|
80
47
|
self,
|
|
@@ -82,7 +49,6 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
82
49
|
output_path: str | Path | None,
|
|
83
50
|
uploads_root: str | Path | None,
|
|
84
51
|
structured_io: bool,
|
|
85
|
-
skip_patch_io: bool = False,
|
|
86
52
|
dot_env: str | Path | None = None,
|
|
87
53
|
**kwargs: Any,
|
|
88
54
|
) -> None:
|
|
@@ -91,12 +57,12 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
91
57
|
WaldiezBaseRunner._structured_io = structured_io
|
|
92
58
|
WaldiezBaseRunner._output_path = output_path
|
|
93
59
|
WaldiezBaseRunner._uploads_root = uploads_root
|
|
94
|
-
WaldiezBaseRunner._skip_patch_io = skip_patch_io
|
|
95
60
|
WaldiezBaseRunner._dot_env_path = dot_env
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
61
|
+
EventsMixin.set_input_function(input)
|
|
62
|
+
EventsMixin.set_print_function(print)
|
|
63
|
+
EventsMixin.set_send_function(print)
|
|
64
|
+
EventsMixin.set_async(waldiez.is_async)
|
|
65
|
+
RequirementsMixin.__init__(self)
|
|
100
66
|
self._waldiez = waldiez
|
|
101
67
|
self._called_install_requirements = False
|
|
102
68
|
self._exporter = WaldiezExporter(waldiez)
|
|
@@ -110,100 +76,46 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
110
76
|
self._logger = logger
|
|
111
77
|
else:
|
|
112
78
|
self._logger = get_logger()
|
|
79
|
+
waldiez_file = kwargs.get("waldiez_file", "")
|
|
80
|
+
if isinstance(waldiez_file, str) and waldiez_file:
|
|
81
|
+
waldiez_file_path = Path(waldiez_file).resolve()
|
|
82
|
+
elif isinstance(waldiez_file, Path):
|
|
83
|
+
waldiez_file_path = waldiez_file.resolve()
|
|
84
|
+
else:
|
|
85
|
+
waldiez_file_path = waldiez.dump(to=output_path)
|
|
86
|
+
if not waldiez_file_path or not waldiez_file_path.is_file():
|
|
87
|
+
raise ValueError("Could not resolve a waldiez file path")
|
|
88
|
+
WaldiezBaseRunner._waldiez_file = waldiez_file_path
|
|
113
89
|
|
|
114
|
-
|
|
115
|
-
"""Check if the workflow is currently running.
|
|
116
|
-
|
|
117
|
-
Returns
|
|
118
|
-
-------
|
|
119
|
-
bool
|
|
120
|
-
True if the workflow is running, False otherwise.
|
|
121
|
-
"""
|
|
122
|
-
with self._running_lock:
|
|
123
|
-
return WaldiezBaseRunner._running
|
|
124
|
-
|
|
125
|
-
@staticmethod
|
|
126
|
-
def get_input_function() -> (
|
|
127
|
-
Callable[..., str] | Callable[..., Coroutine[Any, Any, str]]
|
|
128
|
-
):
|
|
129
|
-
"""Get the input function for user interaction.
|
|
130
|
-
|
|
131
|
-
Returns
|
|
132
|
-
-------
|
|
133
|
-
Callable[[str, bool], str]
|
|
134
|
-
A function that takes a prompt and a password flag,
|
|
135
|
-
returning user input.
|
|
136
|
-
"""
|
|
137
|
-
if hasattr(WaldiezBaseRunner, "_input") and callable(
|
|
138
|
-
WaldiezBaseRunner._input
|
|
139
|
-
):
|
|
140
|
-
return WaldiezBaseRunner._input
|
|
141
|
-
if WaldiezBaseRunner._is_async:
|
|
142
|
-
return input_async
|
|
143
|
-
return input_sync
|
|
144
|
-
|
|
90
|
+
@override
|
|
145
91
|
@staticmethod
|
|
146
|
-
|
|
147
|
-
"""
|
|
92
|
+
def print(*args: Any, **kwargs: Any) -> None:
|
|
93
|
+
"""Print a message to the output stream.
|
|
148
94
|
|
|
149
95
|
Parameters
|
|
150
96
|
----------
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Returns
|
|
157
|
-
-------
|
|
158
|
-
str
|
|
159
|
-
The user input.
|
|
97
|
+
*args : Any
|
|
98
|
+
Positional arguments to print.
|
|
99
|
+
**kwargs : Any
|
|
100
|
+
Keyword arguments to print.
|
|
160
101
|
"""
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
result = await input_function( # type: ignore
|
|
165
|
-
prompt,
|
|
166
|
-
password=password,
|
|
167
|
-
)
|
|
168
|
-
except TypeError:
|
|
169
|
-
result = await input_function(prompt) # type: ignore
|
|
102
|
+
if len(args) == 1 and isinstance(args[0], dict):
|
|
103
|
+
arg = json.dumps(args[0], default=str, ensure_ascii=False)
|
|
104
|
+
EventsMixin.do_print(arg, **kwargs)
|
|
170
105
|
else:
|
|
171
|
-
|
|
172
|
-
result = input_function(prompt, password=password)
|
|
173
|
-
except TypeError:
|
|
174
|
-
result = input_function(prompt)
|
|
175
|
-
return result # pyright: ignore
|
|
176
|
-
|
|
177
|
-
@staticmethod
|
|
178
|
-
def get_user_input(
|
|
179
|
-
prompt: str,
|
|
180
|
-
*,
|
|
181
|
-
password: bool = False,
|
|
182
|
-
) -> str:
|
|
183
|
-
"""Get user input with an optional password prompt.
|
|
106
|
+
EventsMixin.do_print(*args, **kwargs)
|
|
184
107
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
The prompt to display to the user.
|
|
189
|
-
password : bool, optional
|
|
190
|
-
If True, the input will be hidden (default is False).
|
|
108
|
+
@override
|
|
109
|
+
def is_running(self) -> bool:
|
|
110
|
+
"""Check if the workflow is currently running.
|
|
191
111
|
|
|
192
112
|
Returns
|
|
193
113
|
-------
|
|
194
|
-
|
|
195
|
-
|
|
114
|
+
bool
|
|
115
|
+
True if the workflow is running, False otherwise.
|
|
196
116
|
"""
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
try:
|
|
200
|
-
return syncify(input_function)(prompt, password=password)
|
|
201
|
-
except TypeError:
|
|
202
|
-
return syncify(input_function)(prompt)
|
|
203
|
-
try:
|
|
204
|
-
return str(input_function(prompt, password=password))
|
|
205
|
-
except TypeError:
|
|
206
|
-
return str(input_function(prompt))
|
|
117
|
+
with self._running_lock:
|
|
118
|
+
return WaldiezBaseRunner._running
|
|
207
119
|
|
|
208
120
|
def _load_module(self, output_file: Path, temp_dir: Path) -> ModuleType:
|
|
209
121
|
"""Load the module from the waldiez file."""
|
|
@@ -230,7 +142,7 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
230
142
|
) -> Path:
|
|
231
143
|
"""Run before the flow execution."""
|
|
232
144
|
self.log.info("Preparing workflow file: %s", output_file)
|
|
233
|
-
temp_dir = Path(tempfile.mkdtemp())
|
|
145
|
+
temp_dir = Path(tempfile.mkdtemp(prefix="wlz-"))
|
|
234
146
|
file_name = output_file.name
|
|
235
147
|
with chdir(to=temp_dir):
|
|
236
148
|
self._exporter.export(
|
|
@@ -300,12 +212,14 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
300
212
|
def _after_run(
|
|
301
213
|
self,
|
|
302
214
|
results: list[dict[str, Any]],
|
|
215
|
+
error: BaseException | None,
|
|
303
216
|
output_file: Path,
|
|
217
|
+
waldiez_file: Path,
|
|
304
218
|
uploads_root: Path | None,
|
|
305
219
|
temp_dir: Path,
|
|
306
220
|
skip_mmd: bool,
|
|
307
221
|
skip_timeline: bool,
|
|
308
|
-
) -> None:
|
|
222
|
+
) -> Path | None:
|
|
309
223
|
"""Run after the flow execution."""
|
|
310
224
|
# Save results
|
|
311
225
|
self._last_results = results
|
|
@@ -314,10 +228,13 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
314
228
|
self._stop_requested.clear()
|
|
315
229
|
# pylint: disable=broad-exception-caught
|
|
316
230
|
try:
|
|
317
|
-
|
|
231
|
+
return ResultsMixin.post_run(
|
|
232
|
+
results=results,
|
|
233
|
+
error=error,
|
|
318
234
|
temp_dir=temp_dir,
|
|
319
235
|
output_file=output_file,
|
|
320
236
|
flow_name=self._waldiez.name,
|
|
237
|
+
waldiez_file=waldiez_file,
|
|
321
238
|
uploads_root=uploads_root,
|
|
322
239
|
skip_mmd=skip_mmd,
|
|
323
240
|
skip_timeline=skip_timeline,
|
|
@@ -325,25 +242,39 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
325
242
|
except BaseException as exc: # pragma: no cover
|
|
326
243
|
self.log.warning("Error occurred during after_run: %s", exc)
|
|
327
244
|
self.log.info("Cleanup completed")
|
|
245
|
+
return None
|
|
328
246
|
|
|
329
247
|
async def _a_after_run(
|
|
330
248
|
self,
|
|
331
249
|
results: list[dict[str, Any]],
|
|
250
|
+
error: BaseException | None,
|
|
332
251
|
output_file: Path,
|
|
252
|
+
waldiez_file: Path,
|
|
333
253
|
uploads_root: Path | None,
|
|
334
254
|
temp_dir: Path,
|
|
335
255
|
skip_mmd: bool,
|
|
336
256
|
skip_timeline: bool,
|
|
337
|
-
) -> None:
|
|
257
|
+
) -> Path | None:
|
|
338
258
|
"""Run after the flow execution asynchronously."""
|
|
339
|
-
self.
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
259
|
+
self._last_results = results
|
|
260
|
+
self._stop_requested.clear()
|
|
261
|
+
# pylint: disable=broad-exception-caught
|
|
262
|
+
try:
|
|
263
|
+
return await ResultsMixin.a_post_run(
|
|
264
|
+
results=results,
|
|
265
|
+
error=error,
|
|
266
|
+
temp_dir=temp_dir,
|
|
267
|
+
output_file=output_file,
|
|
268
|
+
flow_name=self._waldiez.name,
|
|
269
|
+
waldiez_file=waldiez_file,
|
|
270
|
+
uploads_root=uploads_root,
|
|
271
|
+
skip_mmd=skip_mmd,
|
|
272
|
+
skip_timeline=skip_timeline,
|
|
273
|
+
)
|
|
274
|
+
except BaseException as exc: # pragma: no cover
|
|
275
|
+
self.log.warning("Error occurred during a_after_run: %s", exc)
|
|
276
|
+
self.log.info("Cleanup completed")
|
|
277
|
+
return None
|
|
347
278
|
|
|
348
279
|
@staticmethod
|
|
349
280
|
def _prepare_paths(
|
|
@@ -364,58 +295,7 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
364
295
|
output_file: Path = Path(WaldiezBaseRunner._output_path)
|
|
365
296
|
return output_file, uploads_root_path
|
|
366
297
|
|
|
367
|
-
@
|
|
368
|
-
async def a_process_event(event: Union["BaseEvent", "BaseMessage"]) -> None:
|
|
369
|
-
"""Process an event or message asynchronously.
|
|
370
|
-
|
|
371
|
-
Parameters
|
|
372
|
-
----------
|
|
373
|
-
event : Union[BaseEvent, BaseMessage]
|
|
374
|
-
The event or message to process.
|
|
375
|
-
"""
|
|
376
|
-
if hasattr(event, "type"): # pragma: no branch
|
|
377
|
-
if event.type == "input_request":
|
|
378
|
-
prompt = getattr(
|
|
379
|
-
event, "prompt", getattr(event.content, "prompt", "> ")
|
|
380
|
-
)
|
|
381
|
-
password = getattr(
|
|
382
|
-
event,
|
|
383
|
-
"password",
|
|
384
|
-
getattr(event.content, "password", False),
|
|
385
|
-
)
|
|
386
|
-
user_input = await WaldiezBaseRunner.a_get_user_input(
|
|
387
|
-
prompt, password=password
|
|
388
|
-
)
|
|
389
|
-
await event.content.respond(user_input)
|
|
390
|
-
else:
|
|
391
|
-
WaldiezBaseRunner._send(event)
|
|
392
|
-
|
|
393
|
-
@staticmethod
|
|
394
|
-
def process_event(event: Union["BaseEvent", "BaseMessage"]) -> None:
|
|
395
|
-
"""Process an event or message synchronously.
|
|
396
|
-
|
|
397
|
-
Parameters
|
|
398
|
-
----------
|
|
399
|
-
event : Union[BaseEvent, BaseMessage]
|
|
400
|
-
The event or message to process.
|
|
401
|
-
"""
|
|
402
|
-
if hasattr(event, "type"): # pragma: no branch
|
|
403
|
-
if event.type == "input_request":
|
|
404
|
-
prompt = getattr(
|
|
405
|
-
event, "prompt", getattr(event.content, "prompt", "> ")
|
|
406
|
-
)
|
|
407
|
-
password = getattr(
|
|
408
|
-
event,
|
|
409
|
-
"password",
|
|
410
|
-
getattr(event.content, "password", False),
|
|
411
|
-
)
|
|
412
|
-
user_input = WaldiezBaseRunner.get_user_input(
|
|
413
|
-
prompt, password=password
|
|
414
|
-
)
|
|
415
|
-
event.content.respond(user_input)
|
|
416
|
-
else:
|
|
417
|
-
WaldiezBaseRunner._send(event)
|
|
418
|
-
|
|
298
|
+
@override
|
|
419
299
|
def before_run(
|
|
420
300
|
self,
|
|
421
301
|
output_file: Path,
|
|
@@ -440,6 +320,7 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
440
320
|
uploads_root=uploads_root,
|
|
441
321
|
)
|
|
442
322
|
|
|
323
|
+
@override
|
|
443
324
|
async def a_before_run(
|
|
444
325
|
self,
|
|
445
326
|
output_file: Path,
|
|
@@ -495,11 +376,11 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
495
376
|
uploads_root=uploads_root_path,
|
|
496
377
|
)
|
|
497
378
|
self.install_requirements()
|
|
498
|
-
refresh_environment()
|
|
499
379
|
return temp_dir, output_file, uploads_root_path
|
|
500
380
|
|
|
501
381
|
# noinspection PyProtocol
|
|
502
382
|
# pylint: disable=too-many-locals,unused-argument
|
|
383
|
+
@override
|
|
503
384
|
def run(
|
|
504
385
|
self,
|
|
505
386
|
output_path: str | Path | None = None,
|
|
@@ -564,8 +445,10 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
564
445
|
uploads_root=uploads_root,
|
|
565
446
|
)
|
|
566
447
|
WaldiezBaseRunner._running = True
|
|
567
|
-
results: list[dict[str, Any]]
|
|
448
|
+
results: list[dict[str, Any]] = []
|
|
449
|
+
error: BaseException | None = None
|
|
568
450
|
old_env_vars = set_env_vars(self._waldiez.get_flow_env_vars())
|
|
451
|
+
output_dir = output_file.parent
|
|
569
452
|
try:
|
|
570
453
|
with chdir(to=temp_dir):
|
|
571
454
|
sys.path.insert(0, str(temp_dir))
|
|
@@ -577,25 +460,30 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
577
460
|
skip_timeline=skip_timeline,
|
|
578
461
|
)
|
|
579
462
|
except (SystemExit, StopRunningException, KeyboardInterrupt) as exc:
|
|
463
|
+
error = exc
|
|
464
|
+
self.log.warning("Execution stopped: %s", exc)
|
|
580
465
|
raise StopRunningException(StopRunningException.reason) from exc
|
|
581
466
|
except BaseException as exc: # pylint: disable=broad-exception-caught
|
|
582
467
|
self.log.error("Error occurred while running workflow: %s", exc)
|
|
583
|
-
|
|
468
|
+
error = exc
|
|
584
469
|
finally:
|
|
585
470
|
WaldiezBaseRunner._running = False
|
|
586
471
|
reset_env_vars(old_env_vars)
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
472
|
+
output = self.after_run(
|
|
473
|
+
results=results,
|
|
474
|
+
error=error,
|
|
475
|
+
output_file=output_file,
|
|
476
|
+
uploads_root=uploads_root_path,
|
|
477
|
+
temp_dir=temp_dir,
|
|
478
|
+
skip_mmd=skip_mmd,
|
|
479
|
+
skip_timeline=skip_timeline,
|
|
480
|
+
)
|
|
481
|
+
if output:
|
|
482
|
+
output_dir = output
|
|
483
|
+
EventsMixin.do_print("<Waldiez> - Done running the flow.")
|
|
596
484
|
if sys.path[0] == str(temp_dir):
|
|
597
485
|
sys.path.pop(0)
|
|
598
|
-
return results
|
|
486
|
+
return self.get_results(results, output_dir)
|
|
599
487
|
|
|
600
488
|
async def a_prepare(
|
|
601
489
|
self,
|
|
@@ -625,11 +513,11 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
625
513
|
uploads_root=uploads_root_path,
|
|
626
514
|
)
|
|
627
515
|
await self.a_install_requirements()
|
|
628
|
-
refresh_environment()
|
|
629
516
|
return temp_dir, output_file, uploads_root_path
|
|
630
517
|
|
|
631
518
|
# noinspection DuplicatedCode
|
|
632
519
|
# noinspection PyProtocol
|
|
520
|
+
@override
|
|
633
521
|
async def a_run(
|
|
634
522
|
self,
|
|
635
523
|
output_path: str | Path | None = None,
|
|
@@ -685,7 +573,9 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
685
573
|
uploads_root=uploads_root,
|
|
686
574
|
)
|
|
687
575
|
WaldiezBaseRunner._running = True
|
|
688
|
-
results: list[dict[str, Any]]
|
|
576
|
+
results: list[dict[str, Any]] = []
|
|
577
|
+
error: BaseException | None = None
|
|
578
|
+
output_dir = output_file.parent
|
|
689
579
|
old_env_vars = set_env_vars(self._waldiez.get_flow_env_vars())
|
|
690
580
|
try:
|
|
691
581
|
async with a_chdir(to=temp_dir):
|
|
@@ -698,39 +588,49 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
698
588
|
skip_timeline=skip_timeline,
|
|
699
589
|
)
|
|
700
590
|
except (SystemExit, StopRunningException, KeyboardInterrupt) as exc:
|
|
591
|
+
self.log.warning("Execution stopped: %s", exc)
|
|
592
|
+
error = exc
|
|
701
593
|
raise StopRunningException(StopRunningException.reason) from exc
|
|
702
594
|
except BaseException as exc: # pylint: disable=broad-exception-caught
|
|
703
|
-
|
|
595
|
+
self.log.error("Error occurred while running workflow: %s", exc)
|
|
596
|
+
error = exc
|
|
704
597
|
finally:
|
|
705
598
|
WaldiezBaseRunner._running = False
|
|
706
599
|
reset_env_vars(old_env_vars)
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
600
|
+
output = await self.a_after_run(
|
|
601
|
+
results=results,
|
|
602
|
+
error=error,
|
|
603
|
+
output_file=output_file,
|
|
604
|
+
uploads_root=uploads_root_path,
|
|
605
|
+
temp_dir=temp_dir,
|
|
606
|
+
skip_mmd=skip_mmd,
|
|
607
|
+
skip_timeline=skip_timeline,
|
|
608
|
+
)
|
|
609
|
+
if output:
|
|
610
|
+
output_dir = output
|
|
715
611
|
if sys.path[0] == str(temp_dir):
|
|
716
612
|
sys.path.pop(0)
|
|
717
|
-
return results
|
|
613
|
+
return await self.a_get_results(results, output_dir)
|
|
718
614
|
|
|
615
|
+
@override
|
|
719
616
|
def after_run(
|
|
720
617
|
self,
|
|
721
618
|
results: list[dict[str, Any]],
|
|
619
|
+
error: BaseException | None,
|
|
722
620
|
output_file: Path,
|
|
723
621
|
uploads_root: Path | None,
|
|
724
622
|
temp_dir: Path,
|
|
725
623
|
skip_mmd: bool,
|
|
726
624
|
skip_timeline: bool,
|
|
727
|
-
) -> None:
|
|
625
|
+
) -> Path | None:
|
|
728
626
|
"""Actions to perform after running the flow.
|
|
729
627
|
|
|
730
628
|
Parameters
|
|
731
629
|
----------
|
|
732
630
|
results : list[dict[str, Any]]
|
|
733
631
|
The results of the flow run.
|
|
632
|
+
error : BaseException | None
|
|
633
|
+
Optional error during the run.
|
|
734
634
|
output_file : Path
|
|
735
635
|
The path to the output file.
|
|
736
636
|
uploads_root : Path | None
|
|
@@ -741,31 +641,42 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
741
641
|
Whether to skip generating the mermaid diagram.
|
|
742
642
|
skip_timeline : bool
|
|
743
643
|
Whether to skip generating the timeline JSON.
|
|
644
|
+
|
|
645
|
+
Returns
|
|
646
|
+
-------
|
|
647
|
+
Path | None
|
|
648
|
+
The destination directory if output file, else None
|
|
744
649
|
"""
|
|
745
|
-
self._after_run(
|
|
650
|
+
return self._after_run(
|
|
746
651
|
results=results,
|
|
652
|
+
error=error,
|
|
747
653
|
output_file=output_file,
|
|
654
|
+
waldiez_file=WaldiezBaseRunner._waldiez_file,
|
|
748
655
|
uploads_root=uploads_root,
|
|
749
656
|
temp_dir=temp_dir,
|
|
750
657
|
skip_mmd=skip_mmd,
|
|
751
658
|
skip_timeline=skip_timeline,
|
|
752
659
|
)
|
|
753
660
|
|
|
661
|
+
@override
|
|
754
662
|
async def a_after_run(
|
|
755
663
|
self,
|
|
756
664
|
results: list[dict[str, Any]],
|
|
665
|
+
error: BaseException | None,
|
|
757
666
|
output_file: Path,
|
|
758
667
|
uploads_root: Path | None,
|
|
759
668
|
temp_dir: Path,
|
|
760
669
|
skip_mmd: bool,
|
|
761
670
|
skip_timeline: bool,
|
|
762
|
-
) -> None:
|
|
671
|
+
) -> Path | None:
|
|
763
672
|
"""Asynchronously perform actions after running the flow.
|
|
764
673
|
|
|
765
674
|
Parameters
|
|
766
675
|
----------
|
|
767
676
|
results : list[dict[str, Any]]
|
|
768
677
|
The results of the flow run.
|
|
678
|
+
error : BaseException | None
|
|
679
|
+
Optional error during the run.
|
|
769
680
|
output_file : Path
|
|
770
681
|
The path to the output file.
|
|
771
682
|
uploads_root : Path | None
|
|
@@ -776,14 +687,20 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
776
687
|
Whether to skip generating the mermaid diagram.
|
|
777
688
|
skip_timeline : bool
|
|
778
689
|
|
|
690
|
+
Returns
|
|
691
|
+
-------
|
|
692
|
+
Path | None
|
|
693
|
+
The destination directory if output file, else None
|
|
779
694
|
"""
|
|
780
|
-
await self._a_after_run(
|
|
695
|
+
return await self._a_after_run(
|
|
781
696
|
results=results,
|
|
697
|
+
error=error,
|
|
782
698
|
output_file=output_file,
|
|
783
699
|
uploads_root=uploads_root,
|
|
784
700
|
temp_dir=temp_dir,
|
|
785
701
|
skip_mmd=skip_mmd,
|
|
786
702
|
skip_timeline=skip_timeline,
|
|
703
|
+
waldiez_file=WaldiezBaseRunner._waldiez_file,
|
|
787
704
|
)
|
|
788
705
|
|
|
789
706
|
@property
|
|
@@ -791,6 +708,11 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
791
708
|
"""Get the Waldiez instance."""
|
|
792
709
|
return self._waldiez
|
|
793
710
|
|
|
711
|
+
@property
|
|
712
|
+
def waldiez_file(self) -> Path:
|
|
713
|
+
"""Get the path to the waldiez file."""
|
|
714
|
+
return self._waldiez_file
|
|
715
|
+
|
|
794
716
|
@property
|
|
795
717
|
def is_async(self) -> bool:
|
|
796
718
|
"""Check if the workflow is async."""
|
|
@@ -826,11 +748,6 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
826
748
|
"""Get the uploads root path for the runner."""
|
|
827
749
|
return WaldiezBaseRunner._uploads_root
|
|
828
750
|
|
|
829
|
-
@property
|
|
830
|
-
def skip_patch_io(self) -> bool:
|
|
831
|
-
"""Check if the runner is skipping patching IO."""
|
|
832
|
-
return WaldiezBaseRunner._skip_patch_io
|
|
833
|
-
|
|
834
751
|
@classmethod
|
|
835
752
|
def load(
|
|
836
753
|
cls,
|
|
@@ -889,14 +806,7 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
889
806
|
)
|
|
890
807
|
|
|
891
808
|
def stop(self) -> None:
|
|
892
|
-
"""Stop the workflow execution.
|
|
893
|
-
|
|
894
|
-
This method sets the stop flag that will be checked by the event
|
|
895
|
-
handlers and other parts of the workflow execution to gracefully
|
|
896
|
-
terminate the workflow execution.
|
|
897
|
-
Note: Stopping will occur at the "next" AutoGen event, not immediately.
|
|
898
|
-
"""
|
|
899
|
-
self.log.info("Stop requested - setting stop flag")
|
|
809
|
+
"""Stop the workflow execution."""
|
|
900
810
|
self._stop_requested.set()
|
|
901
811
|
|
|
902
812
|
def is_stop_requested(self) -> bool:
|
|
@@ -909,6 +819,10 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
909
819
|
"""
|
|
910
820
|
return self._stop_requested.is_set()
|
|
911
821
|
|
|
822
|
+
def set_stop_requested(self) -> None:
|
|
823
|
+
"""Set the stop requested flag."""
|
|
824
|
+
self._stop_requested.set()
|
|
825
|
+
|
|
912
826
|
def __enter__(self) -> Self:
|
|
913
827
|
"""Enter the context manager."""
|
|
914
828
|
return self
|
|
@@ -919,7 +833,7 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
919
833
|
|
|
920
834
|
def __exit__(
|
|
921
835
|
self,
|
|
922
|
-
exc_type:
|
|
836
|
+
exc_type: type[BaseException],
|
|
923
837
|
exc_value: BaseException,
|
|
924
838
|
traceback: TracebackType,
|
|
925
839
|
) -> None:
|
|
@@ -929,7 +843,7 @@ class WaldiezBaseRunner(WaldiezRunnerProtocol, RequirementsMixin):
|
|
|
929
843
|
|
|
930
844
|
async def __aexit__(
|
|
931
845
|
self,
|
|
932
|
-
exc_type:
|
|
846
|
+
exc_type: type[BaseException],
|
|
933
847
|
exc_value: BaseException,
|
|
934
848
|
traceback: TracebackType,
|
|
935
849
|
) -> None:
|