waldiez 0.2.2__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of waldiez might be problematic. Click here for more details.
- waldiez/__init__.py +2 -0
- waldiez/__main__.py +2 -0
- waldiez/_version.py +3 -1
- waldiez/cli.py +13 -3
- waldiez/cli_extras.py +4 -3
- waldiez/conflict_checker.py +4 -3
- waldiez/exporter.py +28 -105
- waldiez/exporting/__init__.py +8 -9
- waldiez/exporting/agent/__init__.py +7 -0
- waldiez/exporting/agent/agent_exporter.py +279 -0
- waldiez/exporting/agent/utils/__init__.py +23 -0
- waldiez/exporting/agent/utils/agent_class_name.py +34 -0
- waldiez/exporting/agent/utils/agent_imports.py +50 -0
- waldiez/exporting/{agents → agent/utils}/code_execution.py +9 -11
- waldiez/exporting/{agents → agent/utils}/group_manager.py +47 -35
- waldiez/exporting/{agents → agent/utils}/rag_user/__init__.py +2 -0
- waldiez/exporting/{agents → agent/utils}/rag_user/chroma_utils.py +22 -17
- waldiez/exporting/{agents → agent/utils}/rag_user/mongo_utils.py +14 -10
- waldiez/exporting/{agents → agent/utils}/rag_user/pgvector_utils.py +12 -8
- waldiez/exporting/{agents → agent/utils}/rag_user/qdrant_utils.py +11 -8
- waldiez/exporting/{agents → agent/utils}/rag_user/rag_user.py +78 -55
- waldiez/exporting/{agents → agent/utils}/rag_user/vector_db.py +10 -8
- waldiez/exporting/agent/utils/swarm_agent.py +463 -0
- waldiez/exporting/{agents → agent/utils}/teachability.py +10 -6
- waldiez/exporting/{agents → agent/utils}/termination_message.py +7 -8
- waldiez/exporting/base/__init__.py +25 -0
- waldiez/exporting/base/agent_position.py +75 -0
- waldiez/exporting/base/base_exporter.py +118 -0
- waldiez/exporting/base/export_position.py +48 -0
- waldiez/exporting/base/import_position.py +23 -0
- waldiez/exporting/base/mixin.py +134 -0
- waldiez/exporting/base/utils/__init__.py +18 -0
- waldiez/exporting/{utils → base/utils}/comments.py +12 -55
- waldiez/exporting/{utils → base/utils}/naming.py +14 -4
- waldiez/exporting/base/utils/path_check.py +68 -0
- waldiez/exporting/{utils/object_string.py → base/utils/to_string.py} +21 -20
- waldiez/exporting/chats/__init__.py +5 -12
- waldiez/exporting/chats/chats_exporter.py +240 -0
- waldiez/exporting/chats/utils/__init__.py +15 -0
- waldiez/exporting/chats/utils/common.py +81 -0
- waldiez/exporting/chats/{nested.py → utils/nested.py} +125 -86
- waldiez/exporting/chats/utils/sequential.py +244 -0
- waldiez/exporting/chats/utils/single_chat.py +313 -0
- waldiez/exporting/chats/utils/swarm.py +207 -0
- waldiez/exporting/flow/__init__.py +5 -3
- waldiez/exporting/flow/flow_exporter.py +503 -0
- waldiez/exporting/flow/utils/__init__.py +47 -0
- waldiez/exporting/flow/utils/agent_utils.py +204 -0
- waldiez/exporting/flow/utils/chat_utils.py +71 -0
- waldiez/exporting/flow/utils/def_main.py +62 -0
- waldiez/exporting/flow/utils/flow_content.py +112 -0
- waldiez/exporting/flow/utils/flow_names.py +115 -0
- waldiez/exporting/flow/utils/importing_utils.py +182 -0
- waldiez/exporting/{utils → flow/utils}/logging_utils.py +34 -31
- waldiez/exporting/models/__init__.py +7 -242
- waldiez/exporting/models/models_exporter.py +192 -0
- waldiez/exporting/models/utils.py +166 -0
- waldiez/exporting/skills/__init__.py +7 -161
- waldiez/exporting/skills/skills_exporter.py +169 -0
- waldiez/exporting/skills/utils.py +281 -0
- waldiez/models/__init__.py +25 -7
- waldiez/models/agents/__init__.py +70 -0
- waldiez/models/agents/agent/__init__.py +11 -1
- waldiez/models/agents/agent/agent.py +9 -4
- waldiez/models/agents/agent/agent_data.py +3 -1
- waldiez/models/agents/agent/code_execution.py +2 -0
- waldiez/models/agents/agent/linked_skill.py +2 -0
- waldiez/models/agents/agent/nested_chat.py +2 -0
- waldiez/models/agents/agent/teachability.py +2 -0
- waldiez/models/agents/agent/termination_message.py +49 -13
- waldiez/models/agents/agents.py +15 -3
- waldiez/models/agents/assistant/__init__.py +2 -0
- waldiez/models/agents/assistant/assistant.py +2 -0
- waldiez/models/agents/assistant/assistant_data.py +2 -0
- waldiez/models/agents/group_manager/__init__.py +9 -1
- waldiez/models/agents/group_manager/group_manager.py +2 -0
- waldiez/models/agents/group_manager/group_manager_data.py +2 -0
- waldiez/models/agents/group_manager/speakers.py +49 -13
- waldiez/models/agents/rag_user/__init__.py +21 -4
- waldiez/models/agents/rag_user/rag_user.py +3 -1
- waldiez/models/agents/rag_user/rag_user_data.py +2 -0
- waldiez/models/agents/rag_user/retrieve_config.py +268 -17
- waldiez/models/agents/rag_user/vector_db_config.py +5 -3
- waldiez/models/agents/swarm_agent/__init__.py +49 -0
- waldiez/models/agents/swarm_agent/after_work.py +178 -0
- waldiez/models/agents/swarm_agent/on_condition.py +103 -0
- waldiez/models/agents/swarm_agent/on_condition_available.py +140 -0
- waldiez/models/agents/swarm_agent/on_condition_target.py +40 -0
- waldiez/models/agents/swarm_agent/swarm_agent.py +107 -0
- waldiez/models/agents/swarm_agent/swarm_agent_data.py +125 -0
- waldiez/models/agents/swarm_agent/update_system_message.py +144 -0
- waldiez/models/agents/user_proxy/__init__.py +2 -0
- waldiez/models/agents/user_proxy/user_proxy.py +2 -0
- waldiez/models/agents/user_proxy/user_proxy_data.py +2 -0
- waldiez/models/chat/__init__.py +21 -3
- waldiez/models/chat/chat.py +241 -7
- waldiez/models/chat/chat_data.py +192 -48
- waldiez/models/chat/chat_message.py +153 -144
- waldiez/models/chat/chat_nested.py +33 -53
- waldiez/models/chat/chat_summary.py +2 -0
- waldiez/models/common/__init__.py +6 -6
- waldiez/models/common/base.py +4 -1
- waldiez/models/common/method_utils.py +163 -83
- waldiez/models/flow/__init__.py +2 -0
- waldiez/models/flow/flow.py +176 -40
- waldiez/models/flow/flow_data.py +63 -2
- waldiez/models/flow/utils.py +172 -0
- waldiez/models/model/__init__.py +2 -0
- waldiez/models/model/model.py +30 -9
- waldiez/models/model/model_data.py +3 -1
- waldiez/models/skill/__init__.py +4 -1
- waldiez/models/skill/skill.py +30 -2
- waldiez/models/skill/skill_data.py +2 -0
- waldiez/models/waldiez.py +28 -4
- waldiez/runner.py +142 -228
- waldiez/running/__init__.py +33 -0
- waldiez/running/environment.py +83 -0
- waldiez/running/gen_seq_diagram.py +185 -0
- waldiez/running/running.py +300 -0
- {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/METADATA +35 -28
- waldiez-0.3.1.dist-info/RECORD +125 -0
- waldiez-0.3.1.dist-info/licenses/LICENSE +201 -0
- waldiez/exporting/agents/__init__.py +0 -5
- waldiez/exporting/agents/agent.py +0 -236
- waldiez/exporting/agents/agent_skills.py +0 -67
- waldiez/exporting/agents/llm_config.py +0 -53
- waldiez/exporting/chats/chats.py +0 -46
- waldiez/exporting/chats/helpers.py +0 -420
- waldiez/exporting/flow/def_main.py +0 -32
- waldiez/exporting/flow/flow.py +0 -189
- waldiez/exporting/utils/__init__.py +0 -36
- waldiez/exporting/utils/importing.py +0 -265
- waldiez/exporting/utils/method_utils.py +0 -35
- waldiez/exporting/utils/path_check.py +0 -51
- waldiez-0.2.2.dist-info/RECORD +0 -92
- waldiez-0.2.2.dist-info/licenses/LICENSE +0 -21
- {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/WHEEL +0 -0
- {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
# pylint: disable=unused-argument
|
|
4
|
+
"""Get the extras for a swarm agent."""
|
|
5
|
+
|
|
6
|
+
from typing import Callable, Dict, List, Tuple
|
|
7
|
+
|
|
8
|
+
from waldiez.exporting.chats.utils.nested import get_nested_chat_queue
|
|
9
|
+
from waldiez.models import (
|
|
10
|
+
WaldiezAgent,
|
|
11
|
+
WaldiezChat,
|
|
12
|
+
WaldiezSwarmAfterWork,
|
|
13
|
+
WaldiezSwarmAgent,
|
|
14
|
+
WaldiezSwarmOnCondition,
|
|
15
|
+
WaldiezSwarmUpdateSystemMessage,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# SwarmAgent is a subclass of ConversableAgent.
|
|
19
|
+
|
|
20
|
+
# Additional args:
|
|
21
|
+
# functions (List[Callable]):
|
|
22
|
+
# -A list of functions to register with the agent.
|
|
23
|
+
# update_agent_state_before_reply (List[Callable]):
|
|
24
|
+
# - A list of functions, including UPDATE_SYSTEM_MESSAGEs,
|
|
25
|
+
# called to update the agent before it replies.
|
|
26
|
+
|
|
27
|
+
# Additional methods:
|
|
28
|
+
# register_hand_off(hand_offs: List[AfterWork|OnCondition]):
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_swarm_extras(
|
|
32
|
+
agent: WaldiezAgent,
|
|
33
|
+
agent_names: Dict[str, str],
|
|
34
|
+
skill_names: Dict[str, str],
|
|
35
|
+
chats: Tuple[List[WaldiezChat], Dict[str, str]],
|
|
36
|
+
is_async: bool,
|
|
37
|
+
serializer: Callable[..., str],
|
|
38
|
+
string_escape: Callable[[str], str],
|
|
39
|
+
) -> Tuple[str, str, str]:
|
|
40
|
+
"""Get the extras of a swarm agent.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
agent : WaldiezAgent
|
|
45
|
+
The agent to get the extras for.
|
|
46
|
+
agent_names : Dict[str, str]
|
|
47
|
+
A mapping of agent IDs to agent names.
|
|
48
|
+
skill_names : Dict[str, str]
|
|
49
|
+
A mapping of skill IDs to skill names.
|
|
50
|
+
chats : Tuple[List[WaldiezChat], Dict[str, str]]
|
|
51
|
+
The list of all chats and the mapping of chat IDs to chat names.
|
|
52
|
+
is_async : bool
|
|
53
|
+
Whether the chat is asynchronous.
|
|
54
|
+
serializer : Callable[..., str]
|
|
55
|
+
The serializer to get the string representation of an object.
|
|
56
|
+
string_escape : Callable[[str], str]
|
|
57
|
+
The function to escape the string quotes and newlines.
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
Tuple[str, str, str]
|
|
61
|
+
The extras of the swarm agent:
|
|
62
|
+
the content before the agent,
|
|
63
|
+
the extra argument(s) for the agent initialization,
|
|
64
|
+
and the content after the agent.
|
|
65
|
+
"""
|
|
66
|
+
args_string = ""
|
|
67
|
+
before_agent = ""
|
|
68
|
+
after_agent = ""
|
|
69
|
+
if agent.agent_type != "swarm" or not isinstance(agent, WaldiezSwarmAgent):
|
|
70
|
+
return args_string, before_agent, after_agent
|
|
71
|
+
args_string = get_function_arg(agent, skill_names)
|
|
72
|
+
before_reply = get_update_agent_state_before_reply_arg(
|
|
73
|
+
agent=agent,
|
|
74
|
+
agent_names=agent_names,
|
|
75
|
+
skill_names=skill_names,
|
|
76
|
+
string_escape=string_escape,
|
|
77
|
+
)
|
|
78
|
+
args_string += before_reply[0]
|
|
79
|
+
before_agent += before_reply[1]
|
|
80
|
+
before_registration, after_agent = get_agent_handoff_registrations(
|
|
81
|
+
agent=agent,
|
|
82
|
+
agent_names=agent_names,
|
|
83
|
+
all_chats=chats[0],
|
|
84
|
+
chat_names=chats[1],
|
|
85
|
+
is_async=is_async,
|
|
86
|
+
serializer=serializer,
|
|
87
|
+
string_escape=string_escape,
|
|
88
|
+
)
|
|
89
|
+
before_agent += before_registration
|
|
90
|
+
return before_agent, args_string, after_agent
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_function_arg(
|
|
94
|
+
agent: WaldiezSwarmAgent,
|
|
95
|
+
skill_names: Dict[str, str],
|
|
96
|
+
) -> str:
|
|
97
|
+
"""Get the function argument of a swarm agent.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
agent : WaldiezSwarmAgent
|
|
102
|
+
The swarm agent to get the function argument for.
|
|
103
|
+
skill_names : Dict[str, str]
|
|
104
|
+
A mapping of skill IDs to skill names.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
str
|
|
109
|
+
The function argument of the swarm agent.
|
|
110
|
+
"""
|
|
111
|
+
tab = " "
|
|
112
|
+
arg_string = f"{tab}functions=["
|
|
113
|
+
added_skills = False
|
|
114
|
+
for function in agent.data.functions:
|
|
115
|
+
skill_name = skill_names.get(function, "")
|
|
116
|
+
if skill_name:
|
|
117
|
+
arg_string += "\n" + f"{tab}{tab}{skill_name},"
|
|
118
|
+
added_skills = True
|
|
119
|
+
if added_skills:
|
|
120
|
+
arg_string += "\n" + tab
|
|
121
|
+
arg_string += "],\n"
|
|
122
|
+
return arg_string
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def get_update_agent_state_before_reply_arg(
|
|
126
|
+
agent: WaldiezSwarmAgent,
|
|
127
|
+
agent_names: Dict[str, str],
|
|
128
|
+
skill_names: Dict[str, str],
|
|
129
|
+
string_escape: Callable[[str], str],
|
|
130
|
+
) -> Tuple[str, str]:
|
|
131
|
+
"""Get the update_agent_state_before_reply argument of a swarm agent.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
agent : WaldiezSwarmAgent
|
|
136
|
+
The swarm agent to get the argument for.
|
|
137
|
+
agent_names : Dict[str, str]
|
|
138
|
+
A mapping of agent IDs to agent names.
|
|
139
|
+
skill_names : Dict[str, str]
|
|
140
|
+
A mapping of skill IDs to skill names.
|
|
141
|
+
string_escape : Callable[[str], str]
|
|
142
|
+
The function to escape the string quotes and newlines.
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
Tuple[str, str]
|
|
147
|
+
The update_agent_state_before_reply argument of the swarm agent
|
|
148
|
+
and the content before the agent if any.
|
|
149
|
+
"""
|
|
150
|
+
# update_function_type : Literal["string", "callable"]
|
|
151
|
+
# The type of the update function. Can be either a string or a callable.
|
|
152
|
+
# update_function : str
|
|
153
|
+
# "The string template or function definition to update "
|
|
154
|
+
# "the agent's system message. Can be a string or a Callable. "
|
|
155
|
+
# "If the function_type is 'string' it will be used as a "
|
|
156
|
+
# "template and substitute the context variables. "
|
|
157
|
+
# ag2 checks for: vars = re.findall(r"\{(\w+)\}", function)
|
|
158
|
+
# "If function_type is 'callable', it should have signature:
|
|
159
|
+
# "def custom_update_system_message("
|
|
160
|
+
# " agent: ConversableAgent, "
|
|
161
|
+
# " messages: List[Dict[str, Any]]
|
|
162
|
+
# ) -> str"
|
|
163
|
+
tab = " "
|
|
164
|
+
before_agent = ""
|
|
165
|
+
arg_string = f"{tab}update_agent_state_before_reply=["
|
|
166
|
+
added_functions = False
|
|
167
|
+
# pylint: disable=line-too-long
|
|
168
|
+
for function in agent.data.update_agent_state_before_reply:
|
|
169
|
+
if isinstance(function, WaldiezSwarmUpdateSystemMessage):
|
|
170
|
+
added_functions = True
|
|
171
|
+
if function.update_function_type == "callable":
|
|
172
|
+
function_content, function_name = function.get_update_function(
|
|
173
|
+
name_suffix=agent_names[agent.id],
|
|
174
|
+
)
|
|
175
|
+
arg_string += (
|
|
176
|
+
"\n" + f"{tab}{tab}UPDATE_SYSTEM_MESSAGE({function_name}),"
|
|
177
|
+
)
|
|
178
|
+
before_agent += "\n" + function_content + "\n"
|
|
179
|
+
else:
|
|
180
|
+
escaped_function = string_escape(function.update_function)
|
|
181
|
+
arg_string += (
|
|
182
|
+
"\n"
|
|
183
|
+
+ f'{tab}{tab}UPDATE_SYSTEM_MESSAGE("{escaped_function}"),'
|
|
184
|
+
)
|
|
185
|
+
else:
|
|
186
|
+
skill_name = skill_names.get(function, "")
|
|
187
|
+
if skill_name:
|
|
188
|
+
added_functions = True
|
|
189
|
+
arg_string += "\n" + f"{tab}{tab}{skill_name},"
|
|
190
|
+
if added_functions:
|
|
191
|
+
arg_string = arg_string + "\n" + tab
|
|
192
|
+
arg_string += "],\n"
|
|
193
|
+
return arg_string, before_agent
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def get_agent_handoff_registrations(
|
|
197
|
+
agent: WaldiezSwarmAgent,
|
|
198
|
+
agent_names: Dict[str, str],
|
|
199
|
+
all_chats: List[WaldiezChat],
|
|
200
|
+
chat_names: Dict[str, str],
|
|
201
|
+
is_async: bool,
|
|
202
|
+
serializer: Callable[..., str],
|
|
203
|
+
string_escape: Callable[[str], str],
|
|
204
|
+
) -> Tuple[str, str]:
|
|
205
|
+
"""Get the agent handoff registrations of a swarm agent.
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
agent : WaldiezSwarmAgent
|
|
210
|
+
The swarm agent to get the agent handoff registrations for.
|
|
211
|
+
agent_names : Dict[str, str]
|
|
212
|
+
A mapping of agent IDs to agent names.
|
|
213
|
+
all_chats : List[WaldiezChat]
|
|
214
|
+
The list of all chats.
|
|
215
|
+
chat_names : Dict[str, str]
|
|
216
|
+
A mapping of chat IDs to chat names.
|
|
217
|
+
is_async : bool
|
|
218
|
+
Whether the chat is asynchronous.
|
|
219
|
+
serializer : Callable[..., str]
|
|
220
|
+
The serializer to get the string representation of an object.
|
|
221
|
+
string_escape : Callable[[str], str]
|
|
222
|
+
The function to escape the string quotes and newlines.
|
|
223
|
+
|
|
224
|
+
Returns
|
|
225
|
+
-------
|
|
226
|
+
Tuple[str, str]
|
|
227
|
+
the contents before and after the agent.
|
|
228
|
+
"""
|
|
229
|
+
agent_name = agent_names[agent.id]
|
|
230
|
+
registrations = []
|
|
231
|
+
before_agent = ""
|
|
232
|
+
after_agent = ""
|
|
233
|
+
if not agent.handoffs:
|
|
234
|
+
return before_agent, after_agent
|
|
235
|
+
tab = " "
|
|
236
|
+
after_agent = f"{agent_name}.register_hand_off(" + "\n" + f"{tab}[" + "\n"
|
|
237
|
+
for hand_off in agent.handoffs:
|
|
238
|
+
if isinstance(hand_off, WaldiezSwarmOnCondition):
|
|
239
|
+
registration, before_handoff = get_agent_on_condition_handoff(
|
|
240
|
+
agent=agent,
|
|
241
|
+
hand_off=hand_off,
|
|
242
|
+
agent_names=agent_names,
|
|
243
|
+
all_chats=all_chats,
|
|
244
|
+
chat_names=chat_names,
|
|
245
|
+
is_async=is_async,
|
|
246
|
+
serializer=serializer,
|
|
247
|
+
string_escape=string_escape,
|
|
248
|
+
)
|
|
249
|
+
if registration:
|
|
250
|
+
registrations.append(registration)
|
|
251
|
+
before_agent += before_handoff
|
|
252
|
+
elif isinstance(hand_off, WaldiezSwarmAfterWork):
|
|
253
|
+
registration, before_handoff = get_agent_after_work_handoff(
|
|
254
|
+
hand_off=hand_off,
|
|
255
|
+
agent_names=agent_names,
|
|
256
|
+
agent_name=agent_name,
|
|
257
|
+
)
|
|
258
|
+
registrations.append(registration)
|
|
259
|
+
before_agent += before_handoff
|
|
260
|
+
after_agent += "\n".join(registrations) + "\n" + f"{tab}]" + "\n" + ")"
|
|
261
|
+
return before_agent, after_agent
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def get_agent_after_work_handoff(
|
|
265
|
+
hand_off: WaldiezSwarmAfterWork,
|
|
266
|
+
agent_names: Dict[str, str],
|
|
267
|
+
agent_name: str,
|
|
268
|
+
) -> Tuple[str, str]:
|
|
269
|
+
"""Get the agent's after work hand off registration.
|
|
270
|
+
|
|
271
|
+
Parameters
|
|
272
|
+
----------
|
|
273
|
+
hand_off : WaldiezSwarmAfterWork
|
|
274
|
+
The hand off to get the registration for.
|
|
275
|
+
agent_names : Dict[str, str]
|
|
276
|
+
A mapping of agent IDs to agent names.
|
|
277
|
+
agent_name : str
|
|
278
|
+
The name of the agent to register the hand off.
|
|
279
|
+
|
|
280
|
+
Returns
|
|
281
|
+
-------
|
|
282
|
+
Tuple[str, str]
|
|
283
|
+
The registration and the content before the agent.
|
|
284
|
+
"""
|
|
285
|
+
before_agent = ""
|
|
286
|
+
tab = " "
|
|
287
|
+
recipient_type = hand_off.recipient_type
|
|
288
|
+
recipient, function_content = hand_off.get_recipient(
|
|
289
|
+
agent_names=agent_names,
|
|
290
|
+
name_suffix=agent_name,
|
|
291
|
+
)
|
|
292
|
+
registration = f"{tab}{tab}{recipient},"
|
|
293
|
+
if recipient_type == "callable" and function_content:
|
|
294
|
+
before_agent += "\n" + function_content + "\n"
|
|
295
|
+
return registration, before_agent
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def get_agent_on_condition_handoff(
|
|
299
|
+
agent: WaldiezSwarmAgent,
|
|
300
|
+
hand_off: WaldiezSwarmOnCondition,
|
|
301
|
+
agent_names: Dict[str, str],
|
|
302
|
+
all_chats: List[WaldiezChat],
|
|
303
|
+
chat_names: Dict[str, str],
|
|
304
|
+
is_async: bool,
|
|
305
|
+
serializer: Callable[..., str],
|
|
306
|
+
string_escape: Callable[[str], str],
|
|
307
|
+
) -> Tuple[str, str]:
|
|
308
|
+
"""Get the agent's on condition hand off registration.
|
|
309
|
+
|
|
310
|
+
Parameters
|
|
311
|
+
----------
|
|
312
|
+
agent : WaldiezSwarmAgent
|
|
313
|
+
The agent to get the registration for.
|
|
314
|
+
hand_off : WaldiezSwarmAfterWork
|
|
315
|
+
The hand off to get the registration for.
|
|
316
|
+
agent_names : Dict[str, str]
|
|
317
|
+
A mapping of agent IDs to agent names.
|
|
318
|
+
all_chats : List[WaldiezChat]
|
|
319
|
+
The list of all chats.
|
|
320
|
+
chat_names : Dict[str, str]
|
|
321
|
+
A mapping of chat IDs to chat names.
|
|
322
|
+
is_async : bool
|
|
323
|
+
Whether the chat is asynchronous.
|
|
324
|
+
serializer : Callable[..., str]
|
|
325
|
+
The serializer to get the string representation of an object.
|
|
326
|
+
string_escape : Callable[[str], str]
|
|
327
|
+
The function to escape the string quotes and newlines.
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
Tuple[str, str]
|
|
332
|
+
The registration and the content before the agent.
|
|
333
|
+
"""
|
|
334
|
+
before_agent = ""
|
|
335
|
+
registration = ""
|
|
336
|
+
available, available_function = hand_off.get_available(
|
|
337
|
+
name_suffix=agent_names[agent.id],
|
|
338
|
+
)
|
|
339
|
+
if available and not available_function:
|
|
340
|
+
available = f'"{string_escape(available)}"'
|
|
341
|
+
if hand_off.target_type == "agent":
|
|
342
|
+
recipient = agent_names[hand_off.target.id]
|
|
343
|
+
condition = (
|
|
344
|
+
string_escape(hand_off.condition) or f"Transfer to {recipient}"
|
|
345
|
+
)
|
|
346
|
+
results = _get_agent_on_condition_handoff_to_agent(
|
|
347
|
+
recipient=recipient,
|
|
348
|
+
available=available,
|
|
349
|
+
condition=condition,
|
|
350
|
+
available_function=available_function,
|
|
351
|
+
)
|
|
352
|
+
before_agent += results[0]
|
|
353
|
+
registration = results[1]
|
|
354
|
+
# else: # target_type == "nested_chat"
|
|
355
|
+
if hand_off.target_type == "nested_chat":
|
|
356
|
+
condition = _get_condition_string(
|
|
357
|
+
condition=hand_off.condition,
|
|
358
|
+
chat_id=hand_off.target.id,
|
|
359
|
+
all_chats=all_chats,
|
|
360
|
+
agent_names=agent_names,
|
|
361
|
+
)
|
|
362
|
+
results = _get_agent_on_condition_handoff_to_nested_chat(
|
|
363
|
+
agent=agent,
|
|
364
|
+
agent_names=agent_names,
|
|
365
|
+
condition=hand_off.condition,
|
|
366
|
+
available=available,
|
|
367
|
+
available_function=available_function,
|
|
368
|
+
all_chats=all_chats,
|
|
369
|
+
chat_names=chat_names,
|
|
370
|
+
is_async=is_async,
|
|
371
|
+
serializer=serializer,
|
|
372
|
+
string_escape=string_escape,
|
|
373
|
+
)
|
|
374
|
+
before_agent += results[0]
|
|
375
|
+
registration = results[1]
|
|
376
|
+
return registration, before_agent
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def _get_agent_on_condition_handoff_to_agent(
|
|
380
|
+
recipient: str,
|
|
381
|
+
available: str,
|
|
382
|
+
condition: str,
|
|
383
|
+
available_function: str,
|
|
384
|
+
) -> Tuple[str, str]:
|
|
385
|
+
before_agent = ""
|
|
386
|
+
tab = " "
|
|
387
|
+
on_condition = (
|
|
388
|
+
f"{tab}{tab}ON_CONDITION(" + "\n"
|
|
389
|
+
f"{tab}{tab}{tab}target={recipient}," + "\n"
|
|
390
|
+
f'{tab}{tab}{tab}condition="{condition}",' + "\n"
|
|
391
|
+
)
|
|
392
|
+
if available:
|
|
393
|
+
on_condition += f"{tab}{tab}{tab}available={available}," + "\n"
|
|
394
|
+
if available_function:
|
|
395
|
+
before_agent += "\n" + available_function + "\n"
|
|
396
|
+
on_condition += f"{tab}{tab}),"
|
|
397
|
+
return before_agent, on_condition
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
# pylint: disable=too-many-locals
|
|
401
|
+
def _get_agent_on_condition_handoff_to_nested_chat(
|
|
402
|
+
agent: WaldiezAgent,
|
|
403
|
+
agent_names: Dict[str, str],
|
|
404
|
+
condition: str,
|
|
405
|
+
available: str,
|
|
406
|
+
available_function: str,
|
|
407
|
+
all_chats: List[WaldiezChat],
|
|
408
|
+
chat_names: Dict[str, str],
|
|
409
|
+
is_async: bool,
|
|
410
|
+
serializer: Callable[..., str],
|
|
411
|
+
string_escape: Callable[[str], str],
|
|
412
|
+
) -> Tuple[str, str]:
|
|
413
|
+
if not agent.data.nested_chats or not agent.data.nested_chats[0].messages:
|
|
414
|
+
return "", ""
|
|
415
|
+
chat_queue, extra_methods = get_nested_chat_queue(
|
|
416
|
+
nested_chat=agent.data.nested_chats[0],
|
|
417
|
+
agent=agent,
|
|
418
|
+
agent_names=agent_names,
|
|
419
|
+
chat_names=chat_names,
|
|
420
|
+
all_chats=all_chats,
|
|
421
|
+
serializer=serializer,
|
|
422
|
+
string_escape=string_escape,
|
|
423
|
+
)
|
|
424
|
+
if not chat_queue:
|
|
425
|
+
return "", ""
|
|
426
|
+
before_agent = ""
|
|
427
|
+
tab = " "
|
|
428
|
+
chat_queue_var_name = f"{agent_names[agent.id]}_handoff_nested_chat_queue"
|
|
429
|
+
if extra_methods:
|
|
430
|
+
before_agent += "\n".join(extra_methods) + "\n"
|
|
431
|
+
before_agent += f"{chat_queue_var_name} = {chat_queue} " + "\n"
|
|
432
|
+
condition_string = string_escape(condition)
|
|
433
|
+
on_condition = (
|
|
434
|
+
f"{tab}{tab}ON_CONDITION(" + "\n"
|
|
435
|
+
f"{tab}{tab}{tab}target=" + "{\n"
|
|
436
|
+
f'{tab}{tab}{tab}{tab}"chat_queue": {chat_queue_var_name},' + "\n"
|
|
437
|
+
f'{tab}{tab}{tab}{tab}"config": None,' + "\n"
|
|
438
|
+
f'{tab}{tab}{tab}{tab}"reply_func_from_nested_chats": None,' + "\n"
|
|
439
|
+
f'{tab}{tab}{tab}{tab}"use_async": {is_async},' + "\n"
|
|
440
|
+
f"{tab}{tab}{tab}" + "},\n"
|
|
441
|
+
f'{tab}{tab}{tab}condition="{condition_string}",' + "\n"
|
|
442
|
+
)
|
|
443
|
+
if available:
|
|
444
|
+
on_condition += f"{tab}{tab}{tab}available={available}," + "\n"
|
|
445
|
+
if available_function:
|
|
446
|
+
before_agent += "\n" + available_function + "\n"
|
|
447
|
+
on_condition += f"{tab}{tab}),"
|
|
448
|
+
return before_agent, on_condition
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def _get_condition_string(
|
|
452
|
+
condition: str,
|
|
453
|
+
chat_id: str,
|
|
454
|
+
all_chats: List[WaldiezChat],
|
|
455
|
+
agent_names: Dict[str, str],
|
|
456
|
+
) -> str:
|
|
457
|
+
if not condition:
|
|
458
|
+
chat = next((c for c in all_chats if c.id == chat_id), None)
|
|
459
|
+
if chat:
|
|
460
|
+
target_name = agent_names[chat.target]
|
|
461
|
+
return f"Transfer to {target_name}"
|
|
462
|
+
return "Transfer to the next agent"
|
|
463
|
+
return condition
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
1
3
|
"""Exporting teachability data for agents."""
|
|
2
4
|
|
|
3
5
|
from typing import Dict
|
|
@@ -23,15 +25,17 @@ def get_agent_teachability_string(
|
|
|
23
25
|
str
|
|
24
26
|
The teachability string
|
|
25
27
|
"""
|
|
26
|
-
if not agent.data.teachability.enabled:
|
|
28
|
+
if not agent.data.teachability or not agent.data.teachability.enabled:
|
|
27
29
|
return ""
|
|
28
30
|
agent_name = agent_names[agent.id]
|
|
29
31
|
teachability = agent.data.teachability
|
|
30
|
-
content = f"{agent_name}_teachability = teachability.Teachability(\n"
|
|
31
|
-
content += f" verbosity={teachability.verbosity}
|
|
32
|
-
content += f" reset_db={teachability.reset_db}
|
|
33
|
-
content += f" recall_threshold={teachability.recall_threshold}
|
|
34
|
-
content +=
|
|
32
|
+
content = f"{agent_name}_teachability = teachability.Teachability(" + "\n"
|
|
33
|
+
content += f" verbosity={teachability.verbosity}," + "\n"
|
|
34
|
+
content += f" reset_db={teachability.reset_db}," + "\n"
|
|
35
|
+
content += f" recall_threshold={teachability.recall_threshold}," + "\n"
|
|
36
|
+
content += (
|
|
37
|
+
f" max_num_retrievals={teachability.max_num_retrievals}," + "\n"
|
|
38
|
+
)
|
|
35
39
|
content += ")\n\n\n"
|
|
36
40
|
content += f"{agent_name}_teachability.add_to_agent({agent_name})"
|
|
37
41
|
return content
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
1
3
|
"""Get the `is_termination_message` check for the agent."""
|
|
2
4
|
|
|
3
5
|
from typing import Tuple
|
|
@@ -33,13 +35,10 @@ def get_is_termination_message(
|
|
|
33
35
|
if agent.data.termination.type == "keyword":
|
|
34
36
|
return agent.data.termination.string, ""
|
|
35
37
|
if agent.data.termination.type == "method":
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
+ "\n"
|
|
41
|
-
+ f"{agent.data.termination.string}"
|
|
42
|
-
+ "\n\n"
|
|
38
|
+
content, function_name = (
|
|
39
|
+
agent.data.termination.get_termination_function(
|
|
40
|
+
name_suffix=agent_name
|
|
41
|
+
)
|
|
43
42
|
)
|
|
44
|
-
return
|
|
43
|
+
return function_name, "\n\n" + content + "\n"
|
|
45
44
|
raise ValueError(f"Invalid termination type: {agent.data.termination.type}")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Base classes, mixins, and utilities for exporting data.
|
|
4
|
+
|
|
5
|
+
Each exporter should inherit from the `BaseExporter` class and implement the
|
|
6
|
+
`export` method. The `export` method should return the exported content as an
|
|
7
|
+
instance of the `ExporterReturnType` typed dictionary.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .agent_position import AgentPosition, AgentPositions
|
|
11
|
+
from .base_exporter import BaseExporter, ExporterReturnType
|
|
12
|
+
from .export_position import ExportPosition, ExportPositions
|
|
13
|
+
from .import_position import ImportPosition
|
|
14
|
+
from .mixin import ExporterMixin
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"AgentPosition",
|
|
18
|
+
"AgentPositions",
|
|
19
|
+
"BaseExporter",
|
|
20
|
+
"ExporterMixin",
|
|
21
|
+
"ExportPosition",
|
|
22
|
+
"ExportPositions",
|
|
23
|
+
"ExporterReturnType",
|
|
24
|
+
"ImportPosition",
|
|
25
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Agent position generation."""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
from waldiez.models import WaldiezAgent
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AgentPositions(Enum):
|
|
13
|
+
"""Agent positions.
|
|
14
|
+
|
|
15
|
+
Attributes
|
|
16
|
+
----------
|
|
17
|
+
BEFORE_ALL: int
|
|
18
|
+
Before all agents.
|
|
19
|
+
BEFORE: int
|
|
20
|
+
Before the agent.
|
|
21
|
+
AS_ARGUMENT: int
|
|
22
|
+
As an argument of the agent's initialization.
|
|
23
|
+
AFTER: int
|
|
24
|
+
After the agent.
|
|
25
|
+
AFTER_ALL: int
|
|
26
|
+
After all agents.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
BEFORE_ALL = 0
|
|
30
|
+
BEFORE = 1
|
|
31
|
+
AS_ARGUMENT = 2
|
|
32
|
+
AFTER = 3
|
|
33
|
+
AFTER_ALL = 4
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
POSITIONS_WITHOUT_AGENT = [
|
|
37
|
+
AgentPositions.BEFORE_ALL,
|
|
38
|
+
AgentPositions.AFTER_ALL,
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(order=True, frozen=True, slots=True)
|
|
43
|
+
class AgentPosition:
|
|
44
|
+
"""Agent position.
|
|
45
|
+
|
|
46
|
+
Attributes
|
|
47
|
+
----------
|
|
48
|
+
agent: Optional[WaldiezAgent]
|
|
49
|
+
The agent.
|
|
50
|
+
position: AgentPositions
|
|
51
|
+
The position.
|
|
52
|
+
order: int
|
|
53
|
+
The order of the agent position.
|
|
54
|
+
|
|
55
|
+
Raises
|
|
56
|
+
------
|
|
57
|
+
ValueError
|
|
58
|
+
If the position is not "BEFORE_ALL" or "AFTER_ALL"
|
|
59
|
+
and the agent is not provided.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
agent: Optional[WaldiezAgent]
|
|
63
|
+
position: AgentPositions
|
|
64
|
+
order: int = 0
|
|
65
|
+
|
|
66
|
+
def __post_init__(self) -> None:
|
|
67
|
+
"""Post initialization.
|
|
68
|
+
|
|
69
|
+
Raises
|
|
70
|
+
------
|
|
71
|
+
ValueError
|
|
72
|
+
If the agent is not provided for the given position.
|
|
73
|
+
"""
|
|
74
|
+
if self.agent is None and self.position not in POSITIONS_WITHOUT_AGENT:
|
|
75
|
+
raise ValueError("Agent must be provided for the given position.")
|