waldiez 0.6.0__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 +18 -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 +9 -10
- 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 +34 -23
- waldiez/exporting/agent/extras/group_member_extras.py +6 -5
- waldiez/exporting/agent/extras/handoffs/after_work.py +1 -1
- waldiez/exporting/agent/extras/handoffs/available.py +1 -1
- waldiez/exporting/agent/extras/handoffs/condition.py +3 -2
- waldiez/exporting/agent/extras/handoffs/handoff.py +1 -1
- waldiez/exporting/agent/extras/handoffs/target.py +6 -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/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/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 +2 -2
- waldiez/exporting/core/protocols.py +6 -5
- waldiez/exporting/core/result.py +25 -28
- waldiez/exporting/core/types.py +10 -10
- waldiez/exporting/core/utils/llm_config.py +2 -2
- waldiez/exporting/core/validation.py +10 -11
- waldiez/exporting/flow/execution_generator.py +98 -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 +5 -5
- waldiez/exporting/flow/utils/importing.py +6 -7
- waldiez/exporting/flow/utils/linting.py +25 -9
- waldiez/exporting/flow/utils/logging.py +2 -2
- 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 +8 -4
- waldiez/io/_ws.py +10 -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 +52 -53
- waldiez/io/utils.py +3 -0
- waldiez/io/ws.py +5 -1
- waldiez/logger.py +16 -3
- waldiez/models/agents/__init__.py +3 -0
- waldiez/models/agents/agent/agent.py +23 -16
- 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 +27 -20
- waldiez/models/chat/chat_data.py +22 -19
- 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/dict_utils.py +8 -6
- waldiez/models/common/handoff.py +18 -17
- waldiez/models/common/method_utils.py +7 -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 +5 -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 +1 -0
- waldiez/models/tool/predefined/_google.py +1 -0
- waldiez/models/tool/predefined/_perplexity.py +1 -0
- waldiez/models/tool/predefined/_searxng.py +1 -0
- waldiez/models/tool/predefined/_tavily.py +1 -0
- waldiez/models/tool/predefined/_wikipedia.py +1 -0
- 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 +117 -264
- 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 +22 -25
- waldiez/running/step_by_step/breakpoints_mixin.py +192 -60
- waldiez/running/step_by_step/command_handler.py +3 -0
- waldiez/running/step_by_step/events_processor.py +194 -14
- waldiez/running/step_by_step/step_by_step_models.py +110 -43
- waldiez/running/step_by_step/step_by_step_runner.py +107 -57
- waldiez/running/subprocess_runner/__base__.py +9 -1
- waldiez/running/subprocess_runner/_async_runner.py +5 -3
- waldiez/running/subprocess_runner/_sync_runner.py +6 -2
- waldiez/running/subprocess_runner/runner.py +39 -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/_file_handler.py +18 -18
- waldiez/ws/_mock.py +2 -1
- waldiez/ws/cli.py +36 -12
- waldiez/ws/client_manager.py +35 -27
- waldiez/ws/errors.py +3 -0
- waldiez/ws/models.py +43 -52
- waldiez/ws/reloader.py +12 -4
- waldiez/ws/server.py +85 -55
- waldiez/ws/session_manager.py +8 -9
- waldiez/ws/session_stats.py +1 -1
- waldiez/ws/utils.py +4 -1
- {waldiez-0.6.0.dist-info → waldiez-0.6.1.dist-info}/METADATA +82 -93
- waldiez-0.6.1.dist-info/RECORD +254 -0
- waldiez/running/post_run.py +0 -186
- waldiez/running/pre_run.py +0 -281
- waldiez/running/run_results.py +0 -14
- waldiez/running/utils.py +0 -625
- waldiez-0.6.0.dist-info/RECORD +0 -251
- {waldiez-0.6.0.dist-info → waldiez-0.6.1.dist-info}/WHEEL +0 -0
- {waldiez-0.6.0.dist-info → waldiez-0.6.1.dist-info}/entry_points.txt +0 -0
- {waldiez-0.6.0.dist-info → waldiez-0.6.1.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.6.0.dist-info → waldiez-0.6.1.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
# pyright: reportMissingTypeStubs=false
|
|
5
|
+
"""Common utilities for the waldiez runner."""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import sys
|
|
9
|
+
import traceback
|
|
10
|
+
|
|
11
|
+
# noinspection PyProtectedMember
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from getpass import getpass
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import (
|
|
16
|
+
Any,
|
|
17
|
+
Callable,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class ProcessSetup:
|
|
23
|
+
"""Container for subprocess setup data."""
|
|
24
|
+
|
|
25
|
+
temp_dir: Path
|
|
26
|
+
file_path: Path
|
|
27
|
+
old_vars: dict[str, str]
|
|
28
|
+
skip_mmd: bool
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async def input_async(prompt: str, *, password: bool = False) -> str:
|
|
32
|
+
"""Asynchronous input function.
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
prompt : str
|
|
37
|
+
The prompt to display to the user.
|
|
38
|
+
password : bool, optional
|
|
39
|
+
Whether to hide input (password mode), by default False.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
str
|
|
44
|
+
The user input.
|
|
45
|
+
"""
|
|
46
|
+
if password:
|
|
47
|
+
try:
|
|
48
|
+
return await asyncio.to_thread(getpass, prompt)
|
|
49
|
+
except EOFError:
|
|
50
|
+
return ""
|
|
51
|
+
try:
|
|
52
|
+
return await asyncio.to_thread(input, prompt)
|
|
53
|
+
except EOFError:
|
|
54
|
+
return ""
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def input_sync(prompt: str, *, password: bool = False) -> str:
|
|
58
|
+
"""Input function (synchronous).
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
prompt : str
|
|
63
|
+
The prompt to display to the user.
|
|
64
|
+
password : bool, optional
|
|
65
|
+
Whether to hide input (password mode), by default False.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
str
|
|
70
|
+
The user input.
|
|
71
|
+
"""
|
|
72
|
+
if password:
|
|
73
|
+
try:
|
|
74
|
+
return getpass(prompt)
|
|
75
|
+
except EOFError:
|
|
76
|
+
return ""
|
|
77
|
+
try:
|
|
78
|
+
return input(prompt)
|
|
79
|
+
except EOFError:
|
|
80
|
+
return ""
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# pylint: disable=import-outside-toplevel,too-complex
|
|
84
|
+
def get_printer() -> Callable[..., None]: # noqa: C901
|
|
85
|
+
"""Get the printer function.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
Callable[..., None]
|
|
90
|
+
The printer function that handles Unicode encoding errors gracefully.
|
|
91
|
+
"""
|
|
92
|
+
try:
|
|
93
|
+
# noinspection PyUnresolvedReferences
|
|
94
|
+
from autogen.io import IOStream # type: ignore
|
|
95
|
+
|
|
96
|
+
printer = IOStream.get_default().print
|
|
97
|
+
except ImportError: # pragma: no cover
|
|
98
|
+
# Fallback to standard print if autogen is not available
|
|
99
|
+
printer = print
|
|
100
|
+
|
|
101
|
+
# noinspection PyBroadException,TryExceptPass
|
|
102
|
+
def safe_printer(*args: Any, **kwargs: Any) -> None: # noqa: C901
|
|
103
|
+
"""Safe printer that handles Unicode encoding errors.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
*args : Any
|
|
108
|
+
Arguments to pass to the printer
|
|
109
|
+
**kwargs : Any
|
|
110
|
+
Keyword arguments to pass to the printer
|
|
111
|
+
"""
|
|
112
|
+
# pylint: disable=broad-exception-caught,too-many-try-statements
|
|
113
|
+
try:
|
|
114
|
+
printer(*args, **kwargs)
|
|
115
|
+
except (UnicodeEncodeError, UnicodeDecodeError):
|
|
116
|
+
# First fallback: try to get a safe string representation
|
|
117
|
+
try:
|
|
118
|
+
msg, flush = get_what_to_print(*args, **kwargs)
|
|
119
|
+
# Convert problematic characters to safe representations
|
|
120
|
+
safe_msg = msg.encode("utf-8", errors="replace").decode("utf-8")
|
|
121
|
+
printer(safe_msg, end="", flush=flush)
|
|
122
|
+
except (UnicodeEncodeError, UnicodeDecodeError):
|
|
123
|
+
# Second fallback: use built-in print with safe encoding
|
|
124
|
+
try:
|
|
125
|
+
# Convert args to safe string representations
|
|
126
|
+
safe_args: list[str] = []
|
|
127
|
+
for arg in args:
|
|
128
|
+
try:
|
|
129
|
+
safe_args.append(
|
|
130
|
+
str(arg)
|
|
131
|
+
.encode("utf-8", errors="replace")
|
|
132
|
+
.decode("utf-8")
|
|
133
|
+
)
|
|
134
|
+
except (
|
|
135
|
+
UnicodeEncodeError,
|
|
136
|
+
UnicodeDecodeError,
|
|
137
|
+
): # pragma: no cover
|
|
138
|
+
safe_args.append(repr(arg))
|
|
139
|
+
|
|
140
|
+
# Use built-in print instead of the custom printer
|
|
141
|
+
print(*safe_args, **kwargs)
|
|
142
|
+
|
|
143
|
+
except Exception:
|
|
144
|
+
# Final fallback: write directly to stderr buffer
|
|
145
|
+
error_msg = (
|
|
146
|
+
"Could not print the message due to encoding issues.\n"
|
|
147
|
+
)
|
|
148
|
+
to_sys_stderr(error_msg)
|
|
149
|
+
except Exception as e:
|
|
150
|
+
# Handle any other unexpected errors
|
|
151
|
+
traceback.print_exc()
|
|
152
|
+
error_msg = f"Unexpected error in printer: {str(e)}\n"
|
|
153
|
+
to_sys_stderr(error_msg)
|
|
154
|
+
|
|
155
|
+
return safe_printer
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def to_sys_stderr(msg: str) -> None:
|
|
159
|
+
"""Write a message to sys.stderr.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
msg : str
|
|
164
|
+
The message to write to stderr.
|
|
165
|
+
"""
|
|
166
|
+
# pylint: disable=broad-exception-caught
|
|
167
|
+
# noinspection TryExceptPass,PyBroadException
|
|
168
|
+
try:
|
|
169
|
+
if hasattr(sys.stderr, "buffer"):
|
|
170
|
+
sys.stderr.buffer.write(msg.encode("utf-8", errors="replace"))
|
|
171
|
+
sys.stderr.buffer.flush()
|
|
172
|
+
else: # pragma: no cover
|
|
173
|
+
sys.stderr.write(msg)
|
|
174
|
+
sys.stderr.flush()
|
|
175
|
+
except Exception: # pragma: no cover
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def get_what_to_print(*args: Any, **kwargs: Any) -> tuple[str, bool]:
|
|
180
|
+
"""Extract message and flush flag from print arguments.
|
|
181
|
+
|
|
182
|
+
Parameters
|
|
183
|
+
----------
|
|
184
|
+
*args : Any
|
|
185
|
+
Arguments to print
|
|
186
|
+
**kwargs : Any
|
|
187
|
+
Keyword arguments for print function
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
tuple[str, bool]
|
|
192
|
+
Message to print and flush flag
|
|
193
|
+
"""
|
|
194
|
+
# Convert all args to strings and join with spaces (like print does)
|
|
195
|
+
msg = " ".join(str(arg) for arg in args)
|
|
196
|
+
|
|
197
|
+
# Handle sep parameter
|
|
198
|
+
sep = kwargs.get("sep", " ")
|
|
199
|
+
if isinstance(sep, bytes): # pragma: no cover
|
|
200
|
+
sep = sep.decode("utf-8", errors="replace")
|
|
201
|
+
if len(args) > 1:
|
|
202
|
+
msg = sep.join(str(arg) for arg in args)
|
|
203
|
+
|
|
204
|
+
# Handle end parameter
|
|
205
|
+
end = kwargs.get("end", "\n")
|
|
206
|
+
if isinstance(end, bytes): # pragma: no cover
|
|
207
|
+
end = end.decode("utf-8", errors="replace")
|
|
208
|
+
msg += end
|
|
209
|
+
|
|
210
|
+
# Handle flush parameter
|
|
211
|
+
flush = kwargs.get("flush", False)
|
|
212
|
+
# noinspection PyUnreachableCode
|
|
213
|
+
if not isinstance(flush, bool): # pragma: no cover
|
|
214
|
+
flush = False
|
|
215
|
+
|
|
216
|
+
return msg, flush
|
waldiez/running/protocol.py
CHANGED
|
@@ -15,7 +15,7 @@ class WaldiezRunnerProtocol(Protocol):
|
|
|
15
15
|
self,
|
|
16
16
|
output_file: Path,
|
|
17
17
|
uploads_root: Path | None,
|
|
18
|
-
) -> Path:
|
|
18
|
+
) -> Path:
|
|
19
19
|
"""Actions to perform before running the flow.
|
|
20
20
|
|
|
21
21
|
Parameters
|
|
@@ -35,7 +35,7 @@ class WaldiezRunnerProtocol(Protocol):
|
|
|
35
35
|
self,
|
|
36
36
|
output_file: Path,
|
|
37
37
|
uploads_root: Path | None,
|
|
38
|
-
) -> Path:
|
|
38
|
+
) -> Path:
|
|
39
39
|
"""Asynchronously perform actions before running the flow.
|
|
40
40
|
|
|
41
41
|
Parameters
|
|
@@ -136,18 +136,21 @@ class WaldiezRunnerProtocol(Protocol):
|
|
|
136
136
|
def after_run(
|
|
137
137
|
self,
|
|
138
138
|
results: list[dict[str, Any]],
|
|
139
|
+
error: BaseException | None,
|
|
139
140
|
output_file: Path,
|
|
140
141
|
uploads_root: Path | None,
|
|
141
142
|
temp_dir: Path,
|
|
142
143
|
skip_mmd: bool,
|
|
143
144
|
skip_timeline: bool,
|
|
144
|
-
) -> None:
|
|
145
|
+
) -> Path | None:
|
|
145
146
|
"""Actions to perform after running the flow.
|
|
146
147
|
|
|
147
148
|
Parameters
|
|
148
149
|
----------
|
|
149
150
|
results : list[dict[str, Any]]
|
|
150
151
|
The results of the run.
|
|
152
|
+
error : BaseException | None
|
|
153
|
+
Optional error during the run.
|
|
151
154
|
output_file : Path
|
|
152
155
|
The path to the output file.
|
|
153
156
|
uploads_root : Path | None
|
|
@@ -163,18 +166,21 @@ class WaldiezRunnerProtocol(Protocol):
|
|
|
163
166
|
async def a_after_run(
|
|
164
167
|
self,
|
|
165
168
|
results: list[dict[str, Any]],
|
|
169
|
+
error: BaseException | None,
|
|
166
170
|
output_file: Path,
|
|
167
171
|
uploads_root: Path | None,
|
|
168
172
|
temp_dir: Path,
|
|
169
173
|
skip_mmd: bool,
|
|
170
174
|
skip_timeline: bool,
|
|
171
|
-
) -> None:
|
|
175
|
+
) -> Path | None:
|
|
172
176
|
"""Asynchronously perform actions after running the flow.
|
|
173
177
|
|
|
174
178
|
Parameters
|
|
175
179
|
----------
|
|
176
180
|
results : list[dict[str, Any]]
|
|
177
181
|
The results of the run.
|
|
182
|
+
error : BaseException | None
|
|
183
|
+
Optional error during the run.
|
|
178
184
|
output_file : Path
|
|
179
185
|
The path to the output file.
|
|
180
186
|
uploads_root : Path | None
|
|
@@ -187,7 +193,7 @@ class WaldiezRunnerProtocol(Protocol):
|
|
|
187
193
|
Whether to skip generating the timeline JSON.
|
|
188
194
|
"""
|
|
189
195
|
|
|
190
|
-
def is_running(self) -> bool:
|
|
196
|
+
def is_running(self) -> bool:
|
|
191
197
|
"""Check if the runner is currently running.
|
|
192
198
|
|
|
193
199
|
Returns
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
# pyright: reportUninitializedInstanceVariable=false
|
|
5
|
+
"""Actions to perform before running the flow."""
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Callable
|
|
9
|
+
|
|
10
|
+
from waldiez.models import Waldiez
|
|
11
|
+
from waldiez.utils.python_manager import PythonManager
|
|
12
|
+
|
|
13
|
+
from .environment import refresh_environment
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RequirementsMixin:
|
|
17
|
+
"""Mixin class to handle requirements installation."""
|
|
18
|
+
|
|
19
|
+
_waldiez: Waldiez
|
|
20
|
+
_called_install_requirements: bool
|
|
21
|
+
print: Callable[..., None]
|
|
22
|
+
|
|
23
|
+
def __init__(self) -> None:
|
|
24
|
+
"""Initialize the instance."""
|
|
25
|
+
self._python_manager = PythonManager()
|
|
26
|
+
|
|
27
|
+
def gather_requirements(self) -> set[str]:
|
|
28
|
+
"""Gather extra requirements to install before running the flow.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
set[str]
|
|
33
|
+
A set of requirements that are not already installed and do not
|
|
34
|
+
include 'waldiez' in their name.
|
|
35
|
+
"""
|
|
36
|
+
extra_requirements = {
|
|
37
|
+
req
|
|
38
|
+
for req in self._waldiez.requirements
|
|
39
|
+
if req not in sys.modules and "waldiez" not in req
|
|
40
|
+
}
|
|
41
|
+
if "python-dotenv" not in extra_requirements: # pragma: no branch
|
|
42
|
+
extra_requirements.add("python-dotenv")
|
|
43
|
+
return extra_requirements
|
|
44
|
+
|
|
45
|
+
def install_requirements(self) -> None:
|
|
46
|
+
"""Install the requirements for the flow."""
|
|
47
|
+
if not self._called_install_requirements: # pragma: no branch
|
|
48
|
+
self._called_install_requirements = True
|
|
49
|
+
extra_requirements = self.gather_requirements()
|
|
50
|
+
if extra_requirements: # pragma: no branch
|
|
51
|
+
self._python_manager.pip_install(
|
|
52
|
+
extra_requirements, printer=self.print
|
|
53
|
+
)
|
|
54
|
+
refresh_environment()
|
|
55
|
+
|
|
56
|
+
async def a_install_requirements(self) -> None:
|
|
57
|
+
"""Install the requirements for the flow asynchronously."""
|
|
58
|
+
if not self._called_install_requirements: # pragma: no branch
|
|
59
|
+
self._called_install_requirements = True
|
|
60
|
+
extra_requirements = self.gather_requirements()
|
|
61
|
+
if extra_requirements: # pragma: no branch
|
|
62
|
+
await self._python_manager.a_pip_install(
|
|
63
|
+
extra_requirements, printer=self.print
|
|
64
|
+
)
|
|
65
|
+
refresh_environment()
|