waldiez 0.4.6__py3-none-any.whl → 0.4.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 (244) hide show
  1. waldiez/__init__.py +5 -5
  2. waldiez/_version.py +1 -1
  3. waldiez/cli.py +112 -73
  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} +16 -15
  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 +419 -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 +114 -49
  175. waldiez/running/__init__.py +1 -1
  176. waldiez/running/environment.py +49 -68
  177. waldiez/running/gen_seq_diagram.py +16 -14
  178. waldiez/running/running.py +53 -34
  179. waldiez/utils/__init__.py +0 -4
  180. waldiez/utils/cli_extras/jupyter.py +5 -3
  181. waldiez/utils/cli_extras/runner.py +6 -4
  182. waldiez/utils/cli_extras/studio.py +6 -4
  183. waldiez/utils/conflict_checker.py +15 -9
  184. waldiez/utils/flaml_warnings.py +5 -5
  185. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/METADATA +235 -91
  186. waldiez-0.4.8.dist-info/RECORD +200 -0
  187. waldiez/exporting/agent/agent_exporter.py +0 -297
  188. waldiez/exporting/agent/utils/__init__.py +0 -23
  189. waldiez/exporting/agent/utils/captain_agent.py +0 -263
  190. waldiez/exporting/agent/utils/code_execution.py +0 -65
  191. waldiez/exporting/agent/utils/group_manager.py +0 -220
  192. waldiez/exporting/agent/utils/rag_user/__init__.py +0 -7
  193. waldiez/exporting/agent/utils/rag_user/rag_user.py +0 -209
  194. waldiez/exporting/agent/utils/reasoning.py +0 -36
  195. waldiez/exporting/agent/utils/swarm_agent.py +0 -469
  196. waldiez/exporting/agent/utils/teachability.py +0 -41
  197. waldiez/exporting/agent/utils/termination_message.py +0 -44
  198. waldiez/exporting/base/__init__.py +0 -25
  199. waldiez/exporting/base/agent_position.py +0 -75
  200. waldiez/exporting/base/base_exporter.py +0 -118
  201. waldiez/exporting/base/export_position.py +0 -48
  202. waldiez/exporting/base/import_position.py +0 -23
  203. waldiez/exporting/base/mixin.py +0 -137
  204. waldiez/exporting/base/utils/__init__.py +0 -18
  205. waldiez/exporting/base/utils/comments.py +0 -96
  206. waldiez/exporting/base/utils/path_check.py +0 -68
  207. waldiez/exporting/base/utils/to_string.py +0 -84
  208. waldiez/exporting/chats/chats_exporter.py +0 -240
  209. waldiez/exporting/chats/utils/swarm.py +0 -210
  210. waldiez/exporting/flow/flow_exporter.py +0 -528
  211. waldiez/exporting/flow/utils/agent_utils.py +0 -204
  212. waldiez/exporting/flow/utils/chat_utils.py +0 -71
  213. waldiez/exporting/flow/utils/def_main.py +0 -77
  214. waldiez/exporting/flow/utils/flow_content.py +0 -202
  215. waldiez/exporting/flow/utils/flow_names.py +0 -116
  216. waldiez/exporting/flow/utils/importing_utils.py +0 -227
  217. waldiez/exporting/models/models_exporter.py +0 -199
  218. waldiez/exporting/models/utils.py +0 -174
  219. waldiez/exporting/skills/__init__.py +0 -9
  220. waldiez/exporting/skills/skills_exporter.py +0 -176
  221. waldiez/exporting/skills/utils.py +0 -369
  222. waldiez/models/agents/agent/teachability.py +0 -70
  223. waldiez/models/agents/rag_user/rag_user.py +0 -60
  224. waldiez/models/agents/swarm_agent/__init__.py +0 -50
  225. waldiez/models/agents/swarm_agent/after_work.py +0 -179
  226. waldiez/models/agents/swarm_agent/on_condition.py +0 -105
  227. waldiez/models/agents/swarm_agent/on_condition_available.py +0 -142
  228. waldiez/models/agents/swarm_agent/on_condition_target.py +0 -40
  229. waldiez/models/agents/swarm_agent/swarm_agent.py +0 -107
  230. waldiez/models/agents/swarm_agent/swarm_agent_data.py +0 -124
  231. waldiez/models/flow/utils.py +0 -232
  232. waldiez/models/skill/__init__.py +0 -16
  233. waldiez/models/skill/extra_requirements.py +0 -36
  234. waldiez/models/skill/skill_data.py +0 -53
  235. waldiez/models/skill/skill_type.py +0 -8
  236. waldiez/utils/pysqlite3_checker.py +0 -308
  237. waldiez/utils/rdps_checker.py +0 -122
  238. waldiez-0.4.6.dist-info/RECORD +0 -149
  239. /waldiez/models/agents/{captain_agent → captain}/__init__.py +0 -0
  240. /waldiez/models/agents/{captain_agent → captain}/captain_agent_lib_entry.py +0 -0
  241. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/WHEEL +0 -0
  242. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/entry_points.txt +0 -0
  243. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/licenses/LICENSE +0 -0
  244. {waldiez-0.4.6.dist-info → waldiez-0.4.8.dist-info}/licenses/NOTICE.md +0 -0
@@ -0,0 +1,181 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=no-self-use,too-few-public-methods
4
+ """Group member agent configuration processor."""
5
+
6
+ from dataclasses import dataclass, field
7
+ from typing import Callable
8
+
9
+ from waldiez.models import (
10
+ WaldiezAgent,
11
+ WaldiezAgentUpdateSystemMessage,
12
+ WaldiezChat,
13
+ )
14
+
15
+ from ...core import (
16
+ ImportStatement,
17
+ InstanceArgument,
18
+ )
19
+ from .handoffs import HandoffProcessor
20
+
21
+
22
+ @dataclass
23
+ class GroupMemberProcessorResult:
24
+ """Result from processing group member agent configuration."""
25
+
26
+ before_agent: str = ""
27
+ after_agent: str = ""
28
+ extra_arguments: list[InstanceArgument] = field(
29
+ default_factory=list[InstanceArgument]
30
+ )
31
+ extra_imports: set[ImportStatement] = field(
32
+ default_factory=set[ImportStatement]
33
+ )
34
+
35
+
36
+ class GroupMemberAgentProcessor:
37
+ """Processor for group member agent configuration."""
38
+
39
+ result: GroupMemberProcessorResult
40
+
41
+ def __init__(
42
+ self,
43
+ agent: WaldiezAgent,
44
+ agent_names: dict[str, str],
45
+ tool_names: dict[str, str],
46
+ all_chats: list[WaldiezChat],
47
+ chat_names: dict[str, str],
48
+ serializer: Callable[..., str],
49
+ ) -> None:
50
+ self.agent = agent
51
+ self.agent_names = agent_names
52
+ self.tool_names = tool_names
53
+ self.all_chats = all_chats
54
+ self.chat_names = chat_names
55
+ self.serializer = serializer
56
+
57
+ def process(
58
+ self,
59
+ ) -> GroupMemberProcessorResult:
60
+ """Process group member agent configuration.
61
+
62
+ Returns
63
+ -------
64
+ GroupMemberProcessorResult
65
+ The processed result containing before_agent code,
66
+ after_agent code, and extra imports.
67
+ """
68
+ self.result = GroupMemberProcessorResult()
69
+ if not self.agent.is_group_member:
70
+ return self.result
71
+ self._process_agent_functions()
72
+ self._process_agent_update_state_before_reply()
73
+ self._process_handoff_registrations()
74
+ return self.result
75
+
76
+ def _process_agent_functions(self) -> None:
77
+ """Process function arguments for the agent."""
78
+ tab = " "
79
+ arg_string = "["
80
+
81
+ tools_added = self._add_tools()
82
+ if tools_added:
83
+ arg_string += f"{tools_added}\n{tab}"
84
+
85
+ arg_string += "]"
86
+ self.result.extra_arguments.append(
87
+ InstanceArgument(
88
+ name="functions",
89
+ value=arg_string,
90
+ instance_id=self.agent.id,
91
+ tabs=1,
92
+ )
93
+ )
94
+
95
+ def _add_tools(self) -> str:
96
+ """Add tools to the function arguments."""
97
+ tab = " "
98
+ arg_string = ""
99
+ for tool in self.agent.data.tools:
100
+ tool_name = self.tool_names.get(tool.id)
101
+ if tool_name:
102
+ arg_string += f"\n{tab}{tab}{tool_name},"
103
+ return arg_string
104
+
105
+ def _process_agent_update_state_before_reply(self) -> None:
106
+ """Process agent update state before reply configuration."""
107
+ tab = " "
108
+ arg_string = "["
109
+
110
+ arcg_content = self._process_update_functions()
111
+
112
+ if arcg_content:
113
+ arg_string += f"{arcg_content}\n{tab}"
114
+ self.result.extra_imports.add(
115
+ ImportStatement("from autogen import UpdateSystemMessage")
116
+ )
117
+ arg_string += "]"
118
+ self.result.extra_arguments.append(
119
+ InstanceArgument(
120
+ name="update_agent_state_before_reply",
121
+ value=arg_string,
122
+ instance_id=self.agent.id,
123
+ tabs=1,
124
+ )
125
+ )
126
+
127
+ def _process_update_functions(
128
+ self,
129
+ ) -> str:
130
+ """Process individual update functions."""
131
+ arg_content = ""
132
+
133
+ for function in self.agent.data.update_agent_state_before_reply:
134
+ if isinstance(function, WaldiezAgentUpdateSystemMessage):
135
+ arg_content = self._process_system_message_update(function)
136
+ else:
137
+ arg_content = self._process_tool_update(function)
138
+
139
+ return arg_content
140
+
141
+ def _process_system_message_update(
142
+ self,
143
+ function: WaldiezAgentUpdateSystemMessage,
144
+ ) -> str:
145
+ """Process system message update function."""
146
+ tab = " "
147
+ space = tab * 2
148
+ if function.type == "callable":
149
+ content, name = function.get_content(
150
+ name_suffix=self.agent_names[self.agent.id]
151
+ )
152
+ arg_string = f"\n{space}UpdateSystemMessage({name}),"
153
+ self.result.before_agent += content + "\n"
154
+ else:
155
+ dumped = self.serializer(function.content)
156
+ arg_string = f"\n{space}UpdateSystemMessage({dumped}),"
157
+ return arg_string
158
+
159
+ def _process_tool_update(
160
+ self,
161
+ function_id: str,
162
+ ) -> str:
163
+ """Process tool-based update function."""
164
+ tool_name = self.tool_names.get(function_id)
165
+ if tool_name:
166
+ tab = " "
167
+ return f"\n{tab}{tab}{tool_name},"
168
+ return ""
169
+
170
+ def _process_handoff_registrations(self) -> None:
171
+ """Process handoff registrations for the agent."""
172
+ result = HandoffProcessor(
173
+ agent=self.agent,
174
+ agent_names=self.agent_names,
175
+ chat_names=self.chat_names,
176
+ all_chats=self.all_chats,
177
+ serializer=self.serializer,
178
+ ).process()
179
+ for extra_import in result.extra_imports:
180
+ self.result.extra_imports.add(ImportStatement(extra_import))
181
+ self.result.after_agent += result.after_agent
@@ -0,0 +1,19 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Utility functions for generating agent related strings."""
4
+
5
+ from .after_work import AfterWorkProcessor, AfterWorkResult
6
+ from .handoff import HandoffProcessor, HandoffResult
7
+ from .target import (
8
+ TargetResult,
9
+ TransitionTargetProcessor,
10
+ )
11
+
12
+ __all__ = [
13
+ "AfterWorkProcessor",
14
+ "AfterWorkResult",
15
+ "HandoffProcessor",
16
+ "HandoffResult",
17
+ "TargetResult",
18
+ "TransitionTargetProcessor",
19
+ ]
@@ -0,0 +1,78 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """After-work processor for Waldiez agents."""
4
+
5
+ # pylint: disable=too-few-public-methods
6
+ from dataclasses import dataclass, field
7
+ from typing import Callable
8
+
9
+ from waldiez.models import WaldiezAgent, WaldiezChat, WaldiezTransitionTarget
10
+
11
+ from .target import TransitionTargetProcessor
12
+
13
+
14
+ @dataclass
15
+ class AfterWorkResult:
16
+ """Result from processing after-work configuration.
17
+
18
+ Attributes
19
+ ----------
20
+ registration : str
21
+ Code to register the after-work transition.
22
+ after_agent : str
23
+ Code to be placed after the agent definition.
24
+ extra_imports : set[str]
25
+ Additional imports required for the after-work transition.
26
+ """
27
+
28
+ content: str = ""
29
+ before_content: str = ""
30
+ extra_imports: set[str] = field(default_factory=set[str])
31
+
32
+
33
+ class AfterWorkProcessor:
34
+ """Processor for after-work configurations."""
35
+
36
+ def __init__(
37
+ self,
38
+ agent: WaldiezAgent,
39
+ agent_names: dict[str, str],
40
+ chat_names: dict[str, str],
41
+ all_chats: list[WaldiezChat],
42
+ serializer: Callable[..., str],
43
+ ):
44
+ """Initialize the processor."""
45
+ self.agent = agent
46
+ self.agent_names = agent_names
47
+ self.agent_name = agent_names[agent.id]
48
+ self.chat_names = chat_names
49
+ self.all_chats = all_chats
50
+ self.serializer = serializer
51
+
52
+ def process(self, after_work: WaldiezTransitionTarget) -> AfterWorkResult:
53
+ """Process after-work configuration.
54
+
55
+ Parameters
56
+ ----------
57
+ after_work : WaldiezTransitionTarget
58
+ The after-work transition target to process.
59
+
60
+ Returns
61
+ -------
62
+ AfterWorkResult
63
+ The processed result containing the registration string,
64
+ before_content code, and extra imports.
65
+ """
66
+ target_processor = TransitionTargetProcessor(
67
+ agent=self.agent,
68
+ agent_names=self.agent_names,
69
+ chat_names=self.chat_names,
70
+ all_chats=self.all_chats,
71
+ serializer=self.serializer,
72
+ )
73
+ target_result = target_processor.process(after_work)
74
+ return AfterWorkResult(
75
+ content=target_result.content,
76
+ before_content=target_result.before_content,
77
+ extra_imports=target_result.extra_imports,
78
+ )
@@ -0,0 +1,74 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-few-public-methods
4
+ """Transition availability processor for Waldiez agents."""
5
+
6
+ from dataclasses import dataclass, field
7
+ from typing import Callable
8
+
9
+ from waldiez.models import WaldiezTransitionAvailability
10
+
11
+
12
+ @dataclass
13
+ class TransitionAvailableResult:
14
+ """Result from processing transition availability."""
15
+
16
+ content: str = ""
17
+ extra_imports: set[str] = field(default_factory=set[str])
18
+
19
+
20
+ class TransitionAvailableProcessor:
21
+ """Processor for transition availability."""
22
+
23
+ def __init__(
24
+ self,
25
+ serializer: Callable[..., str],
26
+ ) -> None:
27
+ """Initialize the processor."""
28
+ self.serializer = serializer
29
+
30
+ def process(
31
+ self,
32
+ available: WaldiezTransitionAvailability,
33
+ ) -> TransitionAvailableResult:
34
+ """Process the transition availability.
35
+
36
+ Parameters
37
+ ----------
38
+ available : WaldiezTransitionAvailability
39
+ The transition availability to process.
40
+
41
+ Returns
42
+ -------
43
+ TransitionAvailableResult
44
+ The result of processing the transition availability.
45
+
46
+ Raises
47
+ ------
48
+ ValueError
49
+ If the transition type is unsupported.
50
+ """
51
+ result = TransitionAvailableResult()
52
+ if available.type == "none":
53
+ return result
54
+ import_prefix = "from autogen.agentchat.group import "
55
+ if available.type == "string":
56
+ content = self.serializer(available.value)
57
+ result.content = f"StringAvailableCondition({content})"
58
+ result.extra_imports.add(f"{import_prefix}StringAvailableCondition")
59
+ return result
60
+ if available.type == "expression":
61
+ content = self.serializer(available.value)
62
+ result.content = (
63
+ "ExpressionAvailableCondition(\n"
64
+ f" expression=ContextExpression({content})\n"
65
+ " )"
66
+ )
67
+ result.extra_imports.add(
68
+ f"{import_prefix}ExpressionAvailableCondition"
69
+ )
70
+ result.extra_imports.add(f"{import_prefix}ContextExpression")
71
+ return result
72
+ raise ValueError(
73
+ f"Unsupported transition availability type: {available.type}"
74
+ )
@@ -0,0 +1,158 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-few-public-methods
4
+ """Handoff condition processing for Waldiez agents."""
5
+
6
+ from dataclasses import dataclass, field
7
+ from typing import Callable
8
+
9
+ from waldiez.models import (
10
+ WaldiezAgent,
11
+ WaldiezChat,
12
+ WaldiezContextStrLLMCondition,
13
+ WaldiezExpressionContextCondition,
14
+ WaldiezHandoffCondition,
15
+ WaldiezStringContextCondition,
16
+ WaldiezStringLLMCondition,
17
+ )
18
+
19
+
20
+ @dataclass
21
+ class ConditionResult:
22
+ """Result from processing handoff conditions.
23
+
24
+ Attributes
25
+ ----------
26
+ content : str
27
+ Content to be used for the handoff condition.
28
+ extra_imports : set[str]
29
+ Additional imports required for the handoff.
30
+ """
31
+
32
+ content: str = ""
33
+ extra_imports: set[str] = field(default_factory=set[str])
34
+
35
+
36
+ class ConditionProcessor:
37
+ """Processor for handoff conditions."""
38
+
39
+ IMPORT_PREFIX = "from autogen.agentchat.group import "
40
+
41
+ def __init__(
42
+ self,
43
+ agent: WaldiezAgent,
44
+ agent_names: dict[str, str],
45
+ chat_names: dict[str, str],
46
+ all_chats: list[WaldiezChat],
47
+ serializer: Callable[..., str],
48
+ ) -> None:
49
+ """Initialize the processor with agent context."""
50
+ self.agent = agent
51
+ self.agent_names = agent_names
52
+ self.agent_name = agent_names[agent.id]
53
+ self.chat_names = chat_names
54
+ self.all_chats = all_chats
55
+ self.serializer = serializer
56
+ self.result = ConditionResult()
57
+
58
+ def process(self, condition: WaldiezHandoffCondition) -> ConditionResult:
59
+ """Process handoff conditions.
60
+
61
+ Parameters
62
+ ----------
63
+ condition : WaldiezHandoffCondition
64
+ The handoff condition to process.
65
+
66
+ Returns
67
+ -------
68
+ ConditionResult
69
+ The processed result containing the relevant code and extra imports.
70
+
71
+ Raises
72
+ ------
73
+ ValueError
74
+ If the condition type is unsupported.
75
+ """
76
+ if isinstance(condition, WaldiezStringLLMCondition):
77
+ self._process_string_llm_condition(condition)
78
+ elif isinstance(condition, WaldiezContextStrLLMCondition):
79
+ self._process_context_str_llm_condition(condition)
80
+ elif isinstance(condition, WaldiezStringContextCondition):
81
+ self._process_string_context_condition(condition)
82
+ elif isinstance(
83
+ condition,
84
+ WaldiezExpressionContextCondition,
85
+ ): # pyright: ignore
86
+ self._process_expression_context_condition(condition)
87
+ else:
88
+ raise ValueError(f"Unsupported condition type: {type(condition)}")
89
+ return self.result
90
+
91
+ def _process_string_llm_condition(
92
+ self,
93
+ condition: WaldiezStringLLMCondition,
94
+ ) -> None:
95
+ """Process a string LLM condition handoff."""
96
+ prompt = self.serializer(condition.prompt)
97
+
98
+ if hasattr(condition, "data") and condition.data:
99
+ data_str = self.serializer(condition.data)
100
+ condition_string = (
101
+ f"StringLLMCondition(prompt={prompt}, data={data_str})"
102
+ )
103
+ else:
104
+ condition_string = f"StringLLMCondition(prompt={prompt})"
105
+ self.result.content += condition_string
106
+ extra_import = f"{self.IMPORT_PREFIX}StringLLMCondition"
107
+ self.result.extra_imports.add(extra_import)
108
+
109
+ def _process_context_str_llm_condition(
110
+ self,
111
+ condition: WaldiezContextStrLLMCondition,
112
+ ) -> None:
113
+ """Process a context string LLM condition handoff."""
114
+ context_str = self.serializer(
115
+ condition.context_str,
116
+ )
117
+
118
+ if hasattr(condition, "data") and condition.data:
119
+ data_str = self.serializer(condition.data)
120
+ condition_string = (
121
+ f"ContextStrLLMCondition(context_str={context_str}, "
122
+ f"data={data_str})"
123
+ )
124
+ else:
125
+ condition_string = (
126
+ f"ContextStrLLMCondition(context_str={context_str})"
127
+ )
128
+ self.result.content += condition_string
129
+ extra_import = f"{self.IMPORT_PREFIX}ContextStrLLMCondition"
130
+ self.result.extra_imports.add(extra_import)
131
+
132
+ def _process_string_context_condition(
133
+ self,
134
+ condition: WaldiezStringContextCondition,
135
+ ) -> None:
136
+ """Process a string context condition handoff."""
137
+ variable_name = self.serializer(
138
+ condition.variable_name,
139
+ )
140
+ condition_string = (
141
+ f"StringContextCondition(variable_name={variable_name})"
142
+ )
143
+ self.result.content += condition_string
144
+ extra_import = f"{self.IMPORT_PREFIX}StringContextCondition"
145
+ self.result.extra_imports.add(extra_import)
146
+
147
+ def _process_expression_context_condition(
148
+ self,
149
+ condition: WaldiezExpressionContextCondition,
150
+ ) -> None:
151
+ """Process an expression context condition handoff."""
152
+ expression = self.serializer(condition.expression)
153
+ condition_string = (
154
+ f"ExpressionContextCondition(expression={expression})"
155
+ )
156
+ self.result.content += condition_string
157
+ extra_import = f"{self.IMPORT_PREFIX}ExpressionContextCondition"
158
+ self.result.extra_imports.add(extra_import)
@@ -0,0 +1,171 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-few-public-methods
4
+ """Handoff processor for Waldiez agents."""
5
+
6
+ from dataclasses import dataclass, field
7
+ from typing import Callable
8
+
9
+ from waldiez.models import (
10
+ WaldiezAgent,
11
+ WaldiezChat,
12
+ WaldiezHandoff,
13
+ WaldiezTransitionTarget,
14
+ )
15
+
16
+ from .available import (
17
+ TransitionAvailableProcessor,
18
+ TransitionAvailableResult,
19
+ )
20
+ from .condition import ConditionProcessor, ConditionResult
21
+ from .target import TargetResult, TransitionTargetProcessor
22
+
23
+
24
+ @dataclass
25
+ class HandoffResult:
26
+ """Result from processing handoffs.
27
+
28
+ Attributes
29
+ ----------
30
+ Content to be placed before the agent definition.
31
+ after_agent : str
32
+ Content to be placed after the agent definition.
33
+ extra_imports : set[str]
34
+ Additional imports required for the handoff.
35
+ """
36
+
37
+ after_agent: str = ""
38
+ extra_imports: set[str] = field(default_factory=set[str])
39
+
40
+
41
+ class HandoffProcessor:
42
+ """Processor for agent handoffs."""
43
+
44
+ result: HandoffResult
45
+ IMPORT_PREFIX = "from autogen.agentchat.group import "
46
+
47
+ def __init__(
48
+ self,
49
+ agent: WaldiezAgent,
50
+ agent_names: dict[str, str],
51
+ chat_names: dict[str, str],
52
+ all_chats: list[WaldiezChat],
53
+ serializer: Callable[..., str],
54
+ ) -> None:
55
+ self.agent = agent
56
+ self.agent_names = agent_names
57
+ self.agent_name = agent_names[agent.id]
58
+ self.chat_names = chat_names
59
+ self.all_chats = all_chats
60
+ self.serializer = serializer
61
+ self.result = HandoffResult()
62
+
63
+ def process(self) -> HandoffResult:
64
+ """Process all handoff configurations.
65
+
66
+ Returns
67
+ -------
68
+ HandoffResult
69
+ The processed handoff result containing after_agent code,
70
+ and extra imports.
71
+ """
72
+ for handoff in self.agent.handoffs:
73
+ if handoff.is_empty():
74
+ continue
75
+ target = TransitionTargetProcessor(
76
+ agent=self.agent,
77
+ agent_names=self.agent_names,
78
+ chat_names=self.chat_names,
79
+ all_chats=self.all_chats,
80
+ serializer=self.serializer,
81
+ ).process(target=handoff.target)
82
+ self.result.extra_imports.update(target.extra_imports)
83
+ if target.before_content:
84
+ self.result.after_agent += f"{target.before_content}\n"
85
+ condition = ConditionProcessor(
86
+ agent=self.agent,
87
+ agent_names=self.agent_names,
88
+ chat_names=self.chat_names,
89
+ all_chats=self.all_chats,
90
+ serializer=self.serializer,
91
+ ).process(condition=handoff.condition)
92
+ self.result.extra_imports.update(condition.extra_imports)
93
+ available = TransitionAvailableProcessor(
94
+ serializer=self.serializer,
95
+ ).process(
96
+ available=handoff.available,
97
+ )
98
+ registration = self._create_handoff_registration(
99
+ handoff=handoff,
100
+ target=target,
101
+ condition=condition,
102
+ available=available,
103
+ )
104
+ self.result.extra_imports.update(available.extra_imports)
105
+ if registration:
106
+ self.result.after_agent += f"{registration}\n"
107
+
108
+ if self.agent.data.after_work:
109
+ after_work_result = self._process_after_work(
110
+ self.agent.data.after_work
111
+ )
112
+ if after_work_result.before_content:
113
+ self.result.after_agent += (
114
+ f"{after_work_result.before_content}\n"
115
+ )
116
+ self.result.after_agent += after_work_result.content
117
+ self.result.extra_imports.update(after_work_result.extra_imports)
118
+ return self.result
119
+
120
+ def _create_handoff_registration(
121
+ self,
122
+ handoff: WaldiezHandoff,
123
+ target: TargetResult,
124
+ condition: ConditionResult,
125
+ available: TransitionAvailableResult,
126
+ ) -> str:
127
+ """Create the handoff registration string."""
128
+ if handoff.is_empty():
129
+ return ""
130
+ reg_string = ""
131
+ if handoff.is_llm_based():
132
+ reg_string += f"{self.agent_name}.handoffs.add_llm_condition(\n"
133
+ reg_string += " condition=OnCondition(\n"
134
+ self.result.extra_imports.add(f"{self.IMPORT_PREFIX}OnCondition")
135
+ else:
136
+ reg_string += f"{self.agent_name}.handoffs.add_context_condition(\n"
137
+ reg_string += " condition=OnContextCondition(\n"
138
+ self.result.extra_imports.add(
139
+ f"{self.IMPORT_PREFIX}OnContextCondition"
140
+ )
141
+ reg_string += f" target={target.content},\n"
142
+ reg_string += f" condition={condition.content},\n"
143
+ if available.content:
144
+ reg_string += f" available={available.content},\n"
145
+ reg_string += " )\n"
146
+ reg_string += ")"
147
+ return reg_string
148
+
149
+ def _process_after_work(
150
+ self, after_work: WaldiezTransitionTarget
151
+ ) -> TargetResult:
152
+ target_processor = TransitionTargetProcessor(
153
+ agent=self.agent,
154
+ agent_names=self.agent_names,
155
+ chat_names=self.chat_names,
156
+ all_chats=self.all_chats,
157
+ serializer=self.serializer,
158
+ )
159
+ target_result = target_processor.process(after_work)
160
+ if not target_result.content:
161
+ return TargetResult()
162
+ registration = (
163
+ f"{self.agent_name}.handoffs.set_after_work(\n"
164
+ f" target={target_result.content}\n"
165
+ ")"
166
+ )
167
+ return TargetResult(
168
+ content=registration,
169
+ before_content=target_result.before_content,
170
+ extra_imports=target_result.extra_imports,
171
+ )