waldiez 0.4.7__py3-none-any.whl → 0.4.9__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 (248) hide show
  1. waldiez/__init__.py +5 -5
  2. waldiez/_version.py +1 -1
  3. waldiez/cli.py +97 -102
  4. waldiez/exporter.py +61 -19
  5. waldiez/exporting/__init__.py +25 -6
  6. waldiez/exporting/agent/__init__.py +7 -3
  7. waldiez/exporting/agent/code_execution.py +114 -0
  8. waldiez/exporting/agent/exporter.py +354 -0
  9. waldiez/exporting/agent/extras/__init__.py +15 -0
  10. waldiez/exporting/agent/extras/captain_agent_extras.py +315 -0
  11. waldiez/exporting/agent/extras/group/target.py +178 -0
  12. waldiez/exporting/agent/extras/group_manager_agent_extas.py +500 -0
  13. waldiez/exporting/agent/extras/group_member_extras.py +181 -0
  14. waldiez/exporting/agent/extras/handoffs/__init__.py +19 -0
  15. waldiez/exporting/agent/extras/handoffs/after_work.py +78 -0
  16. waldiez/exporting/agent/extras/handoffs/available.py +74 -0
  17. waldiez/exporting/agent/extras/handoffs/condition.py +158 -0
  18. waldiez/exporting/agent/extras/handoffs/handoff.py +171 -0
  19. waldiez/exporting/agent/extras/handoffs/target.py +189 -0
  20. waldiez/exporting/agent/extras/rag/__init__.py +10 -0
  21. waldiez/exporting/agent/{utils/rag_user/chroma_utils.py → extras/rag/chroma_extras.py} +37 -24
  22. waldiez/exporting/agent/{utils/rag_user/mongo_utils.py → extras/rag/mongo_extras.py} +10 -10
  23. waldiez/exporting/agent/{utils/rag_user/pgvector_utils.py → extras/rag/pgvector_extras.py} +13 -13
  24. waldiez/exporting/agent/{utils/rag_user/qdrant_utils.py → extras/rag/qdrant_extras.py} +13 -13
  25. waldiez/exporting/agent/{utils/rag_user/vector_db.py → extras/rag/vector_db_extras.py} +59 -46
  26. waldiez/exporting/agent/extras/rag_user_proxy_agent_extras.py +245 -0
  27. waldiez/exporting/agent/extras/reasoning_agent_extras.py +88 -0
  28. waldiez/exporting/agent/factory.py +95 -0
  29. waldiez/exporting/agent/processor.py +150 -0
  30. waldiez/exporting/agent/system_message.py +36 -0
  31. waldiez/exporting/agent/termination.py +50 -0
  32. waldiez/exporting/chats/__init__.py +7 -3
  33. waldiez/exporting/chats/exporter.py +97 -0
  34. waldiez/exporting/chats/factory.py +65 -0
  35. waldiez/exporting/chats/processor.py +226 -0
  36. waldiez/exporting/chats/utils/__init__.py +6 -5
  37. waldiez/exporting/chats/utils/common.py +11 -45
  38. waldiez/exporting/chats/utils/group.py +55 -0
  39. waldiez/exporting/chats/utils/nested.py +37 -52
  40. waldiez/exporting/chats/utils/sequential.py +72 -61
  41. waldiez/exporting/chats/utils/{single_chat.py → single.py} +48 -50
  42. waldiez/exporting/core/__init__.py +196 -0
  43. waldiez/exporting/core/constants.py +17 -0
  44. waldiez/exporting/core/content.py +69 -0
  45. waldiez/exporting/core/context.py +244 -0
  46. waldiez/exporting/core/enums.py +89 -0
  47. waldiez/exporting/core/errors.py +19 -0
  48. waldiez/exporting/core/exporter.py +390 -0
  49. waldiez/exporting/core/exporters.py +67 -0
  50. waldiez/exporting/core/extras/__init__.py +39 -0
  51. waldiez/exporting/core/extras/agent_extras/__init__.py +27 -0
  52. waldiez/exporting/core/extras/agent_extras/captain_extras.py +57 -0
  53. waldiez/exporting/core/extras/agent_extras/group_manager_extras.py +102 -0
  54. waldiez/exporting/core/extras/agent_extras/rag_user_extras.py +53 -0
  55. waldiez/exporting/core/extras/agent_extras/reasoning_extras.py +68 -0
  56. waldiez/exporting/core/extras/agent_extras/standard_extras.py +263 -0
  57. waldiez/exporting/core/extras/base.py +241 -0
  58. waldiez/exporting/core/extras/chat_extras.py +118 -0
  59. waldiez/exporting/core/extras/flow_extras.py +70 -0
  60. waldiez/exporting/core/extras/model_extras.py +73 -0
  61. waldiez/exporting/core/extras/path_resolver.py +93 -0
  62. waldiez/exporting/core/extras/serializer.py +138 -0
  63. waldiez/exporting/core/extras/tool_extras.py +82 -0
  64. waldiez/exporting/core/protocols.py +259 -0
  65. waldiez/exporting/core/result.py +705 -0
  66. waldiez/exporting/core/types.py +329 -0
  67. waldiez/exporting/core/utils/__init__.py +11 -0
  68. waldiez/exporting/core/utils/comment.py +33 -0
  69. waldiez/exporting/core/utils/llm_config.py +117 -0
  70. waldiez/exporting/core/validation.py +96 -0
  71. waldiez/exporting/flow/__init__.py +6 -2
  72. waldiez/exporting/flow/execution_generator.py +193 -0
  73. waldiez/exporting/flow/exporter.py +107 -0
  74. waldiez/exporting/flow/factory.py +94 -0
  75. waldiez/exporting/flow/file_generator.py +214 -0
  76. waldiez/exporting/flow/merger.py +387 -0
  77. waldiez/exporting/flow/orchestrator.py +411 -0
  78. waldiez/exporting/flow/utils/__init__.py +9 -36
  79. waldiez/exporting/flow/utils/common.py +206 -0
  80. waldiez/exporting/flow/utils/importing.py +373 -0
  81. waldiez/exporting/flow/utils/linting.py +200 -0
  82. waldiez/exporting/flow/utils/{logging_utils.py → logging.py} +23 -9
  83. waldiez/exporting/models/__init__.py +3 -1
  84. waldiez/exporting/models/exporter.py +233 -0
  85. waldiez/exporting/models/factory.py +66 -0
  86. waldiez/exporting/models/processor.py +139 -0
  87. waldiez/exporting/tools/__init__.py +11 -0
  88. waldiez/exporting/tools/exporter.py +207 -0
  89. waldiez/exporting/tools/factory.py +57 -0
  90. waldiez/exporting/tools/processor.py +248 -0
  91. waldiez/exporting/tools/registration.py +133 -0
  92. waldiez/io/__init__.py +128 -0
  93. waldiez/io/_ws.py +199 -0
  94. waldiez/io/models/__init__.py +60 -0
  95. waldiez/io/models/base.py +66 -0
  96. waldiez/io/models/constants.py +78 -0
  97. waldiez/io/models/content/__init__.py +23 -0
  98. waldiez/io/models/content/audio.py +43 -0
  99. waldiez/io/models/content/base.py +45 -0
  100. waldiez/io/models/content/file.py +43 -0
  101. waldiez/io/models/content/image.py +96 -0
  102. waldiez/io/models/content/text.py +37 -0
  103. waldiez/io/models/content/video.py +43 -0
  104. waldiez/io/models/user_input.py +269 -0
  105. waldiez/io/models/user_response.py +215 -0
  106. waldiez/io/mqtt.py +681 -0
  107. waldiez/io/redis.py +782 -0
  108. waldiez/io/structured.py +439 -0
  109. waldiez/io/utils.py +184 -0
  110. waldiez/io/ws.py +298 -0
  111. waldiez/logger.py +481 -0
  112. waldiez/models/__init__.py +108 -51
  113. waldiez/models/agents/__init__.py +34 -70
  114. waldiez/models/agents/agent/__init__.py +10 -4
  115. waldiez/models/agents/agent/agent.py +466 -65
  116. waldiez/models/agents/agent/agent_data.py +119 -47
  117. waldiez/models/agents/agent/agent_type.py +13 -2
  118. waldiez/models/agents/agent/code_execution.py +12 -12
  119. waldiez/models/agents/agent/human_input_mode.py +8 -0
  120. waldiez/models/agents/agent/{linked_skill.py → linked_tool.py} +7 -7
  121. waldiez/models/agents/agent/nested_chat.py +35 -7
  122. waldiez/models/agents/agent/termination_message.py +30 -22
  123. waldiez/models/agents/{swarm_agent → agent}/update_system_message.py +22 -22
  124. waldiez/models/agents/agents.py +58 -63
  125. waldiez/models/agents/assistant/assistant.py +4 -4
  126. waldiez/models/agents/assistant/assistant_data.py +13 -1
  127. waldiez/models/agents/{captain_agent → captain}/captain_agent.py +5 -5
  128. waldiez/models/agents/{captain_agent → captain}/captain_agent_data.py +5 -5
  129. waldiez/models/agents/extra_requirements.py +11 -16
  130. waldiez/models/agents/group_manager/group_manager.py +103 -13
  131. waldiez/models/agents/group_manager/group_manager_data.py +36 -14
  132. waldiez/models/agents/group_manager/speakers.py +77 -24
  133. waldiez/models/agents/{rag_user → rag_user_proxy}/__init__.py +16 -16
  134. waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +64 -0
  135. waldiez/models/agents/{rag_user/rag_user_data.py → rag_user_proxy/rag_user_proxy_data.py} +6 -5
  136. waldiez/models/agents/{rag_user → rag_user_proxy}/retrieve_config.py +182 -114
  137. waldiez/models/agents/{rag_user → rag_user_proxy}/vector_db_config.py +13 -13
  138. waldiez/models/agents/reasoning/reasoning_agent.py +6 -6
  139. waldiez/models/agents/reasoning/reasoning_agent_data.py +110 -63
  140. waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +38 -10
  141. waldiez/models/agents/user_proxy/user_proxy.py +11 -7
  142. waldiez/models/agents/user_proxy/user_proxy_data.py +2 -2
  143. waldiez/models/chat/__init__.py +2 -1
  144. waldiez/models/chat/chat.py +166 -87
  145. waldiez/models/chat/chat_data.py +99 -136
  146. waldiez/models/chat/chat_message.py +33 -23
  147. waldiez/models/chat/chat_nested.py +31 -30
  148. waldiez/models/chat/chat_summary.py +10 -8
  149. waldiez/models/common/__init__.py +52 -2
  150. waldiez/models/common/ag2_version.py +1 -1
  151. waldiez/models/common/base.py +38 -7
  152. waldiez/models/common/dict_utils.py +42 -17
  153. waldiez/models/common/handoff.py +459 -0
  154. waldiez/models/common/id_generator.py +19 -0
  155. waldiez/models/common/method_utils.py +130 -68
  156. waldiez/{exporting/base/utils → models/common}/naming.py +38 -61
  157. waldiez/models/common/waldiez_version.py +37 -0
  158. waldiez/models/flow/__init__.py +9 -2
  159. waldiez/models/flow/connection.py +18 -0
  160. waldiez/models/flow/flow.py +311 -215
  161. waldiez/models/flow/flow_data.py +207 -40
  162. waldiez/models/flow/info.py +85 -0
  163. waldiez/models/flow/naming.py +131 -0
  164. waldiez/models/model/__init__.py +7 -1
  165. waldiez/models/model/extra_requirements.py +3 -12
  166. waldiez/models/model/model.py +76 -21
  167. waldiez/models/model/model_data.py +108 -20
  168. waldiez/models/tool/__init__.py +16 -0
  169. waldiez/models/tool/extra_requirements.py +36 -0
  170. waldiez/models/{skill/skill.py → tool/tool.py} +88 -88
  171. waldiez/models/tool/tool_data.py +51 -0
  172. waldiez/models/tool/tool_type.py +8 -0
  173. waldiez/models/waldiez.py +97 -80
  174. waldiez/runner.py +115 -61
  175. waldiez/running/__init__.py +13 -7
  176. waldiez/running/environment.py +49 -68
  177. waldiez/running/gen_seq_diagram.py +16 -14
  178. waldiez/running/post_run.py +119 -0
  179. waldiez/running/pre_run.py +149 -0
  180. waldiez/running/util.py +134 -0
  181. waldiez/utils/__init__.py +2 -4
  182. waldiez/utils/cli_extras/jupyter.py +5 -3
  183. waldiez/utils/cli_extras/runner.py +6 -4
  184. waldiez/utils/cli_extras/studio.py +6 -4
  185. waldiez/utils/conflict_checker.py +15 -9
  186. waldiez/utils/flaml_warnings.py +5 -5
  187. waldiez/utils/version.py +47 -0
  188. {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/METADATA +235 -91
  189. waldiez-0.4.9.dist-info/RECORD +203 -0
  190. waldiez/exporting/agent/agent_exporter.py +0 -297
  191. waldiez/exporting/agent/utils/__init__.py +0 -23
  192. waldiez/exporting/agent/utils/captain_agent.py +0 -263
  193. waldiez/exporting/agent/utils/code_execution.py +0 -65
  194. waldiez/exporting/agent/utils/group_manager.py +0 -220
  195. waldiez/exporting/agent/utils/rag_user/__init__.py +0 -7
  196. waldiez/exporting/agent/utils/rag_user/rag_user.py +0 -209
  197. waldiez/exporting/agent/utils/reasoning.py +0 -36
  198. waldiez/exporting/agent/utils/swarm_agent.py +0 -469
  199. waldiez/exporting/agent/utils/teachability.py +0 -41
  200. waldiez/exporting/agent/utils/termination_message.py +0 -44
  201. waldiez/exporting/base/__init__.py +0 -25
  202. waldiez/exporting/base/agent_position.py +0 -75
  203. waldiez/exporting/base/base_exporter.py +0 -118
  204. waldiez/exporting/base/export_position.py +0 -48
  205. waldiez/exporting/base/import_position.py +0 -23
  206. waldiez/exporting/base/mixin.py +0 -137
  207. waldiez/exporting/base/utils/__init__.py +0 -18
  208. waldiez/exporting/base/utils/comments.py +0 -96
  209. waldiez/exporting/base/utils/path_check.py +0 -68
  210. waldiez/exporting/base/utils/to_string.py +0 -84
  211. waldiez/exporting/chats/chats_exporter.py +0 -240
  212. waldiez/exporting/chats/utils/swarm.py +0 -210
  213. waldiez/exporting/flow/flow_exporter.py +0 -528
  214. waldiez/exporting/flow/utils/agent_utils.py +0 -204
  215. waldiez/exporting/flow/utils/chat_utils.py +0 -71
  216. waldiez/exporting/flow/utils/def_main.py +0 -77
  217. waldiez/exporting/flow/utils/flow_content.py +0 -202
  218. waldiez/exporting/flow/utils/flow_names.py +0 -116
  219. waldiez/exporting/flow/utils/importing_utils.py +0 -227
  220. waldiez/exporting/models/models_exporter.py +0 -199
  221. waldiez/exporting/models/utils.py +0 -174
  222. waldiez/exporting/skills/__init__.py +0 -9
  223. waldiez/exporting/skills/skills_exporter.py +0 -176
  224. waldiez/exporting/skills/utils.py +0 -369
  225. waldiez/models/agents/agent/teachability.py +0 -70
  226. waldiez/models/agents/rag_user/rag_user.py +0 -60
  227. waldiez/models/agents/swarm_agent/__init__.py +0 -50
  228. waldiez/models/agents/swarm_agent/after_work.py +0 -179
  229. waldiez/models/agents/swarm_agent/on_condition.py +0 -105
  230. waldiez/models/agents/swarm_agent/on_condition_available.py +0 -142
  231. waldiez/models/agents/swarm_agent/on_condition_target.py +0 -40
  232. waldiez/models/agents/swarm_agent/swarm_agent.py +0 -107
  233. waldiez/models/agents/swarm_agent/swarm_agent_data.py +0 -124
  234. waldiez/models/flow/utils.py +0 -232
  235. waldiez/models/skill/__init__.py +0 -16
  236. waldiez/models/skill/extra_requirements.py +0 -36
  237. waldiez/models/skill/skill_data.py +0 -53
  238. waldiez/models/skill/skill_type.py +0 -8
  239. waldiez/running/running.py +0 -369
  240. waldiez/utils/pysqlite3_checker.py +0 -308
  241. waldiez/utils/rdps_checker.py +0 -122
  242. waldiez-0.4.7.dist-info/RECORD +0 -149
  243. /waldiez/models/agents/{captain_agent → captain}/__init__.py +0 -0
  244. /waldiez/models/agents/{captain_agent → captain}/captain_agent_lib_entry.py +0 -0
  245. {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/WHEEL +0 -0
  246. {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/entry_points.txt +0 -0
  247. {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/licenses/LICENSE +0 -0
  248. {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/licenses/NOTICE.md +0 -0
@@ -0,0 +1,329 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+
4
+ """Core dataclasses for the exporting system."""
5
+
6
+ from dataclasses import dataclass, field, fields
7
+ from pathlib import Path
8
+ from typing import Any, Optional, TypeVar
9
+
10
+ from .enums import (
11
+ ImportPosition,
12
+ )
13
+
14
+ # Generic type for extras
15
+ Extras = TypeVar("Extras")
16
+
17
+
18
+ # Sentinel for exporters that do not require extras
19
+ # pylint: disable=too-few-public-methods
20
+ class _NoExtrasType:
21
+ """Sentinel for exporters that do not require extras."""
22
+
23
+ def __repr__(self) -> str:
24
+ """Get the string representation of NoExtras."""
25
+ return "<NoExtras>"
26
+
27
+
28
+ NoExtras = _NoExtrasType()
29
+
30
+
31
+ # Core Data Structures
32
+ @dataclass
33
+ class ImportStatement:
34
+ """Represents an import statement with its position."""
35
+
36
+ statement: str
37
+ position: ImportPosition = ImportPosition.THIRD_PARTY
38
+ metadata: Optional[dict[str, Any]] = None
39
+
40
+ def __hash__(self) -> int:
41
+ """Hash based on the import statement.
42
+
43
+ Returns
44
+ -------
45
+ int
46
+ The hash value of the import statement.
47
+ """
48
+ return hash(self.statement)
49
+
50
+ def __eq__(self, other: object) -> bool:
51
+ """Check equality based on the import statement.
52
+
53
+ Parameters
54
+ ----------
55
+ other : object
56
+ The object to compare against.
57
+
58
+ Returns
59
+ -------
60
+ bool
61
+ True if the other object is an
62
+ ImportStatement with the same statement.
63
+ """
64
+ if isinstance(other, ImportStatement):
65
+ return self.statement == other.statement
66
+ return False
67
+
68
+ def __lt__(self, other: "ImportStatement") -> bool:
69
+ """Enable sorting by position then statement.
70
+
71
+ Parameters
72
+ ----------
73
+ other : ImportStatement
74
+ The other import statement to compare against.
75
+
76
+ Returns
77
+ -------
78
+ bool
79
+ True if this import statement should come before the other.
80
+ """
81
+ if self.position.value != other.position.value:
82
+ return self.position.value < other.position.value
83
+ return self.statement < other.statement
84
+
85
+
86
+ @dataclass
87
+ class EnvironmentVariable:
88
+ """Environment variable with metadata."""
89
+
90
+ name: str
91
+ value: str
92
+ description: Optional[str] = None
93
+ required: bool = True
94
+
95
+ def __post_init__(self) -> None:
96
+ """Validate environment variable."""
97
+ if not self.name or not self.value:
98
+ raise ValueError("Environment variable name and value are required")
99
+
100
+ def __hash__(self) -> int:
101
+ """Hash based on the environment variable name.
102
+
103
+ Returns
104
+ -------
105
+ int
106
+ The hash value of the environment variable name.
107
+ """
108
+ return hash(self.name)
109
+
110
+ def __eq__(self, other: object) -> bool:
111
+ """Check equality based on the environment variable name.
112
+
113
+ Parameters
114
+ ----------
115
+ other : object
116
+ The object to compare against.
117
+
118
+ Returns
119
+ -------
120
+ bool
121
+ True if the other object is an
122
+ EnvironmentVariable with the same name.
123
+ """
124
+ if isinstance(other, EnvironmentVariable):
125
+ return self.name == other.name
126
+ return False
127
+
128
+ def as_tuple(self) -> tuple[str, str]:
129
+ """Get the environment variable as a tuple.
130
+
131
+ Returns
132
+ -------
133
+ tuple[str, str]
134
+ The environment variable as a tuple.
135
+ """
136
+ return (self.name, self.value)
137
+
138
+
139
+ # Instance Argument
140
+ @dataclass
141
+ class InstanceArgument:
142
+ """Represents an instance argument for an agent, model or tool."""
143
+
144
+ instance_id: str
145
+ name: str
146
+ value: Any
147
+ tabs: int = 0
148
+ tabs_length: int = 4 # Assuming 4 spaces per tab
149
+ with_new_line_before: bool = False
150
+ with_new_line_after: bool = False
151
+ with_new_line_if_empty: bool = False
152
+ skip_if_empty_string: bool = True
153
+ comment: Optional[str] = None
154
+
155
+ def has_content(self) -> bool:
156
+ """Check if the instance argument has content.
157
+
158
+ Returns
159
+ -------
160
+ bool
161
+ True if the instance argument has content, otherwise False.
162
+ """
163
+ if self.skip_if_empty_string and isinstance(self.value, str):
164
+ return bool(self.value.strip())
165
+ return self.value is not None and self.value != ""
166
+
167
+ def get_content(
168
+ self,
169
+ prepend_new_line: bool = False,
170
+ append_new_line: bool = False,
171
+ ) -> str:
172
+ """Get the content representation of the instance argument.
173
+
174
+ Parameters
175
+ ----------
176
+ prepend_new_line : bool, optional
177
+ Whether to prepend a new line before the content,
178
+ by default False.
179
+ append_new_line : bool, optional
180
+ Whether to append a new line at the end of the content,
181
+ by default False.
182
+
183
+ Returns
184
+ -------
185
+ str
186
+ The formatted content string for the instance argument.
187
+ """
188
+ if (
189
+ self.skip_if_empty_string
190
+ and isinstance(self.value, str)
191
+ and not self.value.strip()
192
+ ):
193
+ return "\n" if self.with_new_line_if_empty else ""
194
+ space = " " * (self.tabs * self.tabs_length)
195
+ content = f"{space}{self.name}={self.value}," + (
196
+ f" # {self.comment}" if self.comment else ""
197
+ )
198
+ if self.with_new_line_before or prepend_new_line:
199
+ content = "\n" + content
200
+ if self.with_new_line_after or append_new_line:
201
+ content += "\n"
202
+ return content
203
+
204
+ def __hash__(self) -> int:
205
+ """Hash based on the instance ID and name.
206
+
207
+ Returns
208
+ -------
209
+ int
210
+ The hash value of the instance argument.
211
+ """
212
+ return hash((self.instance_id, self.name))
213
+
214
+ def __str__(self) -> str:
215
+ """Get the string representation of the instance argument.
216
+
217
+ Returns
218
+ -------
219
+ str
220
+ The string representation of the instance argument.
221
+ """
222
+ return self.get_content()
223
+
224
+ def __repr__(self) -> str:
225
+ """Get the string representation of the instance argument.
226
+
227
+ Returns
228
+ -------
229
+ str
230
+ The string representation of the instance argument.
231
+ """
232
+ return self.get_content()
233
+
234
+
235
+ # Export Configuration
236
+ @dataclass
237
+ class ExportConfig:
238
+ """Configuration for export operations.
239
+
240
+ Attributes
241
+ ----------
242
+ output_extension : str
243
+ The file extension for the exported content.
244
+ is_async : bool
245
+ Whether the exported content should be asynchronous.
246
+ """
247
+
248
+ name: str = "Waldiez Flow"
249
+ description: str = (
250
+ "Make AG2 Agents Collaborate: Drag, Drop, and Orchestrate with Waldiez"
251
+ )
252
+ requirements: list[str] = field(default_factory=list[str])
253
+ tags: list[str] = field(default_factory=list[str])
254
+ output_extension: str = "py"
255
+ is_async: bool = False
256
+ output_directory: Optional[str | Path] = None
257
+ cache_seed: Optional[int] = None
258
+
259
+ @property
260
+ def for_notebook(self) -> bool:
261
+ """Check if the export is intended for a notebook environment.
262
+
263
+ Returns
264
+ -------
265
+ bool
266
+ True if the output extension is 'ipynb', otherwise False.
267
+ """
268
+ return self.output_extension == "ipynb"
269
+
270
+ def __post_init__(self) -> None:
271
+ """Post-initialization validation."""
272
+ if not self.name:
273
+ raise ValueError("ExportConfig name cannot be empty")
274
+ if not self.description:
275
+ raise ValueError("ExportConfig description cannot be empty")
276
+ if not self.output_extension:
277
+ raise ValueError("ExportConfig output_extension cannot be empty")
278
+
279
+ @classmethod
280
+ def create(cls, **kwargs: Any) -> "ExportConfig":
281
+ """Create a new ExportConfig instance with the provided values.
282
+
283
+ Parameters
284
+ ----------
285
+ **kwargs : Any
286
+ Keyword arguments to initialize the ExportConfig.
287
+
288
+ Returns
289
+ -------
290
+ ExportConfig
291
+ A new instance of ExportConfig.
292
+ """
293
+ valid_fields = {f.name for f in fields(cls)}
294
+ output_extension = kwargs.pop("output_extension", "py")
295
+ for_notebook = kwargs.pop("for_notebook", output_extension == "ipynb")
296
+ if for_notebook is True:
297
+ output_extension = "ipynb"
298
+ cache_seed = kwargs.pop("cache_seed", None)
299
+ if cache_seed is not None and not isinstance(cache_seed, int):
300
+ cache_seed = None
301
+ return cls(
302
+ cache_seed=cache_seed,
303
+ output_extension=output_extension,
304
+ **{k: v for k, v in kwargs.items() if k in valid_fields},
305
+ )
306
+
307
+ def update(self, **kwargs: Any) -> None:
308
+ """Update the export configuration with new values.
309
+
310
+ Parameters
311
+ ----------
312
+ **kwargs : Any
313
+ Keyword arguments to update the configuration.
314
+
315
+ Raises
316
+ ------
317
+ ValueError
318
+ If an invalid configuration key is provided.
319
+ """
320
+ valid_fields = {f.name for f in fields(self)}
321
+ for key, value in kwargs.items():
322
+ if key in valid_fields:
323
+ setattr(self, key, value)
324
+ if (
325
+ "for_notebook" in kwargs
326
+ and isinstance(kwargs["for_notebook"], bool)
327
+ and "output_extension" not in kwargs
328
+ ): # pragma: no cover
329
+ self.output_extension = "ipynb" if kwargs["for_notebook"] else "py"
@@ -0,0 +1,11 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Utility functions for Waldiez exporting."""
4
+
5
+ from .comment import get_comment
6
+ from .llm_config import get_agent_llm_config_arg
7
+
8
+ __all__ = [
9
+ "get_comment",
10
+ "get_agent_llm_config_arg",
11
+ ]
@@ -0,0 +1,33 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Get comment string for scripts or notebooks."""
4
+
5
+
6
+ def get_comment(
7
+ comment: str,
8
+ for_notebook: bool = False,
9
+ md_headings: int = 3,
10
+ ) -> str:
11
+ """Get a comment for the script or notebook.
12
+
13
+ Parameters
14
+ ----------
15
+ comment : str
16
+ The comment to add.
17
+ for_notebook : bool, optional
18
+ Whether the comment is for a notebook, by default False
19
+ md_headings : int, optional
20
+ The number of markdown headings to use (if for_notebook is True),
21
+ by default 2
22
+
23
+ Returns
24
+ -------
25
+ str
26
+ The formatted comment.
27
+ """
28
+ if for_notebook:
29
+ # For notebooks, we use markdown headings
30
+ heading = "#" + "#" * md_headings
31
+ return f"# %% [markdown]\n{heading} {comment}\n# %% \n"
32
+ # For scripts, we use a simple comment
33
+ return f"# {comment}\n"
@@ -0,0 +1,117 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """LLM config argument utility functions for Waldiez agents."""
4
+
5
+ from waldiez.models import WaldiezAgent, WaldiezModel
6
+
7
+
8
+ def get_agent_llm_config_arg(
9
+ agent: WaldiezAgent,
10
+ all_models: list[WaldiezModel],
11
+ model_names: dict[str, str],
12
+ cache_seed: int | None,
13
+ as_dict: bool = False,
14
+ tabs: int = 1,
15
+ ) -> str:
16
+ """Get the string representation of the agent's llm config argument.
17
+
18
+ Parameters
19
+ ----------
20
+ agent : WaldiezAgent
21
+ The agent.
22
+ all_models : list[WaldiezModel]
23
+ All the models in the flow.
24
+ model_names : dict[str, str]
25
+ A mapping of model ids to model names.
26
+ cache_seed : Optional[int]
27
+ The cache seed.
28
+ as_dict : bool, optional
29
+ Whether to return the argument as a dictionary, by default False.
30
+ tabs : int, optional
31
+ The number of tabs for indentation, by default 1.
32
+
33
+ Returns
34
+ -------
35
+ str
36
+ The agent's llm config argument to use.
37
+ """
38
+ if as_dict is False:
39
+ return _get_agent_llm_config_arg_as_arg(
40
+ agent,
41
+ all_models,
42
+ model_names,
43
+ cache_seed,
44
+ tabs=tabs,
45
+ )
46
+ return _get_agent_llm_config_arg_as_dict(
47
+ agent,
48
+ all_models,
49
+ model_names,
50
+ cache_seed,
51
+ tabs=tabs + 1,
52
+ )
53
+
54
+
55
+ def _get_agent_llm_config_arg_as_arg(
56
+ agent: WaldiezAgent,
57
+ all_models: list[WaldiezModel],
58
+ model_names: dict[str, str],
59
+ cache_seed: int | None,
60
+ tabs: int = 1,
61
+ tab_leng: int = 4,
62
+ ) -> str:
63
+ tab = " " * tab_leng * tabs if tabs > 0 else ""
64
+ # tab = " " * tabs if tabs > 0 else ""
65
+ if not agent.data.model_ids:
66
+ return f"{tab}llm_config=False, # pyright: ignore" + "\n"
67
+ content = f"{tab}llm_config=autogen.LLMConfig(" + "\n"
68
+ content += f"{tab} config_list=["
69
+ got_at_least_one_model = False
70
+ temperature: float | None = None
71
+ for model_id in agent.data.model_ids:
72
+ model = next((m for m in all_models if m.id == model_id), None)
73
+ if model is not None:
74
+ temperature = model.data.temperature
75
+ model_name = model_names[model_id]
76
+ content += "\n" + f"{tab} {model_name}_llm_config,"
77
+ got_at_least_one_model = True
78
+ if not got_at_least_one_model: # pragma: no cover
79
+ return f"{tab}llm_config=False, # pyright: ignore" + "\n"
80
+ content += "\n" + f"{tab} ]," + "\n"
81
+ content += f"{tab} cache_seed={cache_seed}," + "\n"
82
+ if temperature is not None:
83
+ content += f"{tab} temperature={temperature}," + "\n"
84
+ content += tab + "),\n"
85
+ return content
86
+
87
+
88
+ def _get_agent_llm_config_arg_as_dict(
89
+ agent: WaldiezAgent,
90
+ all_models: list[WaldiezModel],
91
+ model_names: dict[str, str],
92
+ cache_seed: int | None,
93
+ tabs: int = 1,
94
+ tab_leng: int = 4,
95
+ ) -> str:
96
+ tab = " " * tab_leng * tabs if tabs > 0 else ""
97
+ if not agent.data.model_ids:
98
+ return f'{tab}"llm_config": False' + "\n"
99
+ content = f'{tab}"llm_config": autogen.LLMConfig(' + "\n"
100
+ content += f"{tab} config_list=["
101
+ got_at_least_one_model = False
102
+ temperature: float | None = None
103
+ for model_id in agent.data.model_ids:
104
+ model = next((m for m in all_models if m.id == model_id), None)
105
+ if model is not None: # pragma: no branch
106
+ temperature = model.data.temperature
107
+ model_name = model_names[model_id]
108
+ content += "\n" + f"{tab} {model_name}_llm_config,"
109
+ got_at_least_one_model = True
110
+ if not got_at_least_one_model: # pragma: no cover
111
+ return f'{tab}"llm_config": False' + "\n"
112
+ content += "\n" + f"{tab} ]," + "\n"
113
+ content += f"{tab} cache_seed={cache_seed}," + "\n"
114
+ if temperature is not None:
115
+ content += f"{tab} temperature={temperature}," + "\n"
116
+ content += tab + "),\n"
117
+ return content
@@ -0,0 +1,96 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Validation types and results for Waldiez exporting core."""
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Optional
7
+
8
+
9
+ # Validation Types
10
+ @dataclass
11
+ class ValidationError:
12
+ """Represents a validation error."""
13
+
14
+ message: str
15
+ severity: str = "error" # error, warning, info
16
+ location: Optional[str] = None
17
+ suggestion: Optional[str] = None
18
+
19
+
20
+ @dataclass
21
+ class ValidationResult:
22
+ """Result of validation operations."""
23
+
24
+ is_valid: bool
25
+ errors: list[ValidationError] = field(
26
+ default_factory=list[ValidationError],
27
+ )
28
+ warnings: list[ValidationError] = field(
29
+ default_factory=list[ValidationError],
30
+ )
31
+
32
+ def add_error(
33
+ self,
34
+ message: str,
35
+ location: Optional[str] = None,
36
+ suggestion: Optional[str] = None,
37
+ ) -> None:
38
+ """Add a validation error.
39
+
40
+ Parameters
41
+ ----------
42
+ message : str
43
+ The error message to add.
44
+ location : Optional[str], optional
45
+ The location in the code where the error occurred, by default None
46
+ suggestion : Optional[str], optional
47
+ A suggestion for fixing the error, by default None
48
+ """
49
+ self.errors.append(
50
+ ValidationError(message, "error", location, suggestion)
51
+ )
52
+ self.is_valid = False
53
+
54
+ def add_warning(self, message: str, location: Optional[str] = None) -> None:
55
+ """Add a validation warning.
56
+
57
+ Parameters
58
+ ----------
59
+ message : str
60
+ The warning message to add.
61
+ location : Optional[str], optional
62
+ The location in the code where the warning occurred, by default None
63
+ """
64
+ self.warnings.append(ValidationError(message, "warning", location))
65
+
66
+ def has_errors(self) -> bool:
67
+ """Check if there are any errors.
68
+
69
+ Returns
70
+ -------
71
+ bool
72
+ True if there are validation errors, otherwise False.
73
+ """
74
+ return len(self.errors) > 0
75
+
76
+ def has_warnings(self) -> bool:
77
+ """Check if there are any warnings.
78
+
79
+ Returns
80
+ -------
81
+ bool
82
+ True if there are validation warnings, otherwise False.
83
+ """
84
+ return len(self.warnings) > 0
85
+
86
+ def merge(self, other: "ValidationResult") -> None:
87
+ """Merge another ValidationResult into this one.
88
+
89
+ Parameters
90
+ ----------
91
+ other : ValidationResult
92
+ The other validation result to merge.
93
+ """
94
+ self.is_valid = self.is_valid and other.is_valid
95
+ self.errors.extend(other.errors)
96
+ self.warnings.extend(other.warnings)
@@ -2,6 +2,10 @@
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
3
  """Flow exporter."""
4
4
 
5
- from .flow_exporter import FlowExporter
5
+ from .exporter import FlowExporter
6
+ from .factory import create_flow_exporter
6
7
 
7
- __all__ = ["FlowExporter"]
8
+ __all__ = [
9
+ "FlowExporter",
10
+ "create_flow_exporter",
11
+ ]