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
|
@@ -50,6 +50,10 @@ class BaseSubprocessRunner:
|
|
|
50
50
|
self.dot_env = dot_env
|
|
51
51
|
self.logger = logger or logging.getLogger(self.__class__.__name__)
|
|
52
52
|
self.waiting_for_input = False
|
|
53
|
+
breakpoints = kwargs.get("breakpoints", [])
|
|
54
|
+
if not isinstance(breakpoints, list):
|
|
55
|
+
breakpoints = []
|
|
56
|
+
self.breakpoints: list[str] = breakpoints
|
|
53
57
|
|
|
54
58
|
def build_command(
|
|
55
59
|
self,
|
|
@@ -110,6 +114,10 @@ class BaseSubprocessRunner:
|
|
|
110
114
|
if self.dot_env:
|
|
111
115
|
cmd.extend(["--dot-env", str(self.dot_env)])
|
|
112
116
|
|
|
117
|
+
if self.breakpoints:
|
|
118
|
+
for entry in self.breakpoints:
|
|
119
|
+
cmd.extend(["--breakpoints", entry])
|
|
120
|
+
self.logger.debug("Runner command: %s", " ".join(cmd))
|
|
113
121
|
return cmd
|
|
114
122
|
|
|
115
123
|
def parse_output(
|
|
@@ -138,7 +146,7 @@ class BaseSubprocessRunner:
|
|
|
138
146
|
try:
|
|
139
147
|
data = json.loads(line)
|
|
140
148
|
if isinstance(data, dict):
|
|
141
|
-
return data # pyright: ignore
|
|
149
|
+
return data # pyright: ignore[reportUnknownVariableType]
|
|
142
150
|
except json.JSONDecodeError:
|
|
143
151
|
return self.create_output_message(stream=stream, content=line)
|
|
144
152
|
return self.create_output_message(
|
|
@@ -195,7 +203,7 @@ class BaseSubprocessRunner:
|
|
|
195
203
|
def create_input_response(
|
|
196
204
|
self,
|
|
197
205
|
response_type: str,
|
|
198
|
-
user_input:
|
|
206
|
+
user_input: Any,
|
|
199
207
|
request_id: str | None = None,
|
|
200
208
|
) -> str:
|
|
201
209
|
"""Create input response for subprocess.
|
|
@@ -204,7 +212,7 @@ class BaseSubprocessRunner:
|
|
|
204
212
|
----------
|
|
205
213
|
response_type : str
|
|
206
214
|
Type of the response
|
|
207
|
-
user_input :
|
|
215
|
+
user_input : Any
|
|
208
216
|
User's input response
|
|
209
217
|
request_id : str | None
|
|
210
218
|
Request ID from the input request
|
|
@@ -214,15 +222,12 @@ class BaseSubprocessRunner:
|
|
|
214
222
|
str
|
|
215
223
|
JSON-formatted response
|
|
216
224
|
"""
|
|
217
|
-
response = {
|
|
218
|
-
"type": response_type,
|
|
219
|
-
"data": user_input,
|
|
220
|
-
}
|
|
225
|
+
response: dict[str, Any] = {"type": response_type, "data": user_input}
|
|
221
226
|
|
|
222
227
|
if request_id:
|
|
223
228
|
response["request_id"] = request_id
|
|
224
229
|
|
|
225
|
-
return json.dumps(response) + "\n"
|
|
230
|
+
return json.dumps(response, default=str, ensure_ascii=False) + "\n"
|
|
226
231
|
|
|
227
232
|
def create_output_message(
|
|
228
233
|
self, content: str, stream: str = "stdout", msg_type: str = "output"
|
|
@@ -10,8 +10,9 @@ import logging
|
|
|
10
10
|
|
|
11
11
|
# noinspection PyProtectedMember
|
|
12
12
|
from asyncio.subprocess import Process as AsyncProcess
|
|
13
|
+
from collections.abc import Coroutine
|
|
13
14
|
from pathlib import Path
|
|
14
|
-
from typing import Any, Callable,
|
|
15
|
+
from typing import Any, Callable, Literal
|
|
15
16
|
|
|
16
17
|
from .__base__ import BaseSubprocessRunner
|
|
17
18
|
|
|
@@ -57,7 +58,7 @@ class AsyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
57
58
|
)
|
|
58
59
|
self.on_output = on_output
|
|
59
60
|
self.on_input_request = on_input_request
|
|
60
|
-
self.process:
|
|
61
|
+
self.process: AsyncProcess | None = None
|
|
61
62
|
self.input_queue: asyncio.Queue[str] = asyncio.Queue()
|
|
62
63
|
self.output_queue: asyncio.Queue[dict[str, Any]] = asyncio.Queue()
|
|
63
64
|
self._monitor_tasks: list[asyncio.Task[Any]] = []
|
|
@@ -158,7 +159,8 @@ class AsyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
158
159
|
await self.process.wait()
|
|
159
160
|
|
|
160
161
|
except Exception as e:
|
|
161
|
-
|
|
162
|
+
if not isinstance(e, AttributeError):
|
|
163
|
+
self.logger.error(f"Error stopping subprocess: {e}")
|
|
162
164
|
self.process = None
|
|
163
165
|
|
|
164
166
|
async def _start_monitoring(self) -> None:
|
|
@@ -311,7 +313,7 @@ class AsyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
311
313
|
self.process.stdin.write(response.encode())
|
|
312
314
|
await self.process.stdin.drain()
|
|
313
315
|
|
|
314
|
-
self.logger.debug(f"Sent
|
|
316
|
+
self.logger.debug(f"Sent {response_type}: {user_input}")
|
|
315
317
|
|
|
316
318
|
except asyncio.TimeoutError:
|
|
317
319
|
self.logger.warning("Input request timed out")
|
|
@@ -93,6 +93,7 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
93
93
|
stdin=subprocess.PIPE,
|
|
94
94
|
stdout=subprocess.PIPE,
|
|
95
95
|
stderr=subprocess.PIPE,
|
|
96
|
+
encoding="utf-8",
|
|
96
97
|
text=True,
|
|
97
98
|
bufsize=1, # Line buffered
|
|
98
99
|
)
|
|
@@ -175,7 +176,6 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
175
176
|
# Use readline with timeout simulation
|
|
176
177
|
if self.process.stdout.readable(): # pragma: no branch
|
|
177
178
|
line = self.process.stdout.readline()
|
|
178
|
-
|
|
179
179
|
if not line: # pragma: no cover
|
|
180
180
|
time.sleep(0.1)
|
|
181
181
|
continue
|
|
@@ -209,7 +209,7 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
209
209
|
# Use readline with timeout simulation
|
|
210
210
|
if self.process.stderr.readable(): # pragma: no branch
|
|
211
211
|
line = self.process.stderr.readline()
|
|
212
|
-
|
|
212
|
+
self.logger.debug("Stderr line: %s", line)
|
|
213
213
|
if not line:
|
|
214
214
|
time.sleep(0.1)
|
|
215
215
|
continue
|
|
@@ -272,9 +272,11 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
272
272
|
line : str
|
|
273
273
|
Decoded line from stdout
|
|
274
274
|
"""
|
|
275
|
-
|
|
275
|
+
self.logger.debug(f"Stdout line: {line}")
|
|
276
276
|
parsed_data = self.parse_output(line, stream="stdout")
|
|
277
277
|
if not parsed_data:
|
|
278
|
+
self.logger.debug("Non-structured output, forwarding as is")
|
|
279
|
+
self.output_queue.put({"type": "print", "data": line}, timeout=1.0)
|
|
278
280
|
return
|
|
279
281
|
if parsed_data.get("type") in ("input_request", "debug_input_request"):
|
|
280
282
|
prompt = parsed_data.get("prompt", "> ")
|
|
@@ -317,7 +319,7 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
317
319
|
self.process.stdin.write(response)
|
|
318
320
|
self.process.stdin.flush()
|
|
319
321
|
|
|
320
|
-
self.logger.debug(f"Sent
|
|
322
|
+
self.logger.debug(f"Sent {response_type}: {user_input}")
|
|
321
323
|
|
|
322
324
|
except queue.Empty:
|
|
323
325
|
self.logger.warning("Input request timed out")
|
|
@@ -350,8 +352,9 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
350
352
|
f"Thread {thread.name} did not stop gracefully"
|
|
351
353
|
)
|
|
352
354
|
|
|
355
|
+
# pylint: disable=too-complex
|
|
353
356
|
# noinspection TryExceptPass,PyBroadException
|
|
354
|
-
def _cleanup_process(self) -> None:
|
|
357
|
+
def _cleanup_process(self) -> None: # noqa: C901
|
|
355
358
|
"""Cleanup process resources."""
|
|
356
359
|
if self.process:
|
|
357
360
|
if self.process.stdin:
|
|
@@ -380,7 +383,9 @@ class SyncSubprocessRunner(BaseSubprocessRunner):
|
|
|
380
383
|
self.process.kill()
|
|
381
384
|
self.process.wait()
|
|
382
385
|
except BaseException as e:
|
|
383
|
-
|
|
386
|
+
if not isinstance(e, AttributeError):
|
|
387
|
+
# already "None"
|
|
388
|
+
self.logger.error(f"Error stopping subprocess: {e}")
|
|
384
389
|
finally:
|
|
385
390
|
self.process = None
|
|
386
391
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
# pyright: reportAttributeAccessIssue=false,reportUnknownArgumentType=false
|
|
3
5
|
# flake8: noqa: G004
|
|
4
6
|
"""Waldiez subprocess runner that inherits from BaseRunner."""
|
|
5
7
|
|
|
@@ -8,16 +10,17 @@ import re
|
|
|
8
10
|
from pathlib import Path
|
|
9
11
|
from typing import Any, Callable, Literal
|
|
10
12
|
|
|
13
|
+
from typing_extensions import override
|
|
14
|
+
|
|
11
15
|
from waldiez.models import Waldiez
|
|
12
16
|
|
|
13
17
|
from ..base_runner import WaldiezBaseRunner
|
|
18
|
+
from ..step_by_step.breakpoints_mixin import BreakpointsMixin
|
|
14
19
|
from ._async_runner import AsyncSubprocessRunner
|
|
15
20
|
from ._sync_runner import SyncSubprocessRunner
|
|
16
21
|
|
|
17
|
-
# TODO: check output directory and return the results from the JSON logs
|
|
18
|
-
# in self._run and self._a_run
|
|
19
|
-
|
|
20
22
|
|
|
23
|
+
# noinspection PyUnusedLocal
|
|
21
24
|
class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
22
25
|
"""Waldiez runner that uses subprocess execution via standalone runners."""
|
|
23
26
|
|
|
@@ -70,6 +73,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
70
73
|
dot_env=dot_env,
|
|
71
74
|
**kwargs,
|
|
72
75
|
)
|
|
76
|
+
self.breakpoints = self._parse_breakpoints(**kwargs)
|
|
73
77
|
|
|
74
78
|
# Store callbacks
|
|
75
79
|
self.sync_on_output = on_output or self._default_sync_output
|
|
@@ -89,6 +93,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
89
93
|
mode = kwargs.get("mode", "run")
|
|
90
94
|
if mode not in ["run", "debug"]:
|
|
91
95
|
raise ValueError(f"Invalid mode: {mode}")
|
|
96
|
+
# noinspection PyTypeChecker
|
|
92
97
|
self.mode: Literal["run", "debug"] = mode
|
|
93
98
|
waldiez_file = kwargs.get("waldiez_file")
|
|
94
99
|
self._waldiez_file = self._ensure_waldiez_file(waldiez_file)
|
|
@@ -101,19 +106,30 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
101
106
|
return waldiez_file.resolve()
|
|
102
107
|
file_name = self.waldiez.name
|
|
103
108
|
# sanitize file name
|
|
109
|
+
# noinspection RegExpRedundantEscape
|
|
104
110
|
file_name = re.sub(r"[^a-zA-Z0-9_\-\.]", "_", file_name)[:30]
|
|
105
111
|
file_name = f"{file_name}.waldiez"
|
|
106
|
-
with open(file_name, "w", encoding="utf-8") as f:
|
|
112
|
+
with open(file_name, "w", encoding="utf-8", newline="\n") as f:
|
|
107
113
|
f.write(self.waldiez.model_dump_json())
|
|
108
114
|
return Path(file_name).resolve()
|
|
109
115
|
|
|
116
|
+
@staticmethod
|
|
117
|
+
def _parse_breakpoints(**kwargs: Any) -> list[str]:
|
|
118
|
+
initial_breakpoints = kwargs.get("breakpoints")
|
|
119
|
+
if isinstance(initial_breakpoints, (list, set, tuple)):
|
|
120
|
+
breakpoints = BreakpointsMixin.get_initial_breakpoints(
|
|
121
|
+
initial_breakpoints
|
|
122
|
+
)
|
|
123
|
+
return [str(item) for item in breakpoints]
|
|
124
|
+
return []
|
|
125
|
+
|
|
110
126
|
def _default_sync_output(self, data: dict[str, Any]) -> None:
|
|
111
127
|
"""Get the default sync output handler."""
|
|
112
128
|
if data.get("type") == "error":
|
|
113
129
|
self.log.error(data.get("data", ""))
|
|
114
130
|
else:
|
|
115
131
|
content = data.get("data", data)
|
|
116
|
-
self.
|
|
132
|
+
self.print(content)
|
|
117
133
|
|
|
118
134
|
def _default_sync_input_request(self, prompt: str) -> None:
|
|
119
135
|
"""Get the default sync input request handler."""
|
|
@@ -138,6 +154,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
138
154
|
uploads_root=self.uploads_root,
|
|
139
155
|
dot_env=self.dot_env_path,
|
|
140
156
|
logger=self.log,
|
|
157
|
+
breakpoints=self.breakpoints,
|
|
141
158
|
)
|
|
142
159
|
return self.async_runner
|
|
143
160
|
|
|
@@ -150,9 +167,11 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
150
167
|
uploads_root=self.uploads_root,
|
|
151
168
|
dot_env=self.dot_env_path,
|
|
152
169
|
logger=self.log,
|
|
170
|
+
breakpoints=self.breakpoints,
|
|
153
171
|
)
|
|
154
172
|
return self.sync_runner
|
|
155
173
|
|
|
174
|
+
@override
|
|
156
175
|
def run(
|
|
157
176
|
self,
|
|
158
177
|
output_path: str | Path | None = None,
|
|
@@ -217,6 +236,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
217
236
|
return _output_path / f"{filename}.py"
|
|
218
237
|
return self._waldiez_file.with_suffix(".py")
|
|
219
238
|
|
|
239
|
+
@override
|
|
220
240
|
def _run(
|
|
221
241
|
self,
|
|
222
242
|
temp_dir: Path,
|
|
@@ -239,14 +259,8 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
239
259
|
runner = self._create_sync_subprocess_runner()
|
|
240
260
|
|
|
241
261
|
# Run subprocess
|
|
242
|
-
|
|
243
|
-
return
|
|
244
|
-
{
|
|
245
|
-
"success": success,
|
|
246
|
-
"runner": "sync_subprocess",
|
|
247
|
-
"mode": self.mode,
|
|
248
|
-
}
|
|
249
|
-
]
|
|
262
|
+
runner.run_subprocess(self._waldiez_file, mode=self.mode)
|
|
263
|
+
return self.read_from_output(output_file.parent)
|
|
250
264
|
|
|
251
265
|
except Exception as e:
|
|
252
266
|
self.log.error("Error in sync subprocess execution: %s", e)
|
|
@@ -258,6 +272,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
258
272
|
}
|
|
259
273
|
]
|
|
260
274
|
|
|
275
|
+
@override
|
|
261
276
|
async def a_run(
|
|
262
277
|
self,
|
|
263
278
|
output_path: str | Path | None = None,
|
|
@@ -308,6 +323,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
308
323
|
**kwargs,
|
|
309
324
|
)
|
|
310
325
|
|
|
326
|
+
@override
|
|
311
327
|
async def _a_run(
|
|
312
328
|
self,
|
|
313
329
|
temp_dir: Path,
|
|
@@ -353,17 +369,11 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
353
369
|
runner = self._create_async_subprocess_runner()
|
|
354
370
|
|
|
355
371
|
# Run subprocess
|
|
356
|
-
|
|
372
|
+
await runner.run_subprocess(
|
|
357
373
|
self._waldiez_file,
|
|
358
374
|
mode=self.mode,
|
|
359
375
|
)
|
|
360
|
-
return
|
|
361
|
-
{
|
|
362
|
-
"success": success,
|
|
363
|
-
"runner": "async_subprocess",
|
|
364
|
-
"mode": self.mode,
|
|
365
|
-
}
|
|
366
|
-
]
|
|
376
|
+
return await self.a_read_from_output(output_file.parent)
|
|
367
377
|
|
|
368
378
|
except Exception as e:
|
|
369
379
|
self.log.error("Error in async subprocess execution: %s", e)
|
|
@@ -405,6 +415,7 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
405
415
|
self.sync_runner.provide_user_input, user_input
|
|
406
416
|
)
|
|
407
417
|
|
|
418
|
+
@override
|
|
408
419
|
def stop(self) -> None:
|
|
409
420
|
"""Stop the workflow execution."""
|
|
410
421
|
super().stop() # Set the base runner stop flag
|
|
@@ -458,10 +469,13 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
458
469
|
self.sync_runner.stop()
|
|
459
470
|
self.sync_runner = None
|
|
460
471
|
|
|
472
|
+
@override
|
|
461
473
|
def _after_run(
|
|
462
474
|
self,
|
|
463
475
|
results: list[dict[str, Any]],
|
|
476
|
+
error: BaseException | None,
|
|
464
477
|
output_file: Path,
|
|
478
|
+
waldiez_file: Path,
|
|
465
479
|
uploads_root: Path | None,
|
|
466
480
|
temp_dir: Path,
|
|
467
481
|
skip_mmd: bool,
|
|
@@ -472,9 +486,13 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
472
486
|
Parameters
|
|
473
487
|
----------
|
|
474
488
|
results : list[dict[str, Any]]
|
|
475
|
-
Results from the workflow execution
|
|
489
|
+
Results from the workflow execution.
|
|
490
|
+
error : BaseException | None
|
|
491
|
+
Optional error during the run.
|
|
476
492
|
output_file : Path
|
|
477
493
|
Output file path
|
|
494
|
+
waldiez_file : Path
|
|
495
|
+
The waldiez file used/dumped for the run.
|
|
478
496
|
uploads_root : Path | None
|
|
479
497
|
Uploads root directory
|
|
480
498
|
temp_dir : Path
|
|
@@ -487,10 +505,13 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
487
505
|
# Cleanup subprocess runners
|
|
488
506
|
self._cleanup_subprocess_runners()
|
|
489
507
|
|
|
508
|
+
@override
|
|
490
509
|
async def _a_after_run(
|
|
491
510
|
self,
|
|
492
511
|
results: list[dict[str, Any]],
|
|
512
|
+
error: BaseException | None,
|
|
493
513
|
output_file: Path,
|
|
514
|
+
waldiez_file: Path,
|
|
494
515
|
uploads_root: Path | None,
|
|
495
516
|
temp_dir: Path,
|
|
496
517
|
skip_mmd: bool,
|
|
@@ -501,9 +522,13 @@ class WaldiezSubprocessRunner(WaldiezBaseRunner):
|
|
|
501
522
|
Parameters
|
|
502
523
|
----------
|
|
503
524
|
results : list[dict[str, Any]]
|
|
504
|
-
Results from the workflow execution
|
|
525
|
+
Results from the workflow execution.
|
|
526
|
+
error : BaseException | None
|
|
527
|
+
Optional error during the run.
|
|
505
528
|
output_file : Path
|
|
506
529
|
Output file path
|
|
530
|
+
waldiez_file : Path
|
|
531
|
+
The waldiez file used/dumped for the run.
|
|
507
532
|
uploads_root : Path | None
|
|
508
533
|
Uploads root directory
|
|
509
534
|
temp_dir : Path
|
|
@@ -93,7 +93,7 @@ class TimelineProcessor:
|
|
|
93
93
|
bool
|
|
94
94
|
True if the value is missing, NaN, or empty; False otherwise.
|
|
95
95
|
"""
|
|
96
|
-
if pd.isna(value):
|
|
96
|
+
if pd.isna(value):
|
|
97
97
|
return True
|
|
98
98
|
if isinstance(value, str) and (
|
|
99
99
|
value.strip() == "" or value.lower() == "nan"
|
waldiez/utils/__init__.py
CHANGED
|
@@ -15,16 +15,16 @@ __waldiez_checked_conflicts = False
|
|
|
15
15
|
def _check_autogen_agentchat() -> None: # pragma: no cover
|
|
16
16
|
try:
|
|
17
17
|
version("autogen-agentchat")
|
|
18
|
-
|
|
18
|
+
msg = (
|
|
19
19
|
"Conflict detected: 'autogen-agentchat' is installed "
|
|
20
20
|
"in the current environment, \n"
|
|
21
21
|
"which conflicts with 'ag2'.\n"
|
|
22
22
|
"Please uninstall 'autogen-agentchat': \n"
|
|
23
|
-
f"{sys.executable} -m pip uninstall -y autogen-agentchat
|
|
23
|
+
f"{sys.executable} -m pip uninstall -y autogen-agentchat\n"
|
|
24
24
|
"And install 'ag2' (and/or 'waldiez') again: \n"
|
|
25
|
-
f"{sys.executable} -m pip install --force ag2 waldiez"
|
|
26
|
-
file=sys.stderr,
|
|
25
|
+
f"{sys.executable} -m pip install --force ag2 waldiez"
|
|
27
26
|
)
|
|
27
|
+
print(msg, file=sys.stderr)
|
|
28
28
|
sys.exit(1)
|
|
29
29
|
except PackageNotFoundError:
|
|
30
30
|
pass
|