waldiez 0.4.9__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of waldiez might be problematic. Click here for more details.
- waldiez/__init__.py +1 -2
- waldiez/_version.py +1 -1
- waldiez/cli.py +65 -58
- waldiez/exporter.py +64 -9
- waldiez/exporting/agent/extras/group_manager_agent_extas.py +1 -1
- waldiez/exporting/core/context.py +12 -0
- waldiez/exporting/core/extras/flow_extras.py +2 -14
- waldiez/exporting/core/types.py +21 -0
- waldiez/exporting/flow/exporter.py +4 -0
- waldiez/exporting/flow/factory.py +16 -0
- waldiez/exporting/flow/orchestrator.py +12 -0
- waldiez/exporting/flow/utils/__init__.py +2 -0
- waldiez/exporting/flow/utils/common.py +96 -2
- waldiez/exporting/flow/utils/logging.py +5 -6
- waldiez/io/mqtt.py +7 -3
- waldiez/io/structured.py +5 -1
- waldiez/models/common/method_utils.py +1 -1
- waldiez/models/tool/tool.py +2 -1
- waldiez/runner.py +402 -321
- waldiez/running/__init__.py +6 -34
- waldiez/running/base_runner.py +907 -0
- waldiez/running/environment.py +74 -0
- waldiez/running/import_runner.py +424 -0
- waldiez/running/patch_io_stream.py +208 -0
- waldiez/running/post_run.py +26 -24
- waldiez/running/pre_run.py +2 -46
- waldiez/running/protocol.py +281 -0
- waldiez/running/run_results.py +22 -0
- waldiez/running/subprocess_runner.py +100 -0
- waldiez/utils/__init__.py +0 -4
- waldiez/utils/version.py +4 -2
- {waldiez-0.4.9.dist-info → waldiez-0.5.0.dist-info}/METADATA +39 -113
- {waldiez-0.4.9.dist-info → waldiez-0.5.0.dist-info}/RECORD +42 -37
- waldiez/utils/flaml_warnings.py +0 -17
- /waldiez/{utils/cli_extras → cli_extras}/__init__.py +0 -0
- /waldiez/{utils/cli_extras → cli_extras}/jupyter.py +0 -0
- /waldiez/{utils/cli_extras → cli_extras}/runner.py +0 -0
- /waldiez/{utils/cli_extras → cli_extras}/studio.py +0 -0
- /waldiez/running/{util.py → utils.py} +0 -0
- {waldiez-0.4.9.dist-info → waldiez-0.5.0.dist-info}/WHEEL +0 -0
- {waldiez-0.4.9.dist-info → waldiez-0.5.0.dist-info}/entry_points.txt +0 -0
- {waldiez-0.4.9.dist-info → waldiez-0.5.0.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.4.9.dist-info → waldiez-0.5.0.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
# flake8: noqa: E501
|
|
5
5
|
"""Common utils for the final generatio."""
|
|
6
6
|
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
7
9
|
from waldiez.models import Waldiez
|
|
8
10
|
|
|
9
11
|
from ...core import FILE_HEADER
|
|
@@ -151,7 +153,7 @@ def get_after_run_content(
|
|
|
151
153
|
if agent.is_reasoning:
|
|
152
154
|
agent_name = agent_names[agent.id]
|
|
153
155
|
content += f"""
|
|
154
|
-
{space}# pylint: disable=broad-
|
|
156
|
+
{space}# pylint: disable=broad-exception-caught,too-many-try-statements
|
|
155
157
|
{space}try:
|
|
156
158
|
{space}{tab}{agent_name}.visualize_tree()
|
|
157
159
|
{space}{tab}if os.path.exists("tree_of_thoughts.png"):
|
|
@@ -160,8 +162,9 @@ def get_after_run_content(
|
|
|
160
162
|
{space}except BaseException:
|
|
161
163
|
{space}{tab}pass
|
|
162
164
|
{space}# save the tree to json
|
|
165
|
+
{space}# pylint: disable=protected-access
|
|
163
166
|
{space}try:
|
|
164
|
-
{space}{tab}data = {agent_name}._root.to_dict() #
|
|
167
|
+
{space}{tab}data = {agent_name}._root.to_dict() # pyright: ignore
|
|
165
168
|
{space}{tab}with open("{agent_name}_reasoning_tree.json", "w", encoding="utf-8") as f:
|
|
166
169
|
{space}{tab}{tab}json.dump(data, f)
|
|
167
170
|
{space}except BaseException:
|
|
@@ -204,3 +207,94 @@ if not hasattr(np, "_no_pep50_warning"):
|
|
|
204
207
|
setattr(np, "_no_pep50_warning", _np_no_nep50_warning) # noqa
|
|
205
208
|
'''
|
|
206
209
|
return content
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def get_set_io_stream(
|
|
213
|
+
use_structured_io: bool,
|
|
214
|
+
is_async: bool,
|
|
215
|
+
uploads_root: Path | None,
|
|
216
|
+
) -> str:
|
|
217
|
+
"""Get the content to set structured IO.
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
use_structured_io : bool
|
|
222
|
+
Whether to use structured IO or not.
|
|
223
|
+
is_async : bool
|
|
224
|
+
Whether the flow is async or not.
|
|
225
|
+
uploads_root : Path | None
|
|
226
|
+
The uploads root, to get user-uploaded files, by default None.
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
str
|
|
231
|
+
The content to set structured IO.
|
|
232
|
+
"""
|
|
233
|
+
if use_structured_io:
|
|
234
|
+
return get_set_structured_io_stream(
|
|
235
|
+
is_async=is_async,
|
|
236
|
+
uploads_root=uploads_root,
|
|
237
|
+
)
|
|
238
|
+
return get_patch_default_io_stream(is_async)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def get_set_structured_io_stream(
|
|
242
|
+
is_async: bool,
|
|
243
|
+
uploads_root: Path | None,
|
|
244
|
+
) -> str:
|
|
245
|
+
"""Get the content to set structured IO.
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
is_async : bool
|
|
250
|
+
Whether the flow is async or not.
|
|
251
|
+
uploads_root : Path | None
|
|
252
|
+
The uploads root, to get user-uploaded files, by default None.
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
str
|
|
257
|
+
The content to set structured IO.
|
|
258
|
+
"""
|
|
259
|
+
upload_root_arg = f'r"{uploads_root}"' if uploads_root else "None"
|
|
260
|
+
return f"""
|
|
261
|
+
# set structured IO
|
|
262
|
+
try:
|
|
263
|
+
# pylint: disable=import-outside-toplevel
|
|
264
|
+
from autogen.io import IOStream
|
|
265
|
+
from waldiez.io import StructuredIOStream
|
|
266
|
+
stream = StructuredIOStream(
|
|
267
|
+
is_async={is_async},
|
|
268
|
+
uploads_root={upload_root_arg}
|
|
269
|
+
)
|
|
270
|
+
IOStream.set_default(stream)
|
|
271
|
+
except BaseException: # pylint: disable=broad-exception-caught
|
|
272
|
+
# allow running the flow without structured IO
|
|
273
|
+
pass
|
|
274
|
+
"""
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def get_patch_default_io_stream(is_async: bool) -> str:
|
|
278
|
+
"""Get the content to patch the default IO stream.
|
|
279
|
+
|
|
280
|
+
Parameters
|
|
281
|
+
----------
|
|
282
|
+
is_async : bool
|
|
283
|
+
Whether the flow is async or not.
|
|
284
|
+
|
|
285
|
+
Returns
|
|
286
|
+
-------
|
|
287
|
+
str
|
|
288
|
+
The content to patch the default IO stream.
|
|
289
|
+
"""
|
|
290
|
+
# copy from waldiez/running/patch_io_stream.py
|
|
291
|
+
return f"""
|
|
292
|
+
# patch the default IOStream
|
|
293
|
+
try:
|
|
294
|
+
# pylint: disable=import-outside-toplevel
|
|
295
|
+
from waldiez.running.patch_io_stream import patch_io_stream
|
|
296
|
+
patch_io_stream(is_async={is_async})
|
|
297
|
+
except BaseException: # pylint: disable=broad-exception-caught
|
|
298
|
+
# allow running the flow without patching the IOStream
|
|
299
|
+
pass
|
|
300
|
+
"""
|
|
@@ -193,7 +193,7 @@ def get_async_sqlite_out() -> str:
|
|
|
193
193
|
query = f"SELECT * FROM {table}" # nosec
|
|
194
194
|
try:
|
|
195
195
|
cursor = await conn.execute(query)
|
|
196
|
-
except BaseException: # pylint: disable=broad-
|
|
196
|
+
except BaseException: # pylint: disable=broad-exception-caught
|
|
197
197
|
await conn.close()
|
|
198
198
|
return
|
|
199
199
|
rows = await cursor.fetchall()
|
|
@@ -210,6 +210,7 @@ def get_async_sqlite_out() -> str:
|
|
|
210
210
|
await file.write(json.dumps(data, indent=4, ensure_ascii=False)
|
|
211
211
|
```
|
|
212
212
|
"""
|
|
213
|
+
# fmt: off
|
|
213
214
|
content = "\n\n"
|
|
214
215
|
content += "async def get_sqlite_out(dbname: str, table: str, csv_file: str) -> None:\n"
|
|
215
216
|
content += ' """Convert a sqlite table to csv and json files.\n\n'
|
|
@@ -226,7 +227,7 @@ def get_async_sqlite_out() -> str:
|
|
|
226
227
|
content += ' query = f"SELECT * FROM {table}" # nosec\n'
|
|
227
228
|
content += " try:\n"
|
|
228
229
|
content += " cursor = await conn.execute(query)\n"
|
|
229
|
-
content += " except BaseException: # pylint: disable=broad-
|
|
230
|
+
content += " except BaseException: # pylint: disable=broad-exception-caught\n"
|
|
230
231
|
content += " await conn.close()\n"
|
|
231
232
|
content += " return\n"
|
|
232
233
|
content += " rows = await cursor.fetchall()\n"
|
|
@@ -235,10 +236,7 @@ def get_async_sqlite_out() -> str:
|
|
|
235
236
|
content += " data = [dict(zip(column_names, row)) for row in rows]\n"
|
|
236
237
|
content += " await cursor.close()\n"
|
|
237
238
|
content += " await conn.close()\n"
|
|
238
|
-
content += (
|
|
239
|
-
' async with aiofiles.open(csv_file, "w", newline="", '
|
|
240
|
-
'encoding="utf-8") as file:\n'
|
|
241
|
-
)
|
|
239
|
+
content += ' async with aiofiles.open(csv_file, "w", newline="", encoding="utf-8") as file:\n'
|
|
242
240
|
content += ' csv_writer = AsyncDictWriter(file, fieldnames=column_names, dialect="unix")\n'
|
|
243
241
|
content += " await csv_writer.writeheader()\n"
|
|
244
242
|
content += " await csv_writer.writerows(data)\n"
|
|
@@ -246,6 +244,7 @@ def get_async_sqlite_out() -> str:
|
|
|
246
244
|
content += ' async with aiofiles.open(json_file, "w", encoding="utf-8") as file:\n'
|
|
247
245
|
content += " await file.write(json.dumps(data, indent=4, ensure_ascii=False))\n"
|
|
248
246
|
content += "\n"
|
|
247
|
+
# fmt: on
|
|
249
248
|
return content
|
|
250
249
|
|
|
251
250
|
|
waldiez/io/mqtt.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# flake8: noqa: E501
|
|
5
5
|
# pylint: disable=too-many-try-statements,broad-exception-caught,
|
|
6
6
|
# pylint: disable=line-too-long,unused-argument,too-many-instance-attributes
|
|
7
|
-
# pylint: disable=too-many-arguments,too-many-positional-arguments
|
|
7
|
+
# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-locals
|
|
8
8
|
|
|
9
9
|
"""An MQTT I/O stream for handling print and input messages."""
|
|
10
10
|
|
|
@@ -82,6 +82,7 @@ class MqttIOStream(IOStream):
|
|
|
82
82
|
broker_port: int = 1883,
|
|
83
83
|
task_id: str | None = None,
|
|
84
84
|
input_timeout: int = 120,
|
|
85
|
+
connect_timeout: int = 10,
|
|
85
86
|
max_retain_messages: int = 1000,
|
|
86
87
|
on_input_request: Optional[Callable[[str, str, str], None]] = None,
|
|
87
88
|
on_input_response: Optional[Callable[[str, str], None]] = None,
|
|
@@ -104,6 +105,8 @@ class MqttIOStream(IOStream):
|
|
|
104
105
|
An ID to use for the topics. If not provided, a random UUID will be generated.
|
|
105
106
|
input_timeout : int, optional
|
|
106
107
|
The time to wait for user input in seconds, by default 120.
|
|
108
|
+
connect_timeout : int, optional
|
|
109
|
+
The time to wait for MQTT connection in seconds, by default 10.
|
|
107
110
|
on_input_request : Optional[Callable[[str, str, str], None]], optional
|
|
108
111
|
Callback for input request, by default None
|
|
109
112
|
parameters: prompt, request_id, task_id
|
|
@@ -129,6 +132,7 @@ class MqttIOStream(IOStream):
|
|
|
129
132
|
self.broker_port = broker_port
|
|
130
133
|
self.task_id = task_id or uuid.uuid4().hex
|
|
131
134
|
self.input_timeout = input_timeout
|
|
135
|
+
self.connect_timeout = connect_timeout
|
|
132
136
|
self.on_input_request = on_input_request
|
|
133
137
|
self.on_input_response = on_input_response
|
|
134
138
|
self.max_retain_messages = max_retain_messages
|
|
@@ -191,7 +195,7 @@ class MqttIOStream(IOStream):
|
|
|
191
195
|
self.client.loop_start()
|
|
192
196
|
|
|
193
197
|
# Wait for connection
|
|
194
|
-
timeout =
|
|
198
|
+
timeout = self.connect_timeout # seconds
|
|
195
199
|
start_time = time.time()
|
|
196
200
|
while (
|
|
197
201
|
not self.client.is_connected()
|
|
@@ -280,7 +284,7 @@ class MqttIOStream(IOStream):
|
|
|
280
284
|
while reconnect_count < MQTT_MAX_RECONNECT_COUNT:
|
|
281
285
|
LOG.info("Reconnecting in %d seconds...", reconnect_delay)
|
|
282
286
|
time.sleep(reconnect_delay)
|
|
283
|
-
# pylint: disable=broad-
|
|
287
|
+
# pylint: disable=broad-exception-caught
|
|
284
288
|
try:
|
|
285
289
|
client.reconnect()
|
|
286
290
|
except Exception as err:
|
waldiez/io/structured.py
CHANGED
|
@@ -101,7 +101,11 @@ class StructuredIOStream(IOStream):
|
|
|
101
101
|
The line read from the input stream.
|
|
102
102
|
"""
|
|
103
103
|
request_id = uuid4().hex
|
|
104
|
-
prompt = prompt or ">
|
|
104
|
+
prompt = prompt or ">"
|
|
105
|
+
if not prompt or prompt in [">", "> "]:
|
|
106
|
+
# if the prompt is just ">" or "> ",
|
|
107
|
+
# let's use a more descriptive one
|
|
108
|
+
prompt = "Enter your message to start the conversation: "
|
|
105
109
|
|
|
106
110
|
self._send_input_request(prompt, request_id, password)
|
|
107
111
|
user_input_raw = self._read_user_input(prompt, password, request_id)
|
waldiez/models/tool/tool.py
CHANGED
|
@@ -137,9 +137,10 @@ class WaldiezTool(WaldiezBase):
|
|
|
137
137
|
raise FileNotFoundError(f"File not found: {resolved}")
|
|
138
138
|
with resolved.open("r", encoding="utf-8") as file:
|
|
139
139
|
data_string = file.read()
|
|
140
|
+
# pylint: disable=broad-exception-caught
|
|
140
141
|
try:
|
|
141
142
|
data_dict = json.loads(data_string)
|
|
142
|
-
except BaseException as exc:
|
|
143
|
+
except BaseException as exc:
|
|
143
144
|
raise ValueError(f"Invalid WaldiezTool/JSON: {exc}") from exc
|
|
144
145
|
return WaldiezTool.model_validate(data_dict)
|
|
145
146
|
|