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
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Common utilities for the waldiez runner."""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import functools
|
|
7
|
+
import inspect
|
|
8
|
+
import logging
|
|
9
|
+
import threading
|
|
10
|
+
|
|
11
|
+
# noinspection PyProtectedMember
|
|
12
|
+
from collections.abc import Coroutine
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from typing import (
|
|
15
|
+
Any,
|
|
16
|
+
Callable,
|
|
17
|
+
Generic,
|
|
18
|
+
TypeVar,
|
|
19
|
+
cast,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
T = TypeVar("T")
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class _ResultContainer(Generic[T]):
|
|
29
|
+
"""Container for thread execution results with proper typing."""
|
|
30
|
+
|
|
31
|
+
result: T | None = None
|
|
32
|
+
exception: BaseException | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def is_async_callable(fn: Any) -> bool:
|
|
36
|
+
"""Check if a function is async callable, including partials/callables.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
fn : Any
|
|
41
|
+
The function to check.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
bool
|
|
46
|
+
True if the function is async callable, False otherwise.
|
|
47
|
+
"""
|
|
48
|
+
if isinstance(fn, functools.partial):
|
|
49
|
+
fn = fn.func
|
|
50
|
+
unwrapped = inspect.unwrap(fn)
|
|
51
|
+
return inspect.iscoroutinefunction(
|
|
52
|
+
unwrapped
|
|
53
|
+
) or inspect.iscoroutinefunction(
|
|
54
|
+
getattr(unwrapped, "__call__", None), # noqa: B004
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def syncify(
|
|
59
|
+
async_func: Callable[..., Coroutine[Any, Any, T]],
|
|
60
|
+
timeout: float | None = None,
|
|
61
|
+
) -> Callable[..., T]:
|
|
62
|
+
"""Convert an async function to a sync function.
|
|
63
|
+
|
|
64
|
+
This function handles the conversion of async functions to sync functions,
|
|
65
|
+
properly managing event loops and thread execution contexts.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
async_func : Callable[..., Coroutine[Any, Any, T]]
|
|
70
|
+
The async function to convert.
|
|
71
|
+
timeout : float | None, optional
|
|
72
|
+
The timeout for the sync function. Defaults to None.
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
Callable[..., T]
|
|
77
|
+
The converted sync function.
|
|
78
|
+
|
|
79
|
+
Raises
|
|
80
|
+
------
|
|
81
|
+
TimeoutError
|
|
82
|
+
If the async function times out.
|
|
83
|
+
RuntimeError
|
|
84
|
+
If there are issues with event loop management.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def _sync_wrapper(*args: Any, **kwargs: Any) -> T:
|
|
88
|
+
"""Get the result of the async function."""
|
|
89
|
+
# pylint: disable=too-many-try-statements
|
|
90
|
+
try:
|
|
91
|
+
# Check if we're already in an event loop
|
|
92
|
+
asyncio.get_running_loop()
|
|
93
|
+
return _run_in_thread(async_func, args, kwargs, timeout)
|
|
94
|
+
except RuntimeError:
|
|
95
|
+
# No event loop running, we can use asyncio.run directly
|
|
96
|
+
logger.debug("No event loop running, using asyncio.run")
|
|
97
|
+
|
|
98
|
+
# Create a new event loop and run the coroutine
|
|
99
|
+
try:
|
|
100
|
+
if timeout is not None:
|
|
101
|
+
# Need to run with asyncio.run and wait_for inside
|
|
102
|
+
async def _with_timeout() -> T:
|
|
103
|
+
return await asyncio.wait_for(
|
|
104
|
+
async_func(*args, **kwargs), timeout=timeout
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return asyncio.run(_with_timeout())
|
|
108
|
+
return asyncio.run(async_func(*args, **kwargs))
|
|
109
|
+
except (asyncio.TimeoutError, TimeoutError) as e:
|
|
110
|
+
raise TimeoutError(
|
|
111
|
+
f"Async function timed out after {timeout} seconds"
|
|
112
|
+
) from e
|
|
113
|
+
|
|
114
|
+
return _sync_wrapper
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _run_in_thread(
|
|
118
|
+
async_func: Callable[..., Coroutine[Any, Any, T]],
|
|
119
|
+
args: tuple[Any, ...],
|
|
120
|
+
kwargs: dict[str, Any],
|
|
121
|
+
timeout: float | None,
|
|
122
|
+
) -> T:
|
|
123
|
+
"""Run async function in a separate thread.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
async_func : Callable[..., Coroutine[Any, Any, T]]
|
|
128
|
+
The async function to run.
|
|
129
|
+
args : tuple[Any, ...]
|
|
130
|
+
Positional arguments for the function.
|
|
131
|
+
kwargs : dict[str, Any]
|
|
132
|
+
Keyword arguments for the function.
|
|
133
|
+
timeout : float | None
|
|
134
|
+
Timeout in seconds.
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
T
|
|
139
|
+
The result of the async function.
|
|
140
|
+
|
|
141
|
+
Raises
|
|
142
|
+
------
|
|
143
|
+
TimeoutError
|
|
144
|
+
If the function execution times out.
|
|
145
|
+
RuntimeError
|
|
146
|
+
If thread execution fails unexpectedly.
|
|
147
|
+
"""
|
|
148
|
+
result_container: _ResultContainer[T] = _ResultContainer()
|
|
149
|
+
finished_event = threading.Event()
|
|
150
|
+
|
|
151
|
+
def _thread_target() -> None:
|
|
152
|
+
"""Target function for the thread."""
|
|
153
|
+
# pylint: disable=too-many-try-statements, broad-exception-caught
|
|
154
|
+
try:
|
|
155
|
+
if timeout is not None:
|
|
156
|
+
|
|
157
|
+
async def _with_timeout() -> T:
|
|
158
|
+
return await asyncio.wait_for(
|
|
159
|
+
async_func(*args, **kwargs), timeout=timeout
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
result_container.result = asyncio.run(_with_timeout())
|
|
163
|
+
else:
|
|
164
|
+
result_container.result = asyncio.run(
|
|
165
|
+
async_func(*args, **kwargs)
|
|
166
|
+
)
|
|
167
|
+
except (
|
|
168
|
+
BaseException
|
|
169
|
+
) as e: # Catch BaseException to propagate cancellations
|
|
170
|
+
result_container.exception = e
|
|
171
|
+
finally:
|
|
172
|
+
finished_event.set()
|
|
173
|
+
|
|
174
|
+
thread = threading.Thread(target=_thread_target, daemon=True)
|
|
175
|
+
thread.start()
|
|
176
|
+
|
|
177
|
+
# Wait for completion with timeout
|
|
178
|
+
timeout_buffer = 1.0 # 1 second buffer for cleanup
|
|
179
|
+
wait_timeout = timeout + timeout_buffer if timeout is not None else None
|
|
180
|
+
|
|
181
|
+
if not finished_event.wait(timeout=wait_timeout): # pragma: no cover
|
|
182
|
+
raise TimeoutError(
|
|
183
|
+
f"Function execution timed out after {timeout} seconds"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
thread.join(timeout=timeout_buffer) # Give thread time to clean up
|
|
187
|
+
|
|
188
|
+
if result_container.exception is not None:
|
|
189
|
+
raise result_container.exception
|
|
190
|
+
|
|
191
|
+
# Use cast since we know the result should be T if no exception occurred
|
|
192
|
+
return cast(T, result_container.result)
|