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/models/common/handoff.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
# pylint: disable=invalid-name
|
|
5
|
+
|
|
3
6
|
"""Waldiez Agent Handoff class."""
|
|
4
7
|
|
|
5
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
6
9
|
|
|
7
10
|
from pydantic import Field
|
|
8
11
|
from typing_extensions import Annotated, Literal
|
|
@@ -115,13 +118,13 @@ class WaldiezSimpleTarget(WaldiezBase):
|
|
|
115
118
|
Field(
|
|
116
119
|
"TerminateTarget", description="The type of the transition target."
|
|
117
120
|
),
|
|
118
|
-
]
|
|
121
|
+
]
|
|
119
122
|
value: Annotated[
|
|
120
123
|
list[str],
|
|
121
124
|
Field(
|
|
122
125
|
default_factory=list,
|
|
123
126
|
),
|
|
124
|
-
]
|
|
127
|
+
] # not actually used (just for consistency with other targets)
|
|
125
128
|
|
|
126
129
|
|
|
127
130
|
class WaldiezGroupOrNestedTarget(WaldiezBase):
|
|
@@ -157,12 +160,10 @@ class WaldiezGroupOrNestedTarget(WaldiezBase):
|
|
|
157
160
|
|
|
158
161
|
|
|
159
162
|
WaldiezTransitionTarget = Annotated[
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
WaldiezSimpleTarget,
|
|
165
|
-
],
|
|
163
|
+
WaldiezAgentTarget
|
|
164
|
+
| WaldiezRandomAgentTarget
|
|
165
|
+
| WaldiezGroupOrNestedTarget
|
|
166
|
+
| WaldiezSimpleTarget,
|
|
166
167
|
Field(discriminator="target_type"),
|
|
167
168
|
]
|
|
168
169
|
|
|
@@ -228,7 +229,7 @@ class WaldiezContextStrLLMCondition(WaldiezBase):
|
|
|
228
229
|
|
|
229
230
|
|
|
230
231
|
WaldiezLLMBasedCondition = Annotated[
|
|
231
|
-
|
|
232
|
+
WaldiezStringLLMCondition | WaldiezContextStrLLMCondition,
|
|
232
233
|
Field(discriminator="condition_type"),
|
|
233
234
|
]
|
|
234
235
|
|
|
@@ -293,15 +294,15 @@ class WaldiezExpressionContextCondition(WaldiezBase):
|
|
|
293
294
|
|
|
294
295
|
|
|
295
296
|
WaldiezContextBasedCondition = Annotated[
|
|
296
|
-
|
|
297
|
+
WaldiezStringContextCondition | WaldiezExpressionContextCondition,
|
|
297
298
|
Field(discriminator="condition_type"),
|
|
298
299
|
]
|
|
299
300
|
|
|
300
301
|
|
|
301
302
|
# Union type for just the condition types (without targets)
|
|
302
|
-
WaldiezHandoffCondition =
|
|
303
|
-
WaldiezLLMBasedCondition
|
|
304
|
-
|
|
303
|
+
WaldiezHandoffCondition = (
|
|
304
|
+
WaldiezLLMBasedCondition | WaldiezContextBasedCondition
|
|
305
|
+
)
|
|
305
306
|
|
|
306
307
|
|
|
307
308
|
# pylint: disable=too-few-public-methods
|
|
@@ -343,6 +344,7 @@ class WaldiezTransitionAvailability(WaldiezBase):
|
|
|
343
344
|
value: str = ""
|
|
344
345
|
|
|
345
346
|
|
|
347
|
+
# noinspection PyTypeHints
|
|
346
348
|
class WaldiezLLMBasedTransition(WaldiezBase):
|
|
347
349
|
"""Condition wrapper for LLM conditions."""
|
|
348
350
|
|
|
@@ -351,6 +353,7 @@ class WaldiezLLMBasedTransition(WaldiezBase):
|
|
|
351
353
|
available: WaldiezTransitionAvailability
|
|
352
354
|
|
|
353
355
|
|
|
356
|
+
# noinspection PyTypeHints
|
|
354
357
|
class WaldiezContextBasedTransition(WaldiezBase):
|
|
355
358
|
"""Condition wrapper for context conditions."""
|
|
356
359
|
|
|
@@ -360,9 +363,9 @@ class WaldiezContextBasedTransition(WaldiezBase):
|
|
|
360
363
|
|
|
361
364
|
|
|
362
365
|
# Union type for complete transitions (condition + target)
|
|
363
|
-
WaldiezHandoffTransition =
|
|
364
|
-
WaldiezLLMBasedTransition
|
|
365
|
-
|
|
366
|
+
WaldiezHandoffTransition = (
|
|
367
|
+
WaldiezLLMBasedTransition | WaldiezContextBasedTransition
|
|
368
|
+
)
|
|
366
369
|
|
|
367
370
|
|
|
368
371
|
class WaldiezHandoff(WaldiezBase):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
# pyright: reportUnknownMemberType=false,reportUnknownVariableType=false
|
|
4
|
-
# pyright: reportUnknownArgumentType=false
|
|
4
|
+
# pyright: reportUnknownArgumentType=false, reportUnusedImport=false
|
|
5
5
|
"""Function related utilities."""
|
|
6
6
|
|
|
7
7
|
import ast
|
|
@@ -9,13 +9,13 @@ import importlib.util
|
|
|
9
9
|
import sys
|
|
10
10
|
import sysconfig
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from typing import NamedTuple
|
|
12
|
+
from typing import NamedTuple
|
|
13
13
|
|
|
14
14
|
# parso for extracting function bodies
|
|
15
15
|
# (keeps comments, docstrings and formatting as-is)
|
|
16
16
|
import parso
|
|
17
|
-
import parso.python
|
|
18
|
-
import parso.tree
|
|
17
|
+
import parso.python
|
|
18
|
+
import parso.tree
|
|
19
19
|
|
|
20
20
|
# let's limit the variable name length
|
|
21
21
|
MAX_VAR_NAME_LENGTH = 64
|
|
@@ -24,8 +24,8 @@ MAX_VAR_NAME_LENGTH = 64
|
|
|
24
24
|
class ParseResult(NamedTuple):
|
|
25
25
|
"""Result of parsing a code string."""
|
|
26
26
|
|
|
27
|
-
error:
|
|
28
|
-
tree:
|
|
27
|
+
error: str | None
|
|
28
|
+
tree: ast.Module | None
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def is_standard_library(module_name: str) -> bool:
|
|
@@ -87,7 +87,7 @@ def parse_code_string(
|
|
|
87
87
|
return ParseResult(None, tree)
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
def _extract_module_name(node: ast.AST) ->
|
|
90
|
+
def _extract_module_name(node: ast.AST) -> str | None:
|
|
91
91
|
"""Extract the root module name from an import node."""
|
|
92
92
|
if isinstance(node, ast.Import):
|
|
93
93
|
return node.names[0].name.split(".")[0]
|
|
@@ -123,11 +123,13 @@ def _extract_imports_from_ast(code_string: str) -> tuple[list[str], list[str]]:
|
|
|
123
123
|
|
|
124
124
|
for node in ast.walk(tree):
|
|
125
125
|
if isinstance(node, (ast.Import, ast.ImportFrom)):
|
|
126
|
+
# noinspection PyTypeChecker
|
|
126
127
|
full_import_statement = ast.get_source_segment(code_string, node)
|
|
127
128
|
if not full_import_statement: # pragma: no cover
|
|
128
129
|
continue
|
|
129
130
|
full_import_statement = full_import_statement.strip()
|
|
130
131
|
|
|
132
|
+
# noinspection PyTypeChecker
|
|
131
133
|
module_name = _extract_module_name(node)
|
|
132
134
|
if not module_name: # pragma: no cover
|
|
133
135
|
continue
|
waldiez/models/common/naming.py
CHANGED
|
@@ -117,3 +117,52 @@ def get_valid_instance_name(
|
|
|
117
117
|
|
|
118
118
|
new_names[instance_id] = name
|
|
119
119
|
return new_names
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def safe_filename(name: str, ext: str = "") -> str:
|
|
123
|
+
"""
|
|
124
|
+
Make a safe cross-platform filename from an arbitrary string.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
name : str
|
|
129
|
+
The string to turn into a safe filename.
|
|
130
|
+
ext : str
|
|
131
|
+
Optional extension (with or without leading dot).
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
str
|
|
136
|
+
A safe filename string.
|
|
137
|
+
"""
|
|
138
|
+
# Normalize extension
|
|
139
|
+
# pylint: disable=inconsistent-quotes
|
|
140
|
+
ext = f".{ext.lstrip('.')}" if ext else ""
|
|
141
|
+
|
|
142
|
+
# Forbidden characters on Windows (also bad on Unix)
|
|
143
|
+
forbidden = r'[<>:"/\\|?*\x00-\x1F]'
|
|
144
|
+
name = re.sub(forbidden, "_", name)
|
|
145
|
+
|
|
146
|
+
# Trim trailing dots/spaces (illegal on Windows)
|
|
147
|
+
name = name.rstrip(". ")
|
|
148
|
+
|
|
149
|
+
# Collapse multiple underscores
|
|
150
|
+
name = re.sub(r"_+", "_", name)
|
|
151
|
+
|
|
152
|
+
# Reserved Windows device names
|
|
153
|
+
reserved = re.compile(
|
|
154
|
+
r"^(con|prn|aux|nul|com[1-9]|lpt[1-9])$", re.IGNORECASE
|
|
155
|
+
)
|
|
156
|
+
if reserved.match(name):
|
|
157
|
+
name = f"_{name}"
|
|
158
|
+
|
|
159
|
+
# Fallback if empty
|
|
160
|
+
if not name:
|
|
161
|
+
name = "file"
|
|
162
|
+
|
|
163
|
+
# Ensure length limit (NTFS max filename length = 255 bytes)
|
|
164
|
+
max_len = 255 - len(ext)
|
|
165
|
+
if len(name) > max_len:
|
|
166
|
+
name = name[:max_len]
|
|
167
|
+
|
|
168
|
+
return f"{name}{ext}"
|
waldiez/models/flow/flow.py
CHANGED
|
@@ -58,7 +58,7 @@ class WaldiezFlow(WaldiezBase):
|
|
|
58
58
|
description="The version waldiez that was used to create the flow",
|
|
59
59
|
title="Version",
|
|
60
60
|
),
|
|
61
|
-
]
|
|
61
|
+
]
|
|
62
62
|
type: Annotated[
|
|
63
63
|
Literal["flow"],
|
|
64
64
|
Field(
|
|
@@ -462,10 +462,11 @@ class WaldiezFlow(WaldiezBase):
|
|
|
462
462
|
agent.id in (chat.source, chat.target)
|
|
463
463
|
for chat in self.data.chats
|
|
464
464
|
):
|
|
465
|
-
|
|
465
|
+
msg = (
|
|
466
466
|
f"Agent {agent.id} ({agent.name}) "
|
|
467
467
|
"does not connect to any other node."
|
|
468
468
|
)
|
|
469
|
+
raise ValueError(msg)
|
|
469
470
|
|
|
470
471
|
@model_validator(mode="after")
|
|
471
472
|
def validate_flow(self) -> Self:
|
|
@@ -593,21 +594,24 @@ class WaldiezFlow(WaldiezBase):
|
|
|
593
594
|
If there are no group manager agents.
|
|
594
595
|
"""
|
|
595
596
|
if not group_manager.data.initial_agent_id:
|
|
596
|
-
|
|
597
|
+
msg = (
|
|
597
598
|
"The flow is a group chat but the group manager agent "
|
|
598
599
|
f"{group_manager.id} has no initial agent ID."
|
|
599
600
|
)
|
|
601
|
+
raise ValueError(msg)
|
|
600
602
|
if group_manager.data.initial_agent_id not in all_member_ids:
|
|
601
|
-
|
|
603
|
+
msg = (
|
|
602
604
|
"The flow is a group chat but the initial agent ID "
|
|
603
605
|
f"{group_manager.data.initial_agent_id} is not in the flow."
|
|
604
606
|
)
|
|
607
|
+
raise ValueError(msg)
|
|
605
608
|
group_members = self.get_group_members(group_manager.id)
|
|
606
609
|
if not group_members:
|
|
607
|
-
|
|
610
|
+
msg = (
|
|
608
611
|
"The flow is a group chat but the group manager agent "
|
|
609
612
|
f"{group_manager.id} has no members in the group."
|
|
610
613
|
)
|
|
614
|
+
raise ValueError(msg)
|
|
611
615
|
group_manager.set_speakers_order(
|
|
612
616
|
[member.id for member in group_members]
|
|
613
617
|
)
|
|
@@ -639,10 +643,11 @@ class WaldiezFlow(WaldiezBase):
|
|
|
639
643
|
group_manager_id in all_member_ids
|
|
640
644
|
for group_manager_id in group_manager_ids
|
|
641
645
|
):
|
|
642
|
-
|
|
646
|
+
msg = (
|
|
643
647
|
"The flow is a group chat but not all group manager agents are "
|
|
644
648
|
"in the flow."
|
|
645
649
|
)
|
|
650
|
+
raise ValueError(msg)
|
|
646
651
|
# check the initial_agent_id for each group
|
|
647
652
|
for group_manager in self.data.agents.groupManagerAgents:
|
|
648
653
|
self._validate_group_manager(group_manager, all_member_ids)
|
waldiez/models/flow/flow_data.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
# pyright: reportArgumentType=false
|
|
5
|
+
|
|
3
6
|
"""Waldiez flow data."""
|
|
4
7
|
|
|
5
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
6
9
|
|
|
7
10
|
from pydantic import Field, model_validator
|
|
8
11
|
from typing_extensions import Annotated, Self
|
|
@@ -69,7 +72,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
69
72
|
title="Nodes",
|
|
70
73
|
description="The nodes of the flow",
|
|
71
74
|
),
|
|
72
|
-
]
|
|
75
|
+
]
|
|
73
76
|
edges: Annotated[
|
|
74
77
|
list[dict[str, Any]],
|
|
75
78
|
Field(
|
|
@@ -77,7 +80,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
77
80
|
title="Edges",
|
|
78
81
|
description="The edges of the flow",
|
|
79
82
|
),
|
|
80
|
-
]
|
|
83
|
+
]
|
|
81
84
|
viewport: Annotated[
|
|
82
85
|
dict[str, Any],
|
|
83
86
|
Field(
|
|
@@ -85,7 +88,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
85
88
|
title="Viewport",
|
|
86
89
|
description="The viewport of the flow",
|
|
87
90
|
),
|
|
88
|
-
]
|
|
91
|
+
]
|
|
89
92
|
# these are the ones we use.
|
|
90
93
|
agents: Annotated[
|
|
91
94
|
WaldiezAgents,
|
|
@@ -102,7 +105,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
102
105
|
title="Models",
|
|
103
106
|
default_factory=list,
|
|
104
107
|
),
|
|
105
|
-
]
|
|
108
|
+
]
|
|
106
109
|
tools: Annotated[
|
|
107
110
|
list[WaldiezTool],
|
|
108
111
|
Field(
|
|
@@ -110,7 +113,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
110
113
|
title="Tools",
|
|
111
114
|
default_factory=list,
|
|
112
115
|
),
|
|
113
|
-
]
|
|
116
|
+
]
|
|
114
117
|
chats: Annotated[
|
|
115
118
|
list[WaldiezChat],
|
|
116
119
|
Field(
|
|
@@ -118,7 +121,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
118
121
|
title="Chats",
|
|
119
122
|
default_factory=list,
|
|
120
123
|
),
|
|
121
|
-
]
|
|
124
|
+
]
|
|
122
125
|
is_async: Annotated[
|
|
123
126
|
bool,
|
|
124
127
|
Field(
|
|
@@ -126,9 +129,9 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
126
129
|
description="Whether the flow is asynchronous or not",
|
|
127
130
|
title="Is Async",
|
|
128
131
|
),
|
|
129
|
-
]
|
|
132
|
+
]
|
|
130
133
|
cache_seed: Annotated[
|
|
131
|
-
|
|
134
|
+
int | None,
|
|
132
135
|
Field(
|
|
133
136
|
42,
|
|
134
137
|
alias="cacheSeed",
|
|
@@ -138,7 +141,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
138
141
|
),
|
|
139
142
|
title="Cache Seed",
|
|
140
143
|
),
|
|
141
|
-
]
|
|
144
|
+
]
|
|
142
145
|
|
|
143
146
|
@model_validator(mode="after")
|
|
144
147
|
def validate_flow_chats(self) -> Self:
|
|
@@ -200,6 +203,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
200
203
|
WaldiezFlowData
|
|
201
204
|
The default flow data.
|
|
202
205
|
"""
|
|
206
|
+
termination = WaldiezAgentTerminationMessage()
|
|
203
207
|
return cls(
|
|
204
208
|
nodes=[],
|
|
205
209
|
edges=[],
|
|
@@ -213,7 +217,7 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
213
217
|
created_at=now(),
|
|
214
218
|
updated_at=now(),
|
|
215
219
|
data=WaldiezAssistantData(
|
|
216
|
-
termination=
|
|
220
|
+
termination=termination,
|
|
217
221
|
),
|
|
218
222
|
),
|
|
219
223
|
WaldiezAssistant(
|
|
@@ -223,13 +227,15 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
223
227
|
updated_at=now(),
|
|
224
228
|
data=WaldiezAssistantData(
|
|
225
229
|
# is_multimodal=True, # we need an api key for this
|
|
226
|
-
termination=
|
|
230
|
+
termination=termination,
|
|
227
231
|
),
|
|
228
232
|
),
|
|
229
233
|
],
|
|
230
234
|
ragUserProxyAgents=[],
|
|
231
235
|
reasoningAgents=[],
|
|
232
236
|
captainAgents=[],
|
|
237
|
+
groupManagerAgents=[],
|
|
238
|
+
docAgents=[],
|
|
233
239
|
),
|
|
234
240
|
models=[],
|
|
235
241
|
tools=[],
|
|
@@ -285,11 +291,11 @@ class WaldiezFlowData(WaldiezBase):
|
|
|
285
291
|
|
|
286
292
|
def get_flow_data(
|
|
287
293
|
data: dict[str, Any],
|
|
288
|
-
flow_id:
|
|
289
|
-
name:
|
|
290
|
-
description:
|
|
291
|
-
tags:
|
|
292
|
-
requirements:
|
|
294
|
+
flow_id: str | None = None,
|
|
295
|
+
name: str | None = None,
|
|
296
|
+
description: str | None = None,
|
|
297
|
+
tags: list[str] | None = None,
|
|
298
|
+
requirements: list[str] | None = None,
|
|
293
299
|
) -> dict[str, Any]:
|
|
294
300
|
"""Get the flow from the passed data dict.
|
|
295
301
|
|
waldiez/models/flow/info.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
"""Waldiez chat info model."""
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Iterable
|
|
6
6
|
|
|
7
7
|
from pydantic import Field
|
|
8
8
|
from typing_extensions import Annotated
|
|
@@ -54,9 +54,9 @@ class WaldiezFlowInfo(WaldiezBase):
|
|
|
54
54
|
list[WaldiezAgentInfo],
|
|
55
55
|
Field(
|
|
56
56
|
description="List of chat participants with their info",
|
|
57
|
-
default_factory=list
|
|
57
|
+
default_factory=list,
|
|
58
58
|
),
|
|
59
|
-
]
|
|
59
|
+
]
|
|
60
60
|
|
|
61
61
|
@classmethod
|
|
62
62
|
def create(
|
waldiez/models/flow/naming.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
"""Ensure unique names for agents, models, tools, and chats."""
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from typing import TypedDict
|
|
6
7
|
|
|
7
8
|
from ..agents import WaldiezAgent
|
|
8
9
|
from ..chat import WaldiezChat
|
waldiez/models/model/_aws.py
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
# flake8: noqa: E501
|
|
4
4
|
"""Waldiez Model AWS model."""
|
|
5
5
|
|
|
6
|
-
from typing import Optional
|
|
7
|
-
|
|
8
6
|
from pydantic import Field
|
|
9
7
|
from typing_extensions import Annotated
|
|
10
8
|
|
|
@@ -25,51 +23,51 @@ class WaldiezModelAWS(WaldiezBase):
|
|
|
25
23
|
session_token : Optional[str]
|
|
26
24
|
The AWS session token, by default None.
|
|
27
25
|
profile_name : Optional[str]
|
|
28
|
-
The AWS profile name, by default
|
|
26
|
+
The AWS profile name, by default None.
|
|
29
27
|
"""
|
|
30
28
|
|
|
31
29
|
region: Annotated[
|
|
32
|
-
|
|
30
|
+
str | None,
|
|
33
31
|
Field(
|
|
34
32
|
None,
|
|
35
33
|
alias="region",
|
|
36
34
|
title="Region",
|
|
37
35
|
description="The AWS region",
|
|
38
36
|
),
|
|
39
|
-
]
|
|
37
|
+
]
|
|
40
38
|
access_key: Annotated[
|
|
41
|
-
|
|
39
|
+
str | None,
|
|
42
40
|
Field(
|
|
43
41
|
None,
|
|
44
42
|
alias="accessKey",
|
|
45
43
|
title="Access Ke",
|
|
46
44
|
description="The AWS access key",
|
|
47
45
|
),
|
|
48
|
-
]
|
|
46
|
+
]
|
|
49
47
|
secret_key: Annotated[
|
|
50
|
-
|
|
48
|
+
str | None,
|
|
51
49
|
Field(
|
|
52
50
|
None,
|
|
53
51
|
alias="secretKey",
|
|
54
52
|
title="Secret Key",
|
|
55
53
|
description="The AWS secret key",
|
|
56
54
|
),
|
|
57
|
-
]
|
|
55
|
+
]
|
|
58
56
|
session_token: Annotated[
|
|
59
|
-
|
|
57
|
+
str | None,
|
|
60
58
|
Field(
|
|
61
59
|
None,
|
|
62
60
|
alias="sessionToken",
|
|
63
61
|
title="Session Token",
|
|
64
62
|
description="The AWS session token",
|
|
65
63
|
),
|
|
66
|
-
]
|
|
64
|
+
]
|
|
67
65
|
profile_name: Annotated[
|
|
68
|
-
|
|
66
|
+
str | None,
|
|
69
67
|
Field(
|
|
70
68
|
None,
|
|
71
69
|
alias="profileName",
|
|
72
70
|
title="Profile Name",
|
|
73
71
|
description="The AWS Profile name to use",
|
|
74
72
|
),
|
|
75
|
-
]
|
|
73
|
+
]
|
waldiez/models/model/_llm.py
CHANGED
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
# https://docs.llamaindex.ai/en/stable/examples/llm/together/
|
|
24
24
|
# https://docs.llamaindex.ai/en/stable/api_reference/llms/openai_like/
|
|
25
25
|
#
|
|
26
|
+
#
|
|
27
|
+
# pyright: reportImportCycles=false,reportUnusedParameter=false
|
|
28
|
+
# pyright: reportUnnecessaryComparison=false,reportUnreachable=false
|
|
26
29
|
|
|
27
30
|
import os
|
|
28
31
|
from typing import TYPE_CHECKING
|
|
@@ -31,6 +34,7 @@ if TYPE_CHECKING:
|
|
|
31
34
|
from .model import WaldiezModel
|
|
32
35
|
|
|
33
36
|
|
|
37
|
+
# noinspection PyUnusedLocal
|
|
34
38
|
def get_llm_requirements(
|
|
35
39
|
model: "WaldiezModel",
|
|
36
40
|
ag2_version: str, # pylint: disable=unused-argument
|
|
@@ -101,6 +105,7 @@ def get_llm_requirements(
|
|
|
101
105
|
return requirements
|
|
102
106
|
|
|
103
107
|
|
|
108
|
+
# pylint: disable=too-many-branches
|
|
104
109
|
def get_llm_imports(model: "WaldiezModel") -> set[str]:
|
|
105
110
|
"""Get the LLM import statements for the model.
|
|
106
111
|
|
|
@@ -154,9 +159,11 @@ def get_llm_imports(model: "WaldiezModel") -> set[str]:
|
|
|
154
159
|
case "other":
|
|
155
160
|
return {"from llama_index.llms.openai_like import OpenAILike"}
|
|
156
161
|
case _: # pragma: no cover
|
|
162
|
+
# noinspection PyUnreachableCode
|
|
157
163
|
raise ValueError(f"Unsupported API type: {model.data.api_type}")
|
|
158
164
|
|
|
159
165
|
|
|
166
|
+
# pylint: disable=too-many-branches
|
|
160
167
|
def get_llm_arg(model: "WaldiezModel") -> tuple[str, str]:
|
|
161
168
|
"""Get the LLM argument for the model.
|
|
162
169
|
|
|
@@ -201,6 +208,7 @@ def get_llm_arg(model: "WaldiezModel") -> tuple[str, str]:
|
|
|
201
208
|
case "other":
|
|
202
209
|
return do_other_llm(model)
|
|
203
210
|
case _: # pragma: no cover
|
|
211
|
+
# noinspection PyUnreachableCode
|
|
204
212
|
raise ValueError(f"Unsupported API type: {model.data.api_type}")
|
|
205
213
|
|
|
206
214
|
|
waldiez/models/model/_price.py
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
# flake8: noqa: E501
|
|
4
4
|
"""Waldiez Model Price."""
|
|
5
5
|
|
|
6
|
-
from typing import Optional
|
|
7
|
-
|
|
8
6
|
from pydantic import Field
|
|
9
7
|
from typing_extensions import Annotated
|
|
10
8
|
|
|
@@ -23,8 +21,8 @@ class WaldiezModelPrice(WaldiezBase):
|
|
|
23
21
|
"""
|
|
24
22
|
|
|
25
23
|
prompt_price_per_1k: Annotated[
|
|
26
|
-
|
|
24
|
+
float | None, Field(None, alias="promptPricePer1k")
|
|
27
25
|
]
|
|
28
26
|
completion_token_price_per_1k: Annotated[
|
|
29
|
-
|
|
27
|
+
float | None, Field(None, alias="completionTokenPricePer1k")
|
|
30
28
|
]
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
"""Waldiez model extra requirements."""
|
|
4
4
|
|
|
5
|
-
from typing import Set
|
|
6
|
-
|
|
7
5
|
from .model import WaldiezModel
|
|
8
6
|
|
|
9
7
|
|
|
@@ -24,7 +22,7 @@ def get_models_extra_requirements(
|
|
|
24
22
|
list[str]
|
|
25
23
|
The models extra requirements.
|
|
26
24
|
"""
|
|
27
|
-
model_requirements:
|
|
25
|
+
model_requirements: set[str] = set()
|
|
28
26
|
# ref: https://github.com/ag2ai/ag2/blob/main/pyproject.toml
|
|
29
27
|
models_with_additional_requirements = [
|
|
30
28
|
"together",
|
waldiez/models/model/model.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"""Waldiez model model."""
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
from pydantic import Field
|
|
9
9
|
from typing_extensions import Annotated, Literal
|
|
@@ -181,7 +181,7 @@ class WaldiezModel(WaldiezBase):
|
|
|
181
181
|
return api_key or "REPLACE_ME"
|
|
182
182
|
|
|
183
183
|
@property
|
|
184
|
-
def price(self) ->
|
|
184
|
+
def price(self) -> list[float] | None:
|
|
185
185
|
"""Get the model's price."""
|
|
186
186
|
if self.data.price is None:
|
|
187
187
|
return None
|