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.

Files changed (55) hide show
  1. waldiez/__init__.py +15 -66
  2. waldiez/_version.py +1 -1
  3. waldiez/cli.py +11 -8
  4. waldiez/exporting/__init__.py +2 -0
  5. waldiez/exporting/agent/agent_exporter.py +11 -2
  6. waldiez/exporting/agent/utils/__init__.py +2 -0
  7. waldiez/exporting/agent/utils/agent_class_name.py +2 -0
  8. waldiez/exporting/agent/utils/agent_imports.py +5 -0
  9. waldiez/exporting/agent/utils/reasoning.py +36 -0
  10. waldiez/exporting/flow/flow_exporter.py +21 -8
  11. waldiez/exporting/flow/utils/__init__.py +10 -5
  12. waldiez/exporting/flow/utils/def_main.py +25 -20
  13. waldiez/exporting/flow/utils/flow_content.py +51 -3
  14. waldiez/exporting/flow/utils/importing_utils.py +7 -1
  15. waldiez/exporting/flow/utils/logging_utils.py +176 -42
  16. waldiez/models/__init__.py +8 -0
  17. waldiez/models/agents/__init__.py +10 -0
  18. waldiez/models/agents/agent/agent.py +10 -4
  19. waldiez/models/agents/agent/termination_message.py +2 -0
  20. waldiez/models/agents/agents.py +10 -0
  21. waldiez/models/agents/rag_user/retrieve_config.py +46 -17
  22. waldiez/models/agents/reasoning/__init__.py +13 -0
  23. waldiez/models/agents/reasoning/reasoning_agent.py +43 -0
  24. waldiez/models/agents/reasoning/reasoning_agent_data.py +116 -0
  25. waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +101 -0
  26. waldiez/models/agents/swarm_agent/__init__.py +2 -1
  27. waldiez/models/agents/swarm_agent/swarm_agent_data.py +2 -3
  28. waldiez/models/chat/chat_data.py +30 -63
  29. waldiez/models/chat/chat_message.py +2 -26
  30. waldiez/models/chat/chat_nested.py +7 -8
  31. waldiez/models/common/__init__.py +3 -18
  32. waldiez/models/common/date_utils.py +18 -0
  33. waldiez/models/common/dict_utils.py +37 -0
  34. waldiez/models/common/method_utils.py +2 -5
  35. waldiez/models/flow/flow_data.py +1 -1
  36. waldiez/models/model/model.py +3 -0
  37. waldiez/models/model/model_data.py +2 -1
  38. waldiez/models/waldiez.py +4 -1
  39. waldiez/runner.py +3 -3
  40. waldiez/running/environment.py +22 -16
  41. waldiez/running/gen_seq_diagram.py +7 -4
  42. waldiez/running/running.py +69 -19
  43. waldiez/utils/__init__.py +15 -0
  44. waldiez/utils/cli_extras/__init__.py +30 -0
  45. waldiez/{cli_extras.py → utils/cli_extras/jupyter.py} +9 -20
  46. waldiez/utils/cli_extras/studio.py +36 -0
  47. waldiez/{conflict_checker.py → utils/conflict_checker.py} +14 -3
  48. waldiez/utils/flaml_warnings.py +17 -0
  49. waldiez/utils/pysqlite3_checker.py +249 -0
  50. {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/METADATA +27 -19
  51. {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/RECORD +55 -42
  52. waldiez-0.3.8.dist-info/licenses/NOTICE.md +5 -0
  53. {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/WHEEL +0 -0
  54. {waldiez-0.3.6.dist-info → waldiez-0.3.8.dist-info}/entry_points.txt +0 -0
  55. {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
- # pylint: disable=inconsistent-quotes
19
- def get_logging_start_string(tabs: int = 0) -> str:
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
- >>> get_logging_start_string()
36
- runtime_logging.start(
37
- logger_type="sqlite",
38
- config={"dbname": "flow.db"},
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"{tab}runtime_logging.start(" + "\n"
44
- content += f'{tab} logger_type="sqlite",' + "\n"
45
- content += f'{tab} config={{"dbname": "flow.db"}},' + "\n"
46
- content += f"{tab})" + "\n"
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 get_sqlite_out() -> str:
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
- def get_sqlite_out_call(tabs: int = 0) -> str:
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, optional
162
- The number of tabs to use for indentation, by default 0
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
- content += tab + ' get_sqlite_out("flow.db", table, dest)\n'
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
@@ -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["user", "assistant", "manager", "rag_user", "swarm"]
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["user", "assistant", "manager", "rag_user", "swarm"]
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["user", "assistant", "manager", "rag_user", "swarm"],
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 swarm"
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,
@@ -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
- for index, path in enumerate(doc_paths):
722
- is_remote, is_raw = is_remote_path(path)
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
- doc_paths[index] = f'r"{path}"'
727
+ resolved = f'r"{resolved}"'
728
+ if resolved not in paths:
729
+ paths.append(resolved)
726
730
  continue
727
- if path.startswith("file://"):
728
- path = path[len("file://") :]
729
- if path.startswith('r"file://"'):
730
- path = path[len('r"file://"') :]
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
- doc_paths[index] = f'r"{path}"'
736
+ resolved = f'r"{resolved}"'
737
+ if resolved not in paths:
738
+ paths.append(resolved)
734
739
  continue
735
- resolved = resolve_path(path, is_raw)
736
- doc_paths[index] = resolved
737
- self.docs_path = doc_paths
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}"', 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 resolve_path(path: str, is_raw: bool) -> str:
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()