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,53 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """RAG related extas."""
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+ from waldiez.exporting.core.result import ExportResult
8
+
9
+ from ...enums import AgentPosition, ExportPosition
10
+ from .standard_extras import StandardExtras
11
+
12
+
13
+ @dataclass
14
+ class RAGUserExtras(StandardExtras):
15
+ """RAG configuration."""
16
+
17
+ before_content: str = ""
18
+ imports: set[str] = field(default_factory=set[str])
19
+
20
+ def _contribute_specific_content(self, result: ExportResult) -> None:
21
+ """Contribute RAG specific content to the export result."""
22
+ if self.extra_args:
23
+ for arg in self.extra_args:
24
+ result.add_instance_argument(
25
+ name=arg.name,
26
+ value=arg.value,
27
+ instance_id=arg.instance_id,
28
+ tabs=arg.tabs,
29
+ )
30
+ if self.imports:
31
+ for imp in self.imports:
32
+ result.add_import(imp)
33
+ if self.before_content.strip():
34
+ result.add_content(
35
+ self.before_content,
36
+ position=ExportPosition.AGENTS,
37
+ agent_position=AgentPosition.BEFORE,
38
+ agent_id=self.instance_id,
39
+ )
40
+
41
+ def has_specific_content(self) -> bool:
42
+ """Check if there's any RAG content.
43
+
44
+ Returns
45
+ -------
46
+ bool
47
+ True if there's any RAG configuration.
48
+ """
49
+ if not super().has_specific_content():
50
+ return bool(
51
+ self.extra_args or self.before_content.strip() or self.imports
52
+ )
53
+ return True
@@ -0,0 +1,68 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-few-public-methods
4
+ """Resoning agent extras module."""
5
+
6
+ from dataclasses import dataclass
7
+
8
+ from waldiez.exporting.core.result import ExportResult
9
+
10
+ from ...enums import AgentPosition, ExportPosition
11
+ from .standard_extras import StandardExtras
12
+
13
+
14
+ @dataclass
15
+ class ReasoningExtras(StandardExtras):
16
+ """Extras for reasoning agents."""
17
+
18
+ def _contribute_specific_content(self, result: ExportResult) -> None:
19
+ """Contribute reasoning specific content to the export result.
20
+
21
+ Parameters
22
+ ----------
23
+ result : ExportResult
24
+ The export result to contribute to.
25
+ """
26
+ super()._contribute_specific_content(result)
27
+ if self.extra_args:
28
+ for arg in self.extra_args:
29
+ result.add_instance_argument(
30
+ name=arg.name,
31
+ value=arg.value,
32
+ instance_id=arg.instance_id,
33
+ tabs=arg.tabs,
34
+ )
35
+ if self.extra_imports:
36
+ for imp in self.extra_imports:
37
+ result.add_import(imp.statement, imp.position)
38
+ if self.before_agent.strip():
39
+ result.add_content(
40
+ self.before_agent,
41
+ position=ExportPosition.AGENTS,
42
+ agent_position=AgentPosition.BEFORE,
43
+ agent_id=self.instance_id,
44
+ )
45
+ if self.after_agent.strip():
46
+ result.add_content(
47
+ self.after_agent,
48
+ position=ExportPosition.AGENTS,
49
+ agent_position=AgentPosition.AFTER,
50
+ agent_id=self.instance_id,
51
+ )
52
+
53
+ def has_specific_content(self) -> bool:
54
+ """Check for reasoning specific content.
55
+
56
+ Returns
57
+ -------
58
+ bool
59
+ True if there's reasoning specific content.
60
+ """
61
+ if not super().has_specific_content():
62
+ return bool(
63
+ self.extra_args
64
+ or self.extra_imports
65
+ or self.before_agent.strip()
66
+ or self.after_agent.strip()
67
+ )
68
+ return True
@@ -0,0 +1,263 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-few-public-methods,no-self-use
4
+ """Standard agent extras module."""
5
+
6
+ from dataclasses import dataclass
7
+ from typing import Optional
8
+
9
+ from ...enums import AgentPosition, ExportPosition
10
+ from ...result import ExportResult
11
+ from ...types import ImportStatement, InstanceArgument
12
+ from ..base import BaseExtras
13
+
14
+
15
+ @dataclass
16
+ class TerminationConfig:
17
+ """Termination configuration."""
18
+
19
+ termination_arg: str = "None"
20
+ before_content: str = ""
21
+
22
+ def has_content(self) -> bool:
23
+ """Check if there's any termination content.
24
+
25
+ Returns
26
+ -------
27
+ bool
28
+ True if there's any termination configuration.
29
+ """
30
+ return bool(self.before_content.strip())
31
+
32
+
33
+ @dataclass
34
+ class CodeExecutionConfig:
35
+ """Code execution configuration."""
36
+
37
+ executor_content: str = ""
38
+ executor_argument: str = "False"
39
+ executor_import: ImportStatement | None = None
40
+
41
+ def has_content(self) -> bool:
42
+ """Check if there's any code execution content.
43
+
44
+ Returns
45
+ -------
46
+ bool
47
+ True if there's any code execution configuration.
48
+ """
49
+ return bool(
50
+ self.executor_content.strip()
51
+ or self.executor_argument != "False"
52
+ or self.executor_import
53
+ )
54
+
55
+
56
+ @dataclass
57
+ class SystemMessageConfig:
58
+ """System message configuration."""
59
+
60
+ # in case we support later custom methods for system messages
61
+ before_agent_conent: str = ""
62
+ system_message_arg: str = ""
63
+
64
+ def has_content(self) -> bool:
65
+ """Check if there's any system message content.
66
+
67
+ Returns
68
+ -------
69
+ bool
70
+ True if there's any system message configuration.
71
+ """
72
+ return bool(str(self.system_message_arg).strip())
73
+
74
+
75
+ @dataclass
76
+ class StandardExtras(BaseExtras):
77
+ """Extras for standard agents (UserProxy, Assistant, etc.)."""
78
+
79
+ code_execution_config: Optional[CodeExecutionConfig] = None
80
+ termination_config: Optional[TerminationConfig] = None
81
+ system_message_config: Optional[SystemMessageConfig] = None
82
+
83
+ def set_code_execution(self, config: CodeExecutionConfig) -> None:
84
+ """Set code execution configuration.
85
+
86
+ Parameters
87
+ ----------
88
+ config : CodeExecutionConfig
89
+ The code execution configuration.
90
+ """
91
+ self.code_execution_config = config
92
+ if config.executor_import:
93
+ self.add_import(config.executor_import)
94
+ # we either add the executor content here or
95
+ # in _contribute_specific_content below
96
+ if config.executor_content:
97
+ self.append_before_agent(config.executor_content)
98
+
99
+ def set_termination_config(self, config: TerminationConfig) -> None:
100
+ """Set termination configuration.
101
+
102
+ Parameters
103
+ ----------
104
+ config : TerminationConfig
105
+ The termination configuration.
106
+ """
107
+ self.termination_config = config
108
+ if config.before_content:
109
+ self.append_before_agent(config.before_content)
110
+
111
+ def set_system_message_config(self, config: SystemMessageConfig) -> None:
112
+ """Set system message configuration.
113
+
114
+ Parameters
115
+ ----------
116
+ config : SystemMessageConfig
117
+ The system message configuration.
118
+ """
119
+ self.system_message_config = config
120
+ if config.before_agent_conent:
121
+ self.append_before_agent(config.before_agent_conent)
122
+
123
+ def get_code_execution_arg(self) -> InstanceArgument:
124
+ """Get the code execution argument string.
125
+
126
+ Returns
127
+ -------
128
+ InstanceArgument
129
+ The code execution argument.
130
+ """
131
+ if (
132
+ self.code_execution_config
133
+ and self.code_execution_config.executor_argument
134
+ ):
135
+ argunent = self.code_execution_config.executor_argument
136
+ else:
137
+ argunent = "False"
138
+ return InstanceArgument(
139
+ instance_id=self.instance_id,
140
+ name="code_execution_config",
141
+ value=argunent,
142
+ tabs=1,
143
+ )
144
+
145
+ def get_termination_arg(self) -> InstanceArgument:
146
+ """Get the termination argument.
147
+
148
+ Returns
149
+ -------
150
+ InstanceArgument
151
+ The termination argument.
152
+ """
153
+ if self.termination_config and self.termination_config.termination_arg:
154
+ argument = self.termination_config.termination_arg
155
+ else:
156
+ argument = "None"
157
+ comment: str | None = None
158
+ if argument == "None":
159
+ comment = "pyright: ignore"
160
+ return InstanceArgument(
161
+ instance_id=self.instance_id,
162
+ name="is_termination_msg",
163
+ value=argument,
164
+ comment=comment,
165
+ tabs=1,
166
+ )
167
+
168
+ def get_system_message_arg(self) -> InstanceArgument:
169
+ """Get the system message argument.
170
+
171
+ Returns
172
+ -------
173
+ InstanceArgument
174
+ The system message argument.
175
+ """
176
+ if (
177
+ self.system_message_config
178
+ and self.system_message_config.system_message_arg
179
+ ):
180
+ argument = self.system_message_config.system_message_arg
181
+ else:
182
+ argument = ""
183
+ return InstanceArgument(
184
+ instance_id=self.instance_id,
185
+ name="system_message",
186
+ value=argument,
187
+ skip_if_empty_string=True,
188
+ with_new_line_before=True,
189
+ tabs=1,
190
+ )
191
+
192
+ def has_specific_content(self) -> bool:
193
+ """Check for standard agent specific content.
194
+
195
+ Returns
196
+ -------
197
+ bool
198
+ True if there's standard agent specific content.
199
+ """
200
+ return bool(
201
+ self.extra_args
202
+ or (
203
+ self.code_execution_config
204
+ and self.code_execution_config.has_content()
205
+ )
206
+ or (
207
+ self.termination_config
208
+ and self.termination_config.has_content()
209
+ )
210
+ or (
211
+ self.system_message_config
212
+ and self.system_message_config.has_content()
213
+ )
214
+ )
215
+
216
+ def _contribute_specific_content(self, result: ExportResult) -> None:
217
+ """Contribute standard agent specific content.
218
+
219
+ Parameters
220
+ ----------
221
+ result : ExportResult
222
+ The export result to contribute to.
223
+ """
224
+ if self.extra_args:
225
+ result.add_content(
226
+ self.get_extra_args_content(),
227
+ position=ExportPosition.AGENTS,
228
+ agent_position=AgentPosition.AS_ARGUMENT,
229
+ agent_id=self.instance_id,
230
+ )
231
+ # content added above
232
+ # alternatively, we could add it here
233
+ # (but we should pay attention with the order)
234
+ # if (
235
+ # self.code_execution_config
236
+ # and self.code_execution_config.has_content()
237
+ # ):
238
+ # result.add_content(
239
+ # self.code_execution_config.executor_content,
240
+ # position=ExportPosition.AGENTS,
241
+ # agent_position=AgentPosition.BEFORE,
242
+ # order=ContentOrder.EARLY_SETUP,
243
+ # agent_id=self.instance_id,
244
+ # )
245
+ # if self.code_execution_config.executor_import:
246
+ # \statement = self.code_execution_config.executor_import.statement
247
+ # position = self.code_execution_config.executor_import.position
248
+ # result.add_import(
249
+ # statement=statement,
250
+ # position=position,
251
+ # )
252
+ # if self.termination_config and self.termination_config.has_content():
253
+ # result.add_content(
254
+ # self.termination_config.before_content,
255
+ # position=ExportPosition.AGENTS,
256
+ # agent_position=AgentPosition.BEFORE,
257
+ # agent_id=self.instance_id,
258
+ # )
259
+ # for extra_import in self.extra_imports:
260
+ # result.add_import(
261
+ # statement=extra_import.statement,
262
+ # position=extra_import.position,
263
+ # )
@@ -0,0 +1,241 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+
4
+ """Base extras system for all exporters."""
5
+
6
+ import abc
7
+ from dataclasses import dataclass, field
8
+ from typing import Sequence
9
+
10
+ from ..enums import AgentPosition, ContentOrder, ExportPosition, ImportPosition
11
+ from ..protocols import ExportContributor
12
+ from ..result import ExportResult
13
+ from ..types import ImportStatement, InstanceArgument
14
+
15
+
16
+ @dataclass
17
+ class BaseExtras(ExportContributor):
18
+ """Base class for all exporter extras with export contribution."""
19
+
20
+ instance_id: str
21
+ extra_imports: list[ImportStatement] = field(
22
+ default_factory=list[ImportStatement]
23
+ )
24
+ before_agent: str = ""
25
+ after_agent: str = ""
26
+ after_all_agents: str = ""
27
+ extra_args: list[InstanceArgument] = field(
28
+ default_factory=list[InstanceArgument]
29
+ )
30
+
31
+ def get_extra_args_content(self) -> str:
32
+ """Get the extra arguments content.
33
+
34
+ Returns
35
+ -------
36
+ str
37
+ The extra arguments content.
38
+ """
39
+ return "\n".join([arg.get_content() for arg in self.extra_args]) + "\n"
40
+
41
+ def add_arg(self, arg: InstanceArgument | str, tabs: int = 0) -> None:
42
+ """Add an extra argument.
43
+
44
+ Parameters
45
+ ----------
46
+ arg : InstanceArgument
47
+ The argument to add.
48
+ tabs : int, optional
49
+ The number of tabs to indent the argument, by default 0.
50
+ """
51
+ if isinstance(arg, InstanceArgument):
52
+ if arg not in self.extra_args:
53
+ self.extra_args.append(arg)
54
+ elif isinstance(arg, str) and arg.strip(): # pyright: ignore
55
+ # If it's a string, create an InstanceArgument
56
+ # split by '=' (it's an argument line)
57
+ parts = arg.split("=", 1)
58
+ if len(parts) == 2:
59
+ name, value = parts
60
+ comment = ""
61
+ if " #" in value:
62
+ value, _comment = value.split(" #", 1)
63
+ comment = _comment.strip()
64
+ new_arg = InstanceArgument(
65
+ instance_id=self.instance_id,
66
+ name=name.strip(),
67
+ value=value.strip(),
68
+ tabs=tabs,
69
+ comment=comment.strip(),
70
+ )
71
+ if new_arg not in self.extra_args:
72
+ self.extra_args.append(new_arg)
73
+
74
+ def add_import(self, import_statement: ImportStatement) -> None:
75
+ """Add an import statement.
76
+
77
+ Parameters
78
+ ----------
79
+ import_statement : str
80
+ The import statement to add.
81
+ """
82
+ if import_statement and import_statement.statement.strip():
83
+ self.extra_imports.append(import_statement)
84
+
85
+ def add_imports(self, imports: Sequence[ImportStatement]) -> None:
86
+ """Add multiple import statements.
87
+
88
+ Parameters
89
+ ----------
90
+ imports : Set[str]
91
+ The import statements to add.
92
+ """
93
+ for imp in imports:
94
+ self.add_import(imp)
95
+
96
+ def prepend_before_agent(self, content: str) -> None:
97
+ """Prepend content to the before_agent section.
98
+
99
+ Parameters
100
+ ----------
101
+ content : str
102
+ The content to prepend.
103
+ """
104
+ if content and content.strip():
105
+ if self.before_agent:
106
+ self.before_agent = content.rstrip() + "\n" + self.before_agent
107
+ else:
108
+ self.before_agent = content.rstrip()
109
+
110
+ def append_before_agent(self, content: str) -> None:
111
+ """Append content to the before_agent section.
112
+
113
+ Parameters
114
+ ----------
115
+ content : str
116
+ The content to append.
117
+ """
118
+ if content and content.strip():
119
+ if self.before_agent:
120
+ self.before_agent += "\n" + content.rstrip()
121
+ else:
122
+ self.before_agent = content.rstrip()
123
+
124
+ def append_after_agent(self, content: str) -> None:
125
+ """Append content to the after_agent section.
126
+
127
+ Parameters
128
+ ----------
129
+ content : str
130
+ The content to append.
131
+ """
132
+ if content and content.strip():
133
+ if self.after_agent:
134
+ self.after_agent += "\n" + content.rstrip()
135
+ else:
136
+ self.after_agent = content.rstrip()
137
+
138
+ def append_after_all_agents(self, content: str) -> None:
139
+ """Append content to the after_all_agents section.
140
+
141
+ Parameters
142
+ ----------
143
+ content : str
144
+ The content to append.
145
+ """
146
+ if content and content.strip():
147
+ if self.after_all_agents:
148
+ self.after_all_agents += "\n" + content.rstrip()
149
+ else:
150
+ self.after_all_agents = content.rstrip()
151
+
152
+ def prepend_after_all_agents(self, content: str) -> None:
153
+ """Prepend content to the after_all_agents section.
154
+
155
+ Parameters
156
+ ----------
157
+ content : str
158
+ The content to prepend.
159
+ """
160
+ if content and content.strip():
161
+ if self.after_all_agents:
162
+ self.after_all_agents = (
163
+ content.rstrip() + "\n" + self.after_all_agents
164
+ )
165
+ else:
166
+ self.after_all_agents = content.rstrip()
167
+
168
+ def contribute_to_export(self, result: ExportResult) -> None:
169
+ """Contribute this extras' content to the export result.
170
+
171
+ Parameters
172
+ ----------
173
+ result : ExportResult
174
+ The export result to contribute to.
175
+ """
176
+ # Add imports
177
+ result.add_imports(self.extra_imports, ImportPosition.THIRD_PARTY)
178
+
179
+ # Add before/after content with default positioning
180
+ # Subclasses can override this method for custom positioning
181
+ if self.before_agent:
182
+ result.add_content(
183
+ self.before_agent,
184
+ ExportPosition.AGENTS,
185
+ order=ContentOrder.PRE_CONTENT,
186
+ )
187
+
188
+ if self.extra_args:
189
+ for arg in self.extra_args:
190
+ result.add_content(
191
+ arg.get_content(),
192
+ ExportPosition.AGENTS,
193
+ order=ContentOrder.MAIN_CONTENT,
194
+ agent_position=AgentPosition.AS_ARGUMENT,
195
+ )
196
+
197
+ if self.after_agent:
198
+ result.add_content(
199
+ self.after_agent,
200
+ ExportPosition.AGENTS,
201
+ order=ContentOrder.POST_CONTENT,
202
+ )
203
+
204
+ # Allow subclasses to contribute additional content
205
+ self._contribute_specific_content(result)
206
+
207
+ def _contribute_specific_content(self, result: ExportResult) -> None:
208
+ """Contribute subclass-specific content.
209
+
210
+ Override in subclasses to add type-specific content.
211
+
212
+ Parameters
213
+ ----------
214
+ result : ExportResult
215
+ The export result to contribute to.
216
+ """
217
+
218
+ @abc.abstractmethod
219
+ def has_specific_content(self) -> bool:
220
+ """Check if there's subclass-specific content.
221
+
222
+ Returns
223
+ -------
224
+ bool
225
+ True if there's specific content for this extras type.
226
+ """
227
+
228
+ def has_content(self) -> bool:
229
+ """Check if there's any meaningful content.
230
+
231
+ Returns
232
+ -------
233
+ bool
234
+ True if there's any content in this extras instance.
235
+ """
236
+ return bool(
237
+ self.extra_imports
238
+ or self.before_agent.strip()
239
+ or self.after_agent.strip()
240
+ or self.has_specific_content()
241
+ )