waldiez 0.3.6__py3-none-any.whl → 0.3.8__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 +15 -66
- waldiez/_version.py +1 -1
- waldiez/cli.py +11 -8
- waldiez/exporting/__init__.py +2 -0
- waldiez/exporting/agent/agent_exporter.py +11 -2
- waldiez/exporting/agent/utils/__init__.py +2 -0
- waldiez/exporting/agent/utils/agent_class_name.py +2 -0
- waldiez/exporting/agent/utils/agent_imports.py +5 -0
- waldiez/exporting/agent/utils/reasoning.py +36 -0
- waldiez/exporting/flow/flow_exporter.py +21 -8
- waldiez/exporting/flow/utils/__init__.py +10 -5
- waldiez/exporting/flow/utils/def_main.py +25 -20
- waldiez/exporting/flow/utils/flow_content.py +51 -3
- waldiez/exporting/flow/utils/importing_utils.py +7 -1
- waldiez/exporting/flow/utils/logging_utils.py +176 -42
- waldiez/models/__init__.py +8 -0
- waldiez/models/agents/__init__.py +10 -0
- waldiez/models/agents/agent/agent.py +10 -4
- waldiez/models/agents/agent/termination_message.py +2 -0
- waldiez/models/agents/agents.py +10 -0
- waldiez/models/agents/rag_user/retrieve_config.py +46 -17
- waldiez/models/agents/reasoning/__init__.py +13 -0
- waldiez/models/agents/reasoning/reasoning_agent.py +43 -0
- waldiez/models/agents/reasoning/reasoning_agent_data.py +116 -0
- waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +101 -0
- waldiez/models/agents/swarm_agent/__init__.py +2 -1
- waldiez/models/agents/swarm_agent/swarm_agent_data.py +2 -3
- waldiez/models/chat/chat_data.py +30 -63
- waldiez/models/chat/chat_message.py +2 -26
- waldiez/models/chat/chat_nested.py +7 -8
- waldiez/models/common/__init__.py +3 -18
- waldiez/models/common/date_utils.py +18 -0
- waldiez/models/common/dict_utils.py +37 -0
- waldiez/models/common/method_utils.py +2 -5
- waldiez/models/flow/flow_data.py +1 -1
- waldiez/models/model/model.py +3 -0
- waldiez/models/model/model_data.py +2 -1
- waldiez/models/waldiez.py +4 -1
- waldiez/runner.py +3 -3
- waldiez/running/environment.py +22 -16
- waldiez/running/gen_seq_diagram.py +7 -4
- waldiez/running/running.py +69 -19
- waldiez/utils/__init__.py +15 -0
- waldiez/utils/cli_extras/__init__.py +30 -0
- waldiez/{cli_extras.py → utils/cli_extras/jupyter.py} +9 -20
- waldiez/utils/cli_extras/studio.py +36 -0
- waldiez/{conflict_checker.py → utils/conflict_checker.py} +14 -3
- waldiez/utils/flaml_warnings.py +17 -0
- waldiez/utils/pysqlite3_checker.py +249 -0
- {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/METADATA +27 -19
- {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/RECORD +55 -42
- waldiez-0.3.8.dist-info/licenses/NOTICE.md +5 -0
- {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/WHEEL +0 -0
- {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/entry_points.txt +0 -0
- {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
# flake8: noqa: E501
|
|
3
4
|
"""Logging related string generation functions.
|
|
4
5
|
|
|
5
6
|
Functions
|
|
@@ -15,9 +16,8 @@ get_sqlite_to_csv_call_string
|
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"""Get the logging start string.
|
|
19
|
+
def get_start_logging(tabs: int = 0) -> str:
|
|
20
|
+
"""Get the logging start call string.
|
|
21
21
|
|
|
22
22
|
Parameters
|
|
23
23
|
----------
|
|
@@ -32,47 +32,28 @@ def get_logging_start_string(tabs: int = 0) -> str:
|
|
|
32
32
|
Example
|
|
33
33
|
-------
|
|
34
34
|
```python
|
|
35
|
-
>>>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
>>> get_start_logging()
|
|
36
|
+
def start_logging() -> None:
|
|
37
|
+
\"\"\"Start logging.\"\"\"
|
|
38
|
+
runtime_logging.start(
|
|
39
|
+
logger_type="sqlite",
|
|
40
|
+
config={"dbname": "flow.db"},
|
|
41
|
+
)
|
|
41
42
|
"""
|
|
42
43
|
tab = " " * tabs
|
|
43
|
-
content = f
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
content = f'''
|
|
45
|
+
{tab}def start_logging() -> None:
|
|
46
|
+
{tab} """Start logging."""
|
|
47
|
+
{tab} runtime_logging.start(
|
|
48
|
+
{tab} logger_type="sqlite",
|
|
49
|
+
{tab} config={{"dbname": "flow.db"}},
|
|
50
|
+
{tab} )
|
|
51
|
+
'''
|
|
47
52
|
return content
|
|
48
53
|
|
|
49
54
|
|
|
50
|
-
def get_logging_stop_string(tabs: int = 0) -> str:
|
|
51
|
-
"""Get the logging stop string.
|
|
52
|
-
|
|
53
|
-
Parameters
|
|
54
|
-
----------
|
|
55
|
-
tabs : int, optional
|
|
56
|
-
The number of tabs to use for indentation, by default 0
|
|
57
|
-
|
|
58
|
-
Returns
|
|
59
|
-
-------
|
|
60
|
-
str
|
|
61
|
-
The logging stop string
|
|
62
|
-
|
|
63
|
-
Example
|
|
64
|
-
-------
|
|
65
|
-
```python
|
|
66
|
-
>>> get_logging_stop_string()
|
|
67
|
-
runtime_logging.stop()
|
|
68
|
-
```
|
|
69
|
-
"""
|
|
70
|
-
tab = " " * tabs
|
|
71
|
-
return f"{tab}runtime_logging.stop()" + "\n"
|
|
72
|
-
|
|
73
|
-
|
|
74
55
|
# pylint: disable=differing-param-doc,differing-type-doc
|
|
75
|
-
def
|
|
56
|
+
def get_sync_sqlite_out() -> str:
|
|
76
57
|
"""Get the sqlite to csv and json conversion code string.
|
|
77
58
|
|
|
78
59
|
Returns
|
|
@@ -153,13 +134,118 @@ def get_sqlite_out() -> str:
|
|
|
153
134
|
return content
|
|
154
135
|
|
|
155
136
|
|
|
156
|
-
|
|
137
|
+
# pylint: disable=differing-param-doc,differing-type-doc,line-too-long
|
|
138
|
+
def get_async_sqlite_out() -> str:
|
|
139
|
+
"""Get the sqlite to csv and json conversion code string.
|
|
140
|
+
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
str
|
|
144
|
+
The sqlite to csv and json conversion code string.
|
|
145
|
+
|
|
146
|
+
Example
|
|
147
|
+
-------
|
|
148
|
+
```python
|
|
149
|
+
>>> get_sqlite_outputs()
|
|
150
|
+
async def get_sqlite_out(dbname: str, table: str, csv_file: str) -> None:
|
|
151
|
+
\"\"\"Convert a sqlite table to csv and json files.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
dbname : str
|
|
156
|
+
The sqlite database name.
|
|
157
|
+
table : str
|
|
158
|
+
The table name.
|
|
159
|
+
csv_file : str
|
|
160
|
+
The csv file name.
|
|
161
|
+
\"\"\"
|
|
162
|
+
conn = await aiosqlite.connect(dbname)
|
|
163
|
+
query = f"SELECT * FROM {table}" # nosec
|
|
164
|
+
try:
|
|
165
|
+
cursor = await conn.execute(query)
|
|
166
|
+
except BaseException: # pylint: disable=broad-except
|
|
167
|
+
await conn.close()
|
|
168
|
+
return
|
|
169
|
+
rows = await cursor.fetchall()
|
|
170
|
+
column_names = [description[0] for description in cursor.description]
|
|
171
|
+
data = [dict(zip(column_names, row)) for row in rows]
|
|
172
|
+
await cursor.close()
|
|
173
|
+
await conn.close()
|
|
174
|
+
async with aiofiles.open(csv_file, "w", newline="", encoding="utf-8") as file:
|
|
175
|
+
csv_writer = csv.DictWriter(file, fieldnames=column_names)
|
|
176
|
+
csv_writer.writeheader()
|
|
177
|
+
csv_writer.writerows(data)
|
|
178
|
+
json_file = csv_file.replace(".csv", ".json")
|
|
179
|
+
async with aiofiles.open(json_file, "w", encoding="utf-8") as file:
|
|
180
|
+
await file.write(json.dumps(data, indent=4, ensure_ascii=False)
|
|
181
|
+
```
|
|
182
|
+
"""
|
|
183
|
+
content = "\n\n"
|
|
184
|
+
content += "async def get_sqlite_out(dbname: str, table: str, csv_file: str) -> None:\n"
|
|
185
|
+
content += ' """Convert a sqlite table to csv and json files.\n\n'
|
|
186
|
+
content += " Parameters\n"
|
|
187
|
+
content += " ----------\n"
|
|
188
|
+
content += " dbname : str\n"
|
|
189
|
+
content += " The sqlite database name.\n"
|
|
190
|
+
content += " table : str\n"
|
|
191
|
+
content += " The table name.\n"
|
|
192
|
+
content += " csv_file : str\n"
|
|
193
|
+
content += " The csv file name.\n"
|
|
194
|
+
content += ' """\n'
|
|
195
|
+
content += " conn = await aiosqlite.connect(dbname)\n"
|
|
196
|
+
content += ' query = f"SELECT * FROM {table}" # nosec\n'
|
|
197
|
+
content += " try:\n"
|
|
198
|
+
content += " cursor = await conn.execute(query)\n"
|
|
199
|
+
content += " except BaseException: # pylint: disable=broad-except\n"
|
|
200
|
+
content += " await conn.close()\n"
|
|
201
|
+
content += " return\n"
|
|
202
|
+
content += " rows = await cursor.fetchall()\n"
|
|
203
|
+
content += " column_names = [description[0] for description "
|
|
204
|
+
content += "in cursor.description]\n"
|
|
205
|
+
content += " data = [dict(zip(column_names, row)) for row in rows]\n"
|
|
206
|
+
content += " await cursor.close()\n"
|
|
207
|
+
content += " await conn.close()\n"
|
|
208
|
+
content += (
|
|
209
|
+
' async with aiofiles.open(csv_file, "w", newline="", '
|
|
210
|
+
'encoding="utf-8") as file:\n'
|
|
211
|
+
)
|
|
212
|
+
content += ' csv_writer = AsyncDictWriter(file, fieldnames=column_names, dialect="unix")\n'
|
|
213
|
+
content += " await csv_writer.writeheader()\n"
|
|
214
|
+
content += " await csv_writer.writerows(data)\n"
|
|
215
|
+
content += ' json_file = csv_file.replace(".csv", ".json")\n'
|
|
216
|
+
content += ' async with aiofiles.open(json_file, "w", encoding="utf-8") as file:\n'
|
|
217
|
+
content += " await file.write(json.dumps(data, indent=4, ensure_ascii=False))\n"
|
|
218
|
+
content += "\n\n"
|
|
219
|
+
return content
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def get_sqlite_out(is_async: bool) -> str:
|
|
223
|
+
"""Get the sqlite to csv and json conversion code string.
|
|
224
|
+
|
|
225
|
+
Parameters
|
|
226
|
+
----------
|
|
227
|
+
is_async : bool
|
|
228
|
+
Whether to use async mode.
|
|
229
|
+
|
|
230
|
+
Returns
|
|
231
|
+
-------
|
|
232
|
+
str
|
|
233
|
+
The sqlite to csv and json conversion code string.
|
|
234
|
+
"""
|
|
235
|
+
if is_async:
|
|
236
|
+
return get_async_sqlite_out()
|
|
237
|
+
return get_sync_sqlite_out()
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def get_sqlite_out_call(tabs: int, is_async: bool) -> str:
|
|
157
241
|
"""Get the sqlite to csv and json conversion call string.
|
|
158
242
|
|
|
159
243
|
Parameters
|
|
160
244
|
----------
|
|
161
|
-
tabs : int
|
|
162
|
-
The number of tabs to use for indentation
|
|
245
|
+
tabs : int
|
|
246
|
+
The number of tabs to use for indentation
|
|
247
|
+
is_async : bool
|
|
248
|
+
Whether to use async mode
|
|
163
249
|
|
|
164
250
|
Returns
|
|
165
251
|
-------
|
|
@@ -203,5 +289,53 @@ def get_sqlite_out_call(tabs: int = 0) -> str:
|
|
|
203
289
|
content += tab + f' "{table}",' + "\n"
|
|
204
290
|
content += tab + "]:\n"
|
|
205
291
|
content += tab + ' dest = os.path.join("logs", f"{table}.csv")' + "\n"
|
|
206
|
-
|
|
292
|
+
if is_async:
|
|
293
|
+
content += tab + ' await get_sqlite_out("flow.db", table, dest)\n'
|
|
294
|
+
else:
|
|
295
|
+
content += tab + ' get_sqlite_out("flow.db", table, dest)\n'
|
|
296
|
+
return content
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def get_stop_logging(tabs: int, is_async: bool) -> str:
|
|
300
|
+
"""Get the function to stop logging and gather logs.
|
|
301
|
+
|
|
302
|
+
Parameters
|
|
303
|
+
----------
|
|
304
|
+
tabs : int
|
|
305
|
+
The number of tabs to use for indentation
|
|
306
|
+
is_async : bool
|
|
307
|
+
Whether to use async mode
|
|
308
|
+
|
|
309
|
+
Returns
|
|
310
|
+
-------
|
|
311
|
+
str
|
|
312
|
+
The logging stop string.
|
|
313
|
+
|
|
314
|
+
Example
|
|
315
|
+
-------
|
|
316
|
+
```python
|
|
317
|
+
>>> get_logging_stop_string()
|
|
318
|
+
def stop_logging() -> None:
|
|
319
|
+
\"\"\"Stop logging.\"\"\"
|
|
320
|
+
runtime_logging.stop()
|
|
321
|
+
for table in [
|
|
322
|
+
"chat_completions",
|
|
323
|
+
"agents",
|
|
324
|
+
"oai_wrappers",
|
|
325
|
+
"oai_clients",
|
|
326
|
+
"version",
|
|
327
|
+
"events",
|
|
328
|
+
"function_calls",
|
|
329
|
+
]:
|
|
330
|
+
dest = os.path.join("logs", f"{table}.csv")
|
|
331
|
+
get_sqlite_out("flow.db", table, dest)
|
|
332
|
+
"""
|
|
333
|
+
tab = " " * tabs
|
|
334
|
+
content = "\n" + tab
|
|
335
|
+
if is_async:
|
|
336
|
+
content += "async "
|
|
337
|
+
content += "def stop_logging() -> None:\n"
|
|
338
|
+
content += ' """Stop logging."""\n'
|
|
339
|
+
content += f"{tab} runtime_logging.stop()\n"
|
|
340
|
+
content += get_sqlite_out_call(tabs + 1, is_async)
|
|
207
341
|
return content
|
waldiez/models/__init__.py
CHANGED
|
@@ -37,11 +37,15 @@ from .agents import (
|
|
|
37
37
|
WaldiezRagUserTask,
|
|
38
38
|
WaldiezRagUserVectorDb,
|
|
39
39
|
WaldiezRagUserVectorDbConfig,
|
|
40
|
+
WaldiezReasoningAgent,
|
|
41
|
+
WaldiezReasoningAgentData,
|
|
42
|
+
WaldiezReasoningAgentReasonConfig,
|
|
40
43
|
WaldiezSwarmAfterWork,
|
|
41
44
|
WaldiezSwarmAfterWorkOption,
|
|
42
45
|
WaldiezSwarmAfterWorkRecipientType,
|
|
43
46
|
WaldiezSwarmAgent,
|
|
44
47
|
WaldiezSwarmAgentData,
|
|
48
|
+
WaldiezSwarmHandoff,
|
|
45
49
|
WaldiezSwarmOnCondition,
|
|
46
50
|
WaldiezSwarmOnConditionAvailable,
|
|
47
51
|
WaldiezSwarmOnConditionTarget,
|
|
@@ -103,6 +107,9 @@ __all__ = [
|
|
|
103
107
|
"WaldiezModelPrice",
|
|
104
108
|
"WaldiezRagUser",
|
|
105
109
|
"WaldiezRagUserData",
|
|
110
|
+
"WaldiezReasoningAgent",
|
|
111
|
+
"WaldiezReasoningAgentData",
|
|
112
|
+
"WaldiezReasoningAgentReasonConfig",
|
|
106
113
|
"WaldiezSkill",
|
|
107
114
|
"WaldiezSkillData",
|
|
108
115
|
"WaldiezUserProxy",
|
|
@@ -118,6 +125,7 @@ __all__ = [
|
|
|
118
125
|
"WaldiezSwarmAfterWorkOption",
|
|
119
126
|
"WaldiezSwarmAfterWorkRecipientType",
|
|
120
127
|
"WaldiezSwarmAgentData",
|
|
128
|
+
"WaldiezSwarmHandoff",
|
|
121
129
|
"WaldiezSwarmOnCondition",
|
|
122
130
|
"WaldiezSwarmOnConditionTarget",
|
|
123
131
|
"WaldiezSwarmOnConditionAvailable",
|
|
@@ -48,6 +48,11 @@ from .rag_user import (
|
|
|
48
48
|
WaldiezRagUserVectorDb,
|
|
49
49
|
WaldiezRagUserVectorDbConfig,
|
|
50
50
|
)
|
|
51
|
+
from .reasoning import (
|
|
52
|
+
WaldiezReasoningAgent,
|
|
53
|
+
WaldiezReasoningAgentData,
|
|
54
|
+
WaldiezReasoningAgentReasonConfig,
|
|
55
|
+
)
|
|
51
56
|
from .swarm_agent import (
|
|
52
57
|
CUSTOM_AFTER_WORK,
|
|
53
58
|
CUSTOM_AFTER_WORK_ARGS,
|
|
@@ -63,6 +68,7 @@ from .swarm_agent import (
|
|
|
63
68
|
WaldiezSwarmAfterWorkRecipientType,
|
|
64
69
|
WaldiezSwarmAgent,
|
|
65
70
|
WaldiezSwarmAgentData,
|
|
71
|
+
WaldiezSwarmHandoff,
|
|
66
72
|
WaldiezSwarmOnCondition,
|
|
67
73
|
WaldiezSwarmOnConditionAvailable,
|
|
68
74
|
WaldiezSwarmOnConditionTarget,
|
|
@@ -116,6 +122,9 @@ __all__ = [
|
|
|
116
122
|
"WaldiezRagUser",
|
|
117
123
|
"WaldiezRagUserData",
|
|
118
124
|
"WaldiezRagUserModels",
|
|
125
|
+
"WaldiezReasoningAgent",
|
|
126
|
+
"WaldiezReasoningAgentData",
|
|
127
|
+
"WaldiezReasoningAgentReasonConfig",
|
|
119
128
|
"WaldiezUserProxy",
|
|
120
129
|
"WaldiezUserProxyData",
|
|
121
130
|
"WaldiezRagUserRetrieveConfig",
|
|
@@ -128,6 +137,7 @@ __all__ = [
|
|
|
128
137
|
"WaldiezSwarmAfterWork",
|
|
129
138
|
"WaldiezSwarmAfterWorkOption",
|
|
130
139
|
"WaldiezSwarmAfterWorkRecipientType",
|
|
140
|
+
"WaldiezSwarmHandoff",
|
|
131
141
|
"WaldiezSwarmOnCondition",
|
|
132
142
|
"WaldiezSwarmOnConditionTarget",
|
|
133
143
|
"WaldiezSwarmOnConditionAvailable",
|
|
@@ -11,7 +11,9 @@ from ...common import WaldiezBase, now
|
|
|
11
11
|
from .agent_data import WaldiezAgentData
|
|
12
12
|
from .code_execution import WaldiezAgentCodeExecutionConfig
|
|
13
13
|
|
|
14
|
-
WaldiezAgentType = Literal[
|
|
14
|
+
WaldiezAgentType = Literal[
|
|
15
|
+
"user", "assistant", "manager", "rag_user", "swarm", "reasoning"
|
|
16
|
+
]
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class WaldiezAgent(WaldiezBase):
|
|
@@ -23,7 +25,9 @@ class WaldiezAgent(WaldiezBase):
|
|
|
23
25
|
The ID of the agent.
|
|
24
26
|
type : Literal["agent"]
|
|
25
27
|
The type of the "node" in a graph: "agent"
|
|
26
|
-
agent_type : Literal[
|
|
28
|
+
agent_type : Literal[
|
|
29
|
+
"user", "assistant", "manager", "rag_user", "swarm", "reasoning"
|
|
30
|
+
]
|
|
27
31
|
The type of the agent
|
|
28
32
|
name: str
|
|
29
33
|
The name of the agent.
|
|
@@ -61,13 +65,15 @@ class WaldiezAgent(WaldiezBase):
|
|
|
61
65
|
),
|
|
62
66
|
]
|
|
63
67
|
agent_type: Annotated[
|
|
64
|
-
Literal[
|
|
68
|
+
Literal[
|
|
69
|
+
"user", "assistant", "manager", "rag_user", "swarm", "reasoning"
|
|
70
|
+
],
|
|
65
71
|
Field(
|
|
66
72
|
...,
|
|
67
73
|
title="Agent type",
|
|
68
74
|
description=(
|
|
69
75
|
"The type of the agent: user, assistant, group manager, "
|
|
70
|
-
"rag_user, or
|
|
76
|
+
"rag_user, swarm or reasoning"
|
|
71
77
|
),
|
|
72
78
|
),
|
|
73
79
|
]
|
|
@@ -115,6 +115,8 @@ class WaldiezAgentTerminationMessage(WaldiezBase):
|
|
|
115
115
|
function_name = f"{name_prefix}_{function_name}"
|
|
116
116
|
if name_suffix:
|
|
117
117
|
function_name = f"{function_name}_{name_suffix}"
|
|
118
|
+
if self.type in ("none", "keyword"):
|
|
119
|
+
return self.string, function_name
|
|
118
120
|
return (
|
|
119
121
|
generate_function(
|
|
120
122
|
function_name=function_name,
|
waldiez/models/agents/agents.py
CHANGED
|
@@ -12,6 +12,7 @@ from .agent import WaldiezAgent
|
|
|
12
12
|
from .assistant import WaldiezAssistant
|
|
13
13
|
from .group_manager.group_manager import WaldiezGroupManager
|
|
14
14
|
from .rag_user import WaldiezRagUser
|
|
15
|
+
from .reasoning import WaldiezReasoningAgent
|
|
15
16
|
from .swarm_agent import WaldiezSwarmAgent
|
|
16
17
|
from .user_proxy import WaldiezUserProxy
|
|
17
18
|
|
|
@@ -71,6 +72,14 @@ class WaldiezAgents(WaldiezBase):
|
|
|
71
72
|
default_factory=list,
|
|
72
73
|
),
|
|
73
74
|
]
|
|
75
|
+
reasoning_agents: Annotated[
|
|
76
|
+
List[WaldiezReasoningAgent],
|
|
77
|
+
Field(
|
|
78
|
+
title="Reasoning Agents.",
|
|
79
|
+
description="Reasoning agents",
|
|
80
|
+
default_factory=list,
|
|
81
|
+
),
|
|
82
|
+
]
|
|
74
83
|
|
|
75
84
|
@property
|
|
76
85
|
def members(self) -> Iterator[WaldiezAgent]:
|
|
@@ -84,6 +93,7 @@ class WaldiezAgents(WaldiezBase):
|
|
|
84
93
|
yield from self.users
|
|
85
94
|
yield from self.assistants
|
|
86
95
|
yield from self.rag_users
|
|
96
|
+
yield from self.reasoning_agents
|
|
87
97
|
yield from self.swarm_agents
|
|
88
98
|
yield from self.managers
|
|
89
99
|
|
|
@@ -718,23 +718,29 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
|
|
|
718
718
|
if isinstance(self.docs_path, str)
|
|
719
719
|
else self.docs_path
|
|
720
720
|
)
|
|
721
|
-
|
|
722
|
-
|
|
721
|
+
paths: List[str] = []
|
|
722
|
+
for path in doc_paths:
|
|
723
|
+
resolved = path
|
|
724
|
+
is_remote, is_raw = is_remote_path(resolved)
|
|
723
725
|
if is_remote:
|
|
724
726
|
if not is_raw:
|
|
725
|
-
|
|
727
|
+
resolved = f'r"{resolved}"'
|
|
728
|
+
if resolved not in paths:
|
|
729
|
+
paths.append(resolved)
|
|
726
730
|
continue
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if string_represents_folder(path):
|
|
731
|
+
resolved = remove_file_scheme(resolved)
|
|
732
|
+
is_raw = resolved.startswith(("r'", 'r"'))
|
|
733
|
+
maybe_folder = string_represents_folder(resolved)
|
|
734
|
+
if maybe_folder:
|
|
732
735
|
if not is_raw:
|
|
733
|
-
|
|
736
|
+
resolved = f'r"{resolved}"'
|
|
737
|
+
if resolved not in paths:
|
|
738
|
+
paths.append(resolved)
|
|
734
739
|
continue
|
|
735
|
-
resolved = resolve_path(
|
|
736
|
-
|
|
737
|
-
|
|
740
|
+
resolved = resolve_path(resolved, is_raw, not maybe_folder)
|
|
741
|
+
if resolved not in paths:
|
|
742
|
+
paths.append(resolved)
|
|
743
|
+
self.docs_path = paths
|
|
738
744
|
|
|
739
745
|
@model_validator(mode="after")
|
|
740
746
|
def validate_rag_user_data(self) -> Self:
|
|
@@ -796,12 +802,35 @@ def is_remote_path(path: str) -> Tuple[bool, bool]:
|
|
|
796
802
|
"""
|
|
797
803
|
is_raw = path.startswith(("r'", 'r"'))
|
|
798
804
|
for not_local in NOT_LOCAL:
|
|
799
|
-
if path.startswith((not_local, f'r"{not_local}
|
|
805
|
+
if path.startswith((not_local, f'r"{not_local}', f"r'{not_local}")):
|
|
800
806
|
return True, is_raw
|
|
801
807
|
return False, is_raw
|
|
802
808
|
|
|
803
809
|
|
|
804
|
-
def
|
|
810
|
+
def remove_file_scheme(path: str) -> str:
|
|
811
|
+
"""Remove the file:// scheme from a path.
|
|
812
|
+
|
|
813
|
+
Parameters
|
|
814
|
+
----------
|
|
815
|
+
path : str
|
|
816
|
+
The path to remove the scheme from.
|
|
817
|
+
|
|
818
|
+
Returns
|
|
819
|
+
-------
|
|
820
|
+
str
|
|
821
|
+
The path without the scheme.
|
|
822
|
+
"""
|
|
823
|
+
resolved = str(path)
|
|
824
|
+
while resolved.startswith('r"file://') and resolved.endswith('"'):
|
|
825
|
+
resolved = resolved[len('r"file://') : -1]
|
|
826
|
+
while resolved.startswith("r'file://") and resolved.endswith("'"):
|
|
827
|
+
resolved = resolved[len("r'file://") : -1]
|
|
828
|
+
while resolved.startswith("file://"):
|
|
829
|
+
resolved = resolved[len("file://") :]
|
|
830
|
+
return resolved
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
def resolve_path(path: str, is_raw: bool, must_exist: bool) -> str:
|
|
805
834
|
"""Try to resolve a path.
|
|
806
835
|
|
|
807
836
|
Parameters
|
|
@@ -810,6 +839,8 @@ def resolve_path(path: str, is_raw: bool) -> str:
|
|
|
810
839
|
The path to resolve.
|
|
811
840
|
is_raw : bool
|
|
812
841
|
If the path is a raw string.
|
|
842
|
+
must_exist : bool
|
|
843
|
+
If the path must exist.
|
|
813
844
|
Returns
|
|
814
845
|
-------
|
|
815
846
|
Path
|
|
@@ -824,8 +855,6 @@ def resolve_path(path: str, is_raw: bool) -> str:
|
|
|
824
855
|
path_string = path
|
|
825
856
|
if is_raw:
|
|
826
857
|
path_string = path[2:-1]
|
|
827
|
-
if path_string.startswith(NOT_LOCAL):
|
|
828
|
-
return path
|
|
829
858
|
try:
|
|
830
859
|
resolved = Path(path_string).resolve()
|
|
831
860
|
except BaseException as error: # pragma: no cover
|
|
@@ -838,6 +867,6 @@ def resolve_path(path: str, is_raw: bool) -> str:
|
|
|
838
867
|
f"Path {path} is not a valid local path."
|
|
839
868
|
) from error
|
|
840
869
|
return raw_string
|
|
841
|
-
if not resolved.exists():
|
|
870
|
+
if not resolved.exists() and must_exist:
|
|
842
871
|
raise ValueError(f"Path {path} does not exist.")
|
|
843
872
|
return f'r"{resolved}"'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Reasoning agent model."""
|
|
4
|
+
|
|
5
|
+
from .reasoning_agent import WaldiezReasoningAgent
|
|
6
|
+
from .reasoning_agent_data import WaldiezReasoningAgentData
|
|
7
|
+
from .reasoning_agent_reason_config import WaldiezReasoningAgentReasonConfig
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"WaldiezReasoningAgentReasonConfig",
|
|
11
|
+
"WaldiezReasoningAgent",
|
|
12
|
+
"WaldiezReasoningAgentData",
|
|
13
|
+
]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Reasoning agent model."""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict
|
|
6
|
+
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
from typing_extensions import Annotated, Literal
|
|
9
|
+
|
|
10
|
+
from ..agent import WaldiezAgent
|
|
11
|
+
from .reasoning_agent_data import WaldiezReasoningAgentData
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class WaldiezReasoningAgent(WaldiezAgent):
|
|
15
|
+
"""Reasoning agent model."""
|
|
16
|
+
|
|
17
|
+
agent_type: Annotated[
|
|
18
|
+
Literal["reasoning"],
|
|
19
|
+
Field(
|
|
20
|
+
"reasoning",
|
|
21
|
+
title="Agent type",
|
|
22
|
+
description="The agent type in a graph: 'reasoning'",
|
|
23
|
+
alias="agentType",
|
|
24
|
+
),
|
|
25
|
+
]
|
|
26
|
+
data: Annotated[
|
|
27
|
+
WaldiezReasoningAgentData,
|
|
28
|
+
Field(
|
|
29
|
+
title="Data",
|
|
30
|
+
description="The reasoning agent's data",
|
|
31
|
+
default_factory=WaldiezReasoningAgentData,
|
|
32
|
+
),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
def get_reasoning_config(self) -> Dict[str, Any]:
|
|
36
|
+
"""Get the reasoning configuration based on its method.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
dict
|
|
41
|
+
The reasoning configuration.
|
|
42
|
+
"""
|
|
43
|
+
return self.data.get_reasoning_config()
|