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
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
# flake8: noqa: E501
|
|
4
4
|
"""Waldiez Model Data."""
|
|
5
5
|
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Annotated, Any, Literal
|
|
7
7
|
|
|
8
8
|
from pydantic import Field, model_validator
|
|
9
|
-
from typing_extensions import
|
|
9
|
+
from typing_extensions import Self
|
|
10
10
|
|
|
11
11
|
from ..common import WaldiezBase, update_dict
|
|
12
12
|
from ._aws import WaldiezModelAWS
|
|
@@ -59,23 +59,23 @@ class WaldiezModelData(WaldiezBase):
|
|
|
59
59
|
"""
|
|
60
60
|
|
|
61
61
|
base_url: Annotated[
|
|
62
|
-
|
|
62
|
+
str | None,
|
|
63
63
|
Field(
|
|
64
64
|
default=None,
|
|
65
65
|
title="Base URL",
|
|
66
66
|
description="The base url of the model",
|
|
67
67
|
alias="baseUrl",
|
|
68
68
|
),
|
|
69
|
-
]
|
|
69
|
+
]
|
|
70
70
|
api_key: Annotated[
|
|
71
|
-
|
|
71
|
+
str | None,
|
|
72
72
|
Field(
|
|
73
73
|
default=None,
|
|
74
74
|
alias="apiKey",
|
|
75
75
|
title="API Key",
|
|
76
76
|
description="The api key to use with the model",
|
|
77
77
|
),
|
|
78
|
-
]
|
|
78
|
+
]
|
|
79
79
|
api_type: Annotated[
|
|
80
80
|
WaldiezModelAPIType,
|
|
81
81
|
Field(
|
|
@@ -84,52 +84,52 @@ class WaldiezModelData(WaldiezBase):
|
|
|
84
84
|
title="API Type",
|
|
85
85
|
description="The api type of the model",
|
|
86
86
|
),
|
|
87
|
-
]
|
|
87
|
+
]
|
|
88
88
|
api_version: Annotated[
|
|
89
|
-
|
|
89
|
+
str | None,
|
|
90
90
|
Field(
|
|
91
91
|
default=None,
|
|
92
92
|
alias="apiVersion",
|
|
93
93
|
title="API Version",
|
|
94
94
|
description="The api version of the model",
|
|
95
95
|
),
|
|
96
|
-
]
|
|
96
|
+
]
|
|
97
97
|
temperature: Annotated[
|
|
98
|
-
|
|
98
|
+
float | None,
|
|
99
99
|
Field(
|
|
100
100
|
default=None,
|
|
101
101
|
alias="temperature",
|
|
102
102
|
title="Temperature",
|
|
103
103
|
description="The temperature of the model",
|
|
104
104
|
),
|
|
105
|
-
]
|
|
105
|
+
]
|
|
106
106
|
top_p: Annotated[
|
|
107
|
-
|
|
107
|
+
float | None,
|
|
108
108
|
Field(
|
|
109
109
|
default=None,
|
|
110
110
|
alias="topP",
|
|
111
111
|
title="Top P",
|
|
112
112
|
description="The top p of the model",
|
|
113
113
|
),
|
|
114
|
-
]
|
|
114
|
+
]
|
|
115
115
|
max_tokens: Annotated[
|
|
116
|
-
|
|
116
|
+
int | None,
|
|
117
117
|
Field(
|
|
118
118
|
default=None,
|
|
119
119
|
alias="maxTokens",
|
|
120
120
|
title="Max Tokens",
|
|
121
121
|
description="The max tokens of the model",
|
|
122
122
|
),
|
|
123
|
-
]
|
|
123
|
+
]
|
|
124
124
|
aws: Annotated[
|
|
125
|
-
|
|
125
|
+
WaldiezModelAWS | None,
|
|
126
126
|
Field(
|
|
127
127
|
default=None,
|
|
128
128
|
alias="aws",
|
|
129
129
|
title="AWS",
|
|
130
130
|
description="The AWS related parameters",
|
|
131
131
|
),
|
|
132
|
-
]
|
|
132
|
+
]
|
|
133
133
|
extras: Annotated[
|
|
134
134
|
dict[str, Any],
|
|
135
135
|
Field(
|
|
@@ -138,7 +138,7 @@ class WaldiezModelData(WaldiezBase):
|
|
|
138
138
|
title="Extras",
|
|
139
139
|
description="Any extra attributes to include in the LLM Config",
|
|
140
140
|
),
|
|
141
|
-
]
|
|
141
|
+
]
|
|
142
142
|
default_headers: Annotated[
|
|
143
143
|
dict[str, str],
|
|
144
144
|
Field(
|
|
@@ -147,13 +147,13 @@ class WaldiezModelData(WaldiezBase):
|
|
|
147
147
|
title="Default Headers",
|
|
148
148
|
description="The default headers of the model",
|
|
149
149
|
),
|
|
150
|
-
]
|
|
150
|
+
]
|
|
151
151
|
price: Annotated[
|
|
152
|
-
|
|
152
|
+
WaldiezModelPrice | None,
|
|
153
153
|
Field(
|
|
154
154
|
default=None, title="Price", description="The price of the model"
|
|
155
155
|
),
|
|
156
|
-
]
|
|
156
|
+
]
|
|
157
157
|
|
|
158
158
|
@model_validator(mode="after")
|
|
159
159
|
def validate_model_data(self) -> Self:
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
"""Waldiez tool extra requirements."""
|
|
4
4
|
|
|
5
|
-
from typing import Set
|
|
6
|
-
|
|
7
5
|
from .predefined import get_predefined_tool_requirements
|
|
8
6
|
from .tool import WaldiezTool
|
|
9
7
|
|
|
@@ -11,7 +9,7 @@ from .tool import WaldiezTool
|
|
|
11
9
|
def get_tools_extra_requirements(
|
|
12
10
|
tools: list[WaldiezTool],
|
|
13
11
|
autogen_version: str,
|
|
14
|
-
) ->
|
|
12
|
+
) -> set[str]:
|
|
15
13
|
"""Get the tools extra requirements.
|
|
16
14
|
|
|
17
15
|
Parameters
|
|
@@ -26,7 +24,7 @@ def get_tools_extra_requirements(
|
|
|
26
24
|
list[str]
|
|
27
25
|
The tools extra requirements.
|
|
28
26
|
"""
|
|
29
|
-
tool_requirements:
|
|
27
|
+
tool_requirements: set[str] = set()
|
|
30
28
|
for tool in tools:
|
|
31
29
|
if tool.tool_type == "langchain":
|
|
32
30
|
tool_requirements.add(f"ag2[interop-langchain]=={autogen_version}")
|
|
@@ -115,6 +115,7 @@ def {self.name}(query: str, num_results: int = 5) -> list[dict[str, Any]]:
|
|
|
115
115
|
return content
|
|
116
116
|
|
|
117
117
|
|
|
118
|
+
# pylint: disable=invalid-name
|
|
118
119
|
DuckDuckGoSearchTool = DuckDuckGoSearchToolImpl()
|
|
119
120
|
DuckDuckGoSearchConfig = PredefinedToolConfig(
|
|
120
121
|
name=DuckDuckGoSearchTool.name,
|
|
@@ -11,6 +11,7 @@ from ._config import PredefinedToolConfig
|
|
|
11
11
|
from .protocol import PredefinedTool
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
# noinspection PyBroadException,TryExceptPass
|
|
14
15
|
class SendEmailToolImpl(PredefinedTool):
|
|
15
16
|
"""Predefined tool for sending emails."""
|
|
16
17
|
|
|
@@ -139,6 +140,7 @@ class SendEmailToolImpl(PredefinedTool):
|
|
|
139
140
|
A list of validation error messages, if any.
|
|
140
141
|
"""
|
|
141
142
|
updated = dict(self._kwargs)
|
|
143
|
+
# noinspection DuplicatedCode
|
|
142
144
|
for key, value in kwargs.items():
|
|
143
145
|
if key in self.kwarg_types:
|
|
144
146
|
typ = self.kwarg_types[key]
|
|
@@ -161,6 +163,7 @@ class SendEmailToolImpl(PredefinedTool):
|
|
|
161
163
|
) -> dict[str, Any]:
|
|
162
164
|
"""Get effective keyword arguments."""
|
|
163
165
|
effective = dict(self._kwargs)
|
|
166
|
+
# noinspection DuplicatedCode
|
|
164
167
|
if runtime_kwargs:
|
|
165
168
|
# cast only known keys, same rules as validate_kwargs
|
|
166
169
|
for k, v in runtime_kwargs.items():
|
|
@@ -462,6 +465,7 @@ def {self.name}(
|
|
|
462
465
|
return base + exported
|
|
463
466
|
|
|
464
467
|
|
|
468
|
+
# pylint: disable=invalid-name
|
|
465
469
|
SendEmailTool = SendEmailToolImpl()
|
|
466
470
|
SendEmailConfig = PredefinedToolConfig(
|
|
467
471
|
name=SendEmailTool.name,
|
|
@@ -94,7 +94,7 @@ class PerplexitySearchToolImpl(PredefinedTool):
|
|
|
94
94
|
if key in kwargs: # pragma: no branch
|
|
95
95
|
type_of = self.kwarg_types.get(key, str)
|
|
96
96
|
# pylint: disable=broad-exception-caught
|
|
97
|
-
# noinspection PyBroadException
|
|
97
|
+
# noinspection PyBroadException,TryExceptPass
|
|
98
98
|
try:
|
|
99
99
|
casted = type_of(value)
|
|
100
100
|
if key in self.kwargs: # pragma: no branch
|
|
@@ -156,6 +156,7 @@ def {self.name}(
|
|
|
156
156
|
return content
|
|
157
157
|
|
|
158
158
|
|
|
159
|
+
# pylint: disable=invalid-name
|
|
159
160
|
PerplexitySearchTool = PerplexitySearchToolImpl()
|
|
160
161
|
PerplexitySearchConfig = PredefinedToolConfig(
|
|
161
162
|
name=PerplexitySearchTool.name,
|
|
@@ -86,7 +86,7 @@ class SearxNGSearchToolImpl(PredefinedTool):
|
|
|
86
86
|
if key in kwargs: # pragma: no branch
|
|
87
87
|
type_of = self.kwarg_types.get(key, str)
|
|
88
88
|
# pylint: disable=broad-exception-caught
|
|
89
|
-
# noinspection PyBroadException
|
|
89
|
+
# noinspection PyBroadException,TryExceptPass
|
|
90
90
|
try:
|
|
91
91
|
casted = type_of(value)
|
|
92
92
|
if key in self.kwargs: # pragma: no branch
|
|
@@ -146,6 +146,7 @@ def {self.name}(
|
|
|
146
146
|
return content
|
|
147
147
|
|
|
148
148
|
|
|
149
|
+
# pylint: disable=invalid-name
|
|
149
150
|
SearxNGSearchTool = SearxNGSearchToolImpl()
|
|
150
151
|
SearxNGSearchConfig = PredefinedToolConfig(
|
|
151
152
|
name=SearxNGSearchTool.name,
|
|
@@ -91,7 +91,7 @@ class WikipediaSearchToolImpl(PredefinedTool):
|
|
|
91
91
|
if key in kwargs:
|
|
92
92
|
type_of = self.kwargs_types.get(key, str)
|
|
93
93
|
# pylint: disable=broad-exception-caught
|
|
94
|
-
# noinspection PyBroadException
|
|
94
|
+
# noinspection PyBroadException,TryExceptPass
|
|
95
95
|
try:
|
|
96
96
|
casted = type_of(value)
|
|
97
97
|
if key in self.kwargs:
|
|
@@ -145,6 +145,7 @@ def {self.name}(query: str, language: str = "en", top_k: int = 3, verbose: bool
|
|
|
145
145
|
return content
|
|
146
146
|
|
|
147
147
|
|
|
148
|
+
# pylint: disable=invalid-name
|
|
148
149
|
WikipediaSearchTool = WikipediaSearchToolImpl()
|
|
149
150
|
WikipediaSearchConfig = PredefinedToolConfig(
|
|
150
151
|
name=WikipediaSearchTool.name,
|
waldiez/models/tool/tool.py
CHANGED
|
@@ -81,7 +81,7 @@ class WaldiezTool(WaldiezBase):
|
|
|
81
81
|
description="The tags of the tool.",
|
|
82
82
|
default_factory=list,
|
|
83
83
|
),
|
|
84
|
-
]
|
|
84
|
+
]
|
|
85
85
|
requirements: Annotated[
|
|
86
86
|
list[str],
|
|
87
87
|
Field(
|
|
@@ -89,7 +89,7 @@ class WaldiezTool(WaldiezBase):
|
|
|
89
89
|
description="The requirements of the tool.",
|
|
90
90
|
default_factory=list,
|
|
91
91
|
),
|
|
92
|
-
]
|
|
92
|
+
]
|
|
93
93
|
data: Annotated[
|
|
94
94
|
WaldiezToolData,
|
|
95
95
|
Field(..., title="Data", description="The data of the tool."),
|
|
@@ -324,22 +324,25 @@ class WaldiezTool(WaldiezBase):
|
|
|
324
324
|
config = get_predefined_tool_config(self.name)
|
|
325
325
|
if not config:
|
|
326
326
|
available_tools = list_predefined_tools()
|
|
327
|
-
|
|
327
|
+
msg = (
|
|
328
328
|
f"Unknown predefined tool: {self.name}. "
|
|
329
329
|
f"Available tools: {available_tools}"
|
|
330
330
|
)
|
|
331
|
+
raise ValueError(msg)
|
|
331
332
|
missing_secrets = config.validate_secrets(self.data.secrets)
|
|
332
333
|
if missing_secrets:
|
|
333
|
-
|
|
334
|
+
msg = (
|
|
334
335
|
f"Missing required secrets for {self.name}: "
|
|
335
336
|
f"{missing_secrets}"
|
|
336
337
|
)
|
|
338
|
+
raise ValueError(msg)
|
|
337
339
|
invalid_kwargs = config.validate_kwargs(self.data.kwargs)
|
|
338
340
|
if invalid_kwargs:
|
|
339
|
-
|
|
341
|
+
msg = (
|
|
340
342
|
f"Invalid keyword arguments for {self.name}: "
|
|
341
343
|
f"{invalid_kwargs}"
|
|
342
344
|
)
|
|
345
|
+
raise ValueError(msg)
|
|
343
346
|
# Update tool metadata from predefined config
|
|
344
347
|
if not self.description:
|
|
345
348
|
self.description = config.description
|
waldiez/models/tool/tool_data.py
CHANGED
|
@@ -34,7 +34,7 @@ class WaldiezToolData(WaldiezBase):
|
|
|
34
34
|
"The type of the tool: shared, custom, langchain, crewai."
|
|
35
35
|
),
|
|
36
36
|
),
|
|
37
|
-
]
|
|
37
|
+
]
|
|
38
38
|
content: Annotated[
|
|
39
39
|
str,
|
|
40
40
|
Field(
|
|
@@ -60,7 +60,7 @@ class WaldiezToolData(WaldiezBase):
|
|
|
60
60
|
"Keyword arguments for the tool, used for initialization."
|
|
61
61
|
),
|
|
62
62
|
),
|
|
63
|
-
]
|
|
63
|
+
]
|
|
64
64
|
|
|
65
65
|
_raw_content: str = ""
|
|
66
66
|
|
waldiez/models/waldiez.py
CHANGED
|
@@ -8,10 +8,15 @@ and run an autogen workflow. It has the model/LLM configurations, the agent
|
|
|
8
8
|
definitions and their optional additional tools to be used.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
+
import asyncio
|
|
11
12
|
import json
|
|
13
|
+
import tempfile
|
|
14
|
+
from collections.abc import Iterator
|
|
12
15
|
from dataclasses import dataclass
|
|
13
16
|
from pathlib import Path
|
|
14
|
-
from typing import Any
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
import aiofiles
|
|
15
20
|
|
|
16
21
|
from .agents import (
|
|
17
22
|
WaldiezAgent,
|
|
@@ -19,7 +24,7 @@ from .agents import (
|
|
|
19
24
|
get_captain_agent_extra_requirements,
|
|
20
25
|
get_retrievechat_extra_requirements,
|
|
21
26
|
)
|
|
22
|
-
from .common import get_autogen_version
|
|
27
|
+
from .common import get_autogen_version, safe_filename
|
|
23
28
|
from .flow import (
|
|
24
29
|
WaldiezAgentConnection,
|
|
25
30
|
WaldiezFlow,
|
|
@@ -92,7 +97,7 @@ class Waldiez:
|
|
|
92
97
|
requirements=requirements,
|
|
93
98
|
)
|
|
94
99
|
validated = WaldiezFlow.model_validate(flow)
|
|
95
|
-
return cls(flow=validated)
|
|
100
|
+
return cls(flow=validated)
|
|
96
101
|
|
|
97
102
|
@classmethod
|
|
98
103
|
def load(
|
|
@@ -131,7 +136,7 @@ class Waldiez:
|
|
|
131
136
|
data: dict[str, Any] = {}
|
|
132
137
|
if not Path(waldiez_file).exists():
|
|
133
138
|
raise ValueError(f"File not found: {waldiez_file}")
|
|
134
|
-
with open(waldiez_file, "r", encoding="utf-8") as file:
|
|
139
|
+
with open(waldiez_file, "r", encoding="utf-8", newline="\n") as file:
|
|
135
140
|
try:
|
|
136
141
|
data = json.load(file)
|
|
137
142
|
except json.decoder.JSONDecodeError as error:
|
|
@@ -144,6 +149,59 @@ class Waldiez:
|
|
|
144
149
|
requirements=requirements,
|
|
145
150
|
)
|
|
146
151
|
|
|
152
|
+
@classmethod
|
|
153
|
+
async def a_load(
|
|
154
|
+
cls,
|
|
155
|
+
waldiez_file: str | Path,
|
|
156
|
+
name: str | None = None,
|
|
157
|
+
description: str | None = None,
|
|
158
|
+
tags: list[str] | None = None,
|
|
159
|
+
requirements: list[str] | None = None,
|
|
160
|
+
) -> "Waldiez":
|
|
161
|
+
"""Load a Waldiez from a file.
|
|
162
|
+
|
|
163
|
+
Parameters
|
|
164
|
+
----------
|
|
165
|
+
waldiez_file : Union[str, Path]
|
|
166
|
+
The Waldiez file.
|
|
167
|
+
name: str | None, optional
|
|
168
|
+
The name, by default None (retrieved from data).
|
|
169
|
+
description : str | None, optional
|
|
170
|
+
The description, by default None (retrieved from data).
|
|
171
|
+
tags: list[str] | None, optional
|
|
172
|
+
The tags, by default None (retrieved from data).
|
|
173
|
+
requirements: list[str] | None, optional
|
|
174
|
+
The requirements, by default None (retrieved from data).
|
|
175
|
+
|
|
176
|
+
Returns
|
|
177
|
+
-------
|
|
178
|
+
Waldiez
|
|
179
|
+
The Waldiez.
|
|
180
|
+
|
|
181
|
+
Raises
|
|
182
|
+
------
|
|
183
|
+
ValueError
|
|
184
|
+
If the file is not found or invalid JSON.
|
|
185
|
+
"""
|
|
186
|
+
data: dict[str, Any] = {}
|
|
187
|
+
if not Path(waldiez_file).exists():
|
|
188
|
+
raise ValueError(f"File not found: {waldiez_file}")
|
|
189
|
+
async with aiofiles.open(
|
|
190
|
+
waldiez_file, "r", encoding="utf-8", newline="\n"
|
|
191
|
+
) as file:
|
|
192
|
+
try:
|
|
193
|
+
contents = await file.read()
|
|
194
|
+
data = json.loads(contents)
|
|
195
|
+
except json.decoder.JSONDecodeError as error:
|
|
196
|
+
raise ValueError(f"Invalid JSON: {waldiez_file}") from error
|
|
197
|
+
return cls.from_dict(
|
|
198
|
+
data,
|
|
199
|
+
name=name,
|
|
200
|
+
description=description,
|
|
201
|
+
tags=tags,
|
|
202
|
+
requirements=requirements,
|
|
203
|
+
)
|
|
204
|
+
|
|
147
205
|
def model_dump_json(
|
|
148
206
|
self, by_alias: bool = True, indent: int | None = None
|
|
149
207
|
) -> str:
|
|
@@ -200,6 +258,26 @@ class Waldiez:
|
|
|
200
258
|
"""Get the chats."""
|
|
201
259
|
return self.flow.ordered_flow
|
|
202
260
|
|
|
261
|
+
@property
|
|
262
|
+
def is_group_pattern_based(
|
|
263
|
+
self,
|
|
264
|
+
) -> bool:
|
|
265
|
+
"""Check if the group manager should use pattern strategy.
|
|
266
|
+
|
|
267
|
+
Returns
|
|
268
|
+
-------
|
|
269
|
+
bool
|
|
270
|
+
True if pattern strategy should be used, False otherwise.
|
|
271
|
+
"""
|
|
272
|
+
if not self.initial_chats:
|
|
273
|
+
return True
|
|
274
|
+
|
|
275
|
+
first_chat = self.initial_chats[0]["chat"]
|
|
276
|
+
return (
|
|
277
|
+
isinstance(first_chat.data.message, str)
|
|
278
|
+
or not first_chat.data.message.is_method()
|
|
279
|
+
)
|
|
280
|
+
|
|
203
281
|
@property
|
|
204
282
|
def agents(self) -> Iterator[WaldiezAgent]:
|
|
205
283
|
"""Get the agents.
|
|
@@ -367,3 +445,73 @@ class Waldiez:
|
|
|
367
445
|
if not agent.is_group_manager:
|
|
368
446
|
return []
|
|
369
447
|
return self.flow.get_group_chat_members(agent.id)
|
|
448
|
+
|
|
449
|
+
def dump(self, to: str | Path | None = None) -> Path:
|
|
450
|
+
"""Dump waldiez flow to a file.
|
|
451
|
+
|
|
452
|
+
Parameters
|
|
453
|
+
----------
|
|
454
|
+
to : str | Path | None
|
|
455
|
+
Optional output path to determine the directory to save the flow to.
|
|
456
|
+
|
|
457
|
+
Returns
|
|
458
|
+
-------
|
|
459
|
+
Path
|
|
460
|
+
The path to the generated file.
|
|
461
|
+
"""
|
|
462
|
+
file_path = Path(to) if to else None
|
|
463
|
+
if file_path:
|
|
464
|
+
file_name = file_path.name
|
|
465
|
+
if not file_name.endswith(".waldiez"):
|
|
466
|
+
file_path.with_suffix(".waldiez")
|
|
467
|
+
|
|
468
|
+
else:
|
|
469
|
+
full_name = self.name
|
|
470
|
+
file_name = safe_filename(full_name, "waldiez")
|
|
471
|
+
file_dir: Path
|
|
472
|
+
if file_path:
|
|
473
|
+
file_dir = file_path if file_path.is_dir() else file_path.parent
|
|
474
|
+
else:
|
|
475
|
+
file_dir = Path(tempfile.mkdtemp())
|
|
476
|
+
file_dir.mkdir(parents=True, exist_ok=True)
|
|
477
|
+
output_path = file_dir / file_name
|
|
478
|
+
with output_path.open(
|
|
479
|
+
"w", encoding="utf-8", errors="replace", newline="\n"
|
|
480
|
+
) as f_open:
|
|
481
|
+
f_open.write(self.model_dump_json())
|
|
482
|
+
return output_path
|
|
483
|
+
|
|
484
|
+
async def a_dump(self, to: str | Path | None = None) -> Path:
|
|
485
|
+
"""Dump waldiez flow to a file asynchronously.
|
|
486
|
+
|
|
487
|
+
Parameters
|
|
488
|
+
----------
|
|
489
|
+
to : str | Path | None
|
|
490
|
+
Optional output path to determine the directory to save the flow to.
|
|
491
|
+
|
|
492
|
+
Returns
|
|
493
|
+
-------
|
|
494
|
+
Path
|
|
495
|
+
The path to the generated file.
|
|
496
|
+
"""
|
|
497
|
+
file_path = Path(to) if to else None
|
|
498
|
+
if file_path:
|
|
499
|
+
file_name = file_path.name
|
|
500
|
+
if not file_name.endswith(".waldiez"):
|
|
501
|
+
file_path.with_suffix(".waldiez")
|
|
502
|
+
else:
|
|
503
|
+
full_name = self.name
|
|
504
|
+
file_name = safe_filename(full_name, "waldiez")
|
|
505
|
+
file_dir: Path
|
|
506
|
+
if file_path:
|
|
507
|
+
file_dir = file_path if file_path.is_dir() else file_path.parent
|
|
508
|
+
else:
|
|
509
|
+
tmp_dir = await asyncio.to_thread(tempfile.mkdtemp)
|
|
510
|
+
file_dir = Path(tmp_dir)
|
|
511
|
+
file_dir.mkdir(parents=True, exist_ok=True)
|
|
512
|
+
output_path = file_dir / file_name
|
|
513
|
+
async with aiofiles.open(
|
|
514
|
+
output_path, "w", encoding="utf-8", errors="replace", newline="\n"
|
|
515
|
+
) as f_open:
|
|
516
|
+
await f_open.write(self.model_dump_json())
|
|
517
|
+
return output_path
|
waldiez/runner.py
CHANGED
|
@@ -20,7 +20,7 @@ during the flow execution.
|
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
from typing import Any
|
|
22
22
|
|
|
23
|
-
from typing_extensions import Literal
|
|
23
|
+
from typing_extensions import Literal, override
|
|
24
24
|
|
|
25
25
|
from .models.waldiez import Waldiez
|
|
26
26
|
from .running import (
|
|
@@ -81,12 +81,12 @@ def create_runner(
|
|
|
81
81
|
f"Unknown runner mode '{mode}'. Available: {available}"
|
|
82
82
|
)
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
runner_cls = runners[mode]
|
|
85
85
|
if mode == "subprocess":
|
|
86
86
|
subprocess_mode = kwargs.pop("subprocess_mode", "run")
|
|
87
87
|
if subprocess_mode not in ["run", "debug"]:
|
|
88
88
|
subprocess_mode = "run"
|
|
89
|
-
return
|
|
89
|
+
return runner_cls(
|
|
90
90
|
waldiez=waldiez,
|
|
91
91
|
output_path=output_path,
|
|
92
92
|
uploads_root=uploads_root,
|
|
@@ -95,7 +95,9 @@ def create_runner(
|
|
|
95
95
|
mode=subprocess_mode,
|
|
96
96
|
**kwargs,
|
|
97
97
|
)
|
|
98
|
-
|
|
98
|
+
if mode != "debug" and "breakpoints" in kwargs: # pragma: no cover
|
|
99
|
+
kwargs.pop("breakpoints", None)
|
|
100
|
+
return runner_cls(
|
|
99
101
|
waldiez=waldiez,
|
|
100
102
|
output_path=output_path,
|
|
101
103
|
uploads_root=uploads_root,
|
|
@@ -111,7 +113,7 @@ class WaldiezRunner(WaldiezBaseRunner):
|
|
|
111
113
|
|
|
112
114
|
# pylint: disable=super-init-not-called
|
|
113
115
|
# noinspection PyMissingConstructor
|
|
114
|
-
def __init__(
|
|
116
|
+
def __init__( # pyright: ignore[reportMissingSuperCall]
|
|
115
117
|
self,
|
|
116
118
|
waldiez: Waldiez,
|
|
117
119
|
mode: Literal["standard", "debug"] = "standard",
|
|
@@ -150,6 +152,7 @@ class WaldiezRunner(WaldiezBaseRunner):
|
|
|
150
152
|
**kwargs,
|
|
151
153
|
)
|
|
152
154
|
|
|
155
|
+
@override
|
|
153
156
|
def __repr__(self) -> str: # pragma: no cover
|
|
154
157
|
"""Get the string representation of the runner.
|
|
155
158
|
|
|
@@ -179,6 +182,7 @@ class WaldiezRunner(WaldiezBaseRunner):
|
|
|
179
182
|
f"{type(self).__name__} has no attribute '{name}'"
|
|
180
183
|
) # pragma: no cover
|
|
181
184
|
|
|
185
|
+
@override
|
|
182
186
|
def _run(
|
|
183
187
|
self,
|
|
184
188
|
temp_dir: Path,
|
|
@@ -197,6 +201,7 @@ class WaldiezRunner(WaldiezBaseRunner):
|
|
|
197
201
|
**kwargs,
|
|
198
202
|
)
|
|
199
203
|
|
|
204
|
+
@override
|
|
200
205
|
async def _a_run(
|
|
201
206
|
self,
|
|
202
207
|
temp_dir: Path,
|
|
@@ -217,6 +222,7 @@ class WaldiezRunner(WaldiezBaseRunner):
|
|
|
217
222
|
**kwargs,
|
|
218
223
|
)
|
|
219
224
|
|
|
225
|
+
@override
|
|
220
226
|
@classmethod
|
|
221
227
|
def load(
|
|
222
228
|
cls,
|