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.
- waldiez/__init__.py +5 -5
- waldiez/_version.py +1 -1
- waldiez/cli.py +97 -102
- waldiez/exporter.py +61 -19
- waldiez/exporting/__init__.py +25 -6
- waldiez/exporting/agent/__init__.py +7 -3
- waldiez/exporting/agent/code_execution.py +114 -0
- waldiez/exporting/agent/exporter.py +354 -0
- waldiez/exporting/agent/extras/__init__.py +15 -0
- waldiez/exporting/agent/extras/captain_agent_extras.py +315 -0
- waldiez/exporting/agent/extras/group/target.py +178 -0
- waldiez/exporting/agent/extras/group_manager_agent_extas.py +500 -0
- waldiez/exporting/agent/extras/group_member_extras.py +181 -0
- waldiez/exporting/agent/extras/handoffs/__init__.py +19 -0
- waldiez/exporting/agent/extras/handoffs/after_work.py +78 -0
- waldiez/exporting/agent/extras/handoffs/available.py +74 -0
- waldiez/exporting/agent/extras/handoffs/condition.py +158 -0
- waldiez/exporting/agent/extras/handoffs/handoff.py +171 -0
- waldiez/exporting/agent/extras/handoffs/target.py +189 -0
- waldiez/exporting/agent/extras/rag/__init__.py +10 -0
- waldiez/exporting/agent/{utils/rag_user/chroma_utils.py → extras/rag/chroma_extras.py} +37 -24
- waldiez/exporting/agent/{utils/rag_user/mongo_utils.py → extras/rag/mongo_extras.py} +10 -10
- waldiez/exporting/agent/{utils/rag_user/pgvector_utils.py → extras/rag/pgvector_extras.py} +13 -13
- waldiez/exporting/agent/{utils/rag_user/qdrant_utils.py → extras/rag/qdrant_extras.py} +13 -13
- waldiez/exporting/agent/{utils/rag_user/vector_db.py → extras/rag/vector_db_extras.py} +59 -46
- waldiez/exporting/agent/extras/rag_user_proxy_agent_extras.py +245 -0
- waldiez/exporting/agent/extras/reasoning_agent_extras.py +88 -0
- waldiez/exporting/agent/factory.py +95 -0
- waldiez/exporting/agent/processor.py +150 -0
- waldiez/exporting/agent/system_message.py +36 -0
- waldiez/exporting/agent/termination.py +50 -0
- waldiez/exporting/chats/__init__.py +7 -3
- waldiez/exporting/chats/exporter.py +97 -0
- waldiez/exporting/chats/factory.py +65 -0
- waldiez/exporting/chats/processor.py +226 -0
- waldiez/exporting/chats/utils/__init__.py +6 -5
- waldiez/exporting/chats/utils/common.py +11 -45
- waldiez/exporting/chats/utils/group.py +55 -0
- waldiez/exporting/chats/utils/nested.py +37 -52
- waldiez/exporting/chats/utils/sequential.py +72 -61
- waldiez/exporting/chats/utils/{single_chat.py → single.py} +48 -50
- waldiez/exporting/core/__init__.py +196 -0
- waldiez/exporting/core/constants.py +17 -0
- waldiez/exporting/core/content.py +69 -0
- waldiez/exporting/core/context.py +244 -0
- waldiez/exporting/core/enums.py +89 -0
- waldiez/exporting/core/errors.py +19 -0
- waldiez/exporting/core/exporter.py +390 -0
- waldiez/exporting/core/exporters.py +67 -0
- waldiez/exporting/core/extras/__init__.py +39 -0
- waldiez/exporting/core/extras/agent_extras/__init__.py +27 -0
- waldiez/exporting/core/extras/agent_extras/captain_extras.py +57 -0
- waldiez/exporting/core/extras/agent_extras/group_manager_extras.py +102 -0
- waldiez/exporting/core/extras/agent_extras/rag_user_extras.py +53 -0
- waldiez/exporting/core/extras/agent_extras/reasoning_extras.py +68 -0
- waldiez/exporting/core/extras/agent_extras/standard_extras.py +263 -0
- waldiez/exporting/core/extras/base.py +241 -0
- waldiez/exporting/core/extras/chat_extras.py +118 -0
- waldiez/exporting/core/extras/flow_extras.py +70 -0
- waldiez/exporting/core/extras/model_extras.py +73 -0
- waldiez/exporting/core/extras/path_resolver.py +93 -0
- waldiez/exporting/core/extras/serializer.py +138 -0
- waldiez/exporting/core/extras/tool_extras.py +82 -0
- waldiez/exporting/core/protocols.py +259 -0
- waldiez/exporting/core/result.py +705 -0
- waldiez/exporting/core/types.py +329 -0
- waldiez/exporting/core/utils/__init__.py +11 -0
- waldiez/exporting/core/utils/comment.py +33 -0
- waldiez/exporting/core/utils/llm_config.py +117 -0
- waldiez/exporting/core/validation.py +96 -0
- waldiez/exporting/flow/__init__.py +6 -2
- waldiez/exporting/flow/execution_generator.py +193 -0
- waldiez/exporting/flow/exporter.py +107 -0
- waldiez/exporting/flow/factory.py +94 -0
- waldiez/exporting/flow/file_generator.py +214 -0
- waldiez/exporting/flow/merger.py +387 -0
- waldiez/exporting/flow/orchestrator.py +411 -0
- waldiez/exporting/flow/utils/__init__.py +9 -36
- waldiez/exporting/flow/utils/common.py +206 -0
- waldiez/exporting/flow/utils/importing.py +373 -0
- waldiez/exporting/flow/utils/linting.py +200 -0
- waldiez/exporting/flow/utils/{logging_utils.py → logging.py} +23 -9
- waldiez/exporting/models/__init__.py +3 -1
- waldiez/exporting/models/exporter.py +233 -0
- waldiez/exporting/models/factory.py +66 -0
- waldiez/exporting/models/processor.py +139 -0
- waldiez/exporting/tools/__init__.py +11 -0
- waldiez/exporting/tools/exporter.py +207 -0
- waldiez/exporting/tools/factory.py +57 -0
- waldiez/exporting/tools/processor.py +248 -0
- waldiez/exporting/tools/registration.py +133 -0
- waldiez/io/__init__.py +128 -0
- waldiez/io/_ws.py +199 -0
- waldiez/io/models/__init__.py +60 -0
- waldiez/io/models/base.py +66 -0
- waldiez/io/models/constants.py +78 -0
- waldiez/io/models/content/__init__.py +23 -0
- waldiez/io/models/content/audio.py +43 -0
- waldiez/io/models/content/base.py +45 -0
- waldiez/io/models/content/file.py +43 -0
- waldiez/io/models/content/image.py +96 -0
- waldiez/io/models/content/text.py +37 -0
- waldiez/io/models/content/video.py +43 -0
- waldiez/io/models/user_input.py +269 -0
- waldiez/io/models/user_response.py +215 -0
- waldiez/io/mqtt.py +681 -0
- waldiez/io/redis.py +782 -0
- waldiez/io/structured.py +439 -0
- waldiez/io/utils.py +184 -0
- waldiez/io/ws.py +298 -0
- waldiez/logger.py +481 -0
- waldiez/models/__init__.py +108 -51
- waldiez/models/agents/__init__.py +34 -70
- waldiez/models/agents/agent/__init__.py +10 -4
- waldiez/models/agents/agent/agent.py +466 -65
- waldiez/models/agents/agent/agent_data.py +119 -47
- waldiez/models/agents/agent/agent_type.py +13 -2
- waldiez/models/agents/agent/code_execution.py +12 -12
- waldiez/models/agents/agent/human_input_mode.py +8 -0
- waldiez/models/agents/agent/{linked_skill.py → linked_tool.py} +7 -7
- waldiez/models/agents/agent/nested_chat.py +35 -7
- waldiez/models/agents/agent/termination_message.py +30 -22
- waldiez/models/agents/{swarm_agent → agent}/update_system_message.py +22 -22
- waldiez/models/agents/agents.py +58 -63
- waldiez/models/agents/assistant/assistant.py +4 -4
- waldiez/models/agents/assistant/assistant_data.py +13 -1
- waldiez/models/agents/{captain_agent → captain}/captain_agent.py +5 -5
- waldiez/models/agents/{captain_agent → captain}/captain_agent_data.py +5 -5
- waldiez/models/agents/extra_requirements.py +11 -16
- waldiez/models/agents/group_manager/group_manager.py +103 -13
- waldiez/models/agents/group_manager/group_manager_data.py +36 -14
- waldiez/models/agents/group_manager/speakers.py +77 -24
- waldiez/models/agents/{rag_user → rag_user_proxy}/__init__.py +16 -16
- waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +64 -0
- waldiez/models/agents/{rag_user/rag_user_data.py → rag_user_proxy/rag_user_proxy_data.py} +6 -5
- waldiez/models/agents/{rag_user → rag_user_proxy}/retrieve_config.py +182 -114
- waldiez/models/agents/{rag_user → rag_user_proxy}/vector_db_config.py +13 -13
- waldiez/models/agents/reasoning/reasoning_agent.py +6 -6
- waldiez/models/agents/reasoning/reasoning_agent_data.py +110 -63
- waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +38 -10
- waldiez/models/agents/user_proxy/user_proxy.py +11 -7
- waldiez/models/agents/user_proxy/user_proxy_data.py +2 -2
- waldiez/models/chat/__init__.py +2 -1
- waldiez/models/chat/chat.py +166 -87
- waldiez/models/chat/chat_data.py +99 -136
- waldiez/models/chat/chat_message.py +33 -23
- waldiez/models/chat/chat_nested.py +31 -30
- waldiez/models/chat/chat_summary.py +10 -8
- waldiez/models/common/__init__.py +52 -2
- waldiez/models/common/ag2_version.py +1 -1
- waldiez/models/common/base.py +38 -7
- waldiez/models/common/dict_utils.py +42 -17
- waldiez/models/common/handoff.py +459 -0
- waldiez/models/common/id_generator.py +19 -0
- waldiez/models/common/method_utils.py +130 -68
- waldiez/{exporting/base/utils → models/common}/naming.py +38 -61
- waldiez/models/common/waldiez_version.py +37 -0
- waldiez/models/flow/__init__.py +9 -2
- waldiez/models/flow/connection.py +18 -0
- waldiez/models/flow/flow.py +311 -215
- waldiez/models/flow/flow_data.py +207 -40
- waldiez/models/flow/info.py +85 -0
- waldiez/models/flow/naming.py +131 -0
- waldiez/models/model/__init__.py +7 -1
- waldiez/models/model/extra_requirements.py +3 -12
- waldiez/models/model/model.py +76 -21
- waldiez/models/model/model_data.py +108 -20
- waldiez/models/tool/__init__.py +16 -0
- waldiez/models/tool/extra_requirements.py +36 -0
- waldiez/models/{skill/skill.py → tool/tool.py} +88 -88
- waldiez/models/tool/tool_data.py +51 -0
- waldiez/models/tool/tool_type.py +8 -0
- waldiez/models/waldiez.py +97 -80
- waldiez/runner.py +115 -61
- waldiez/running/__init__.py +13 -7
- waldiez/running/environment.py +49 -68
- waldiez/running/gen_seq_diagram.py +16 -14
- waldiez/running/post_run.py +119 -0
- waldiez/running/pre_run.py +149 -0
- waldiez/running/util.py +134 -0
- waldiez/utils/__init__.py +2 -4
- waldiez/utils/cli_extras/jupyter.py +5 -3
- waldiez/utils/cli_extras/runner.py +6 -4
- waldiez/utils/cli_extras/studio.py +6 -4
- waldiez/utils/conflict_checker.py +15 -9
- waldiez/utils/flaml_warnings.py +5 -5
- waldiez/utils/version.py +47 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/METADATA +235 -91
- waldiez-0.4.9.dist-info/RECORD +203 -0
- waldiez/exporting/agent/agent_exporter.py +0 -297
- waldiez/exporting/agent/utils/__init__.py +0 -23
- waldiez/exporting/agent/utils/captain_agent.py +0 -263
- waldiez/exporting/agent/utils/code_execution.py +0 -65
- waldiez/exporting/agent/utils/group_manager.py +0 -220
- waldiez/exporting/agent/utils/rag_user/__init__.py +0 -7
- waldiez/exporting/agent/utils/rag_user/rag_user.py +0 -209
- waldiez/exporting/agent/utils/reasoning.py +0 -36
- waldiez/exporting/agent/utils/swarm_agent.py +0 -469
- waldiez/exporting/agent/utils/teachability.py +0 -41
- waldiez/exporting/agent/utils/termination_message.py +0 -44
- waldiez/exporting/base/__init__.py +0 -25
- waldiez/exporting/base/agent_position.py +0 -75
- waldiez/exporting/base/base_exporter.py +0 -118
- waldiez/exporting/base/export_position.py +0 -48
- waldiez/exporting/base/import_position.py +0 -23
- waldiez/exporting/base/mixin.py +0 -137
- waldiez/exporting/base/utils/__init__.py +0 -18
- waldiez/exporting/base/utils/comments.py +0 -96
- waldiez/exporting/base/utils/path_check.py +0 -68
- waldiez/exporting/base/utils/to_string.py +0 -84
- waldiez/exporting/chats/chats_exporter.py +0 -240
- waldiez/exporting/chats/utils/swarm.py +0 -210
- waldiez/exporting/flow/flow_exporter.py +0 -528
- waldiez/exporting/flow/utils/agent_utils.py +0 -204
- waldiez/exporting/flow/utils/chat_utils.py +0 -71
- waldiez/exporting/flow/utils/def_main.py +0 -77
- waldiez/exporting/flow/utils/flow_content.py +0 -202
- waldiez/exporting/flow/utils/flow_names.py +0 -116
- waldiez/exporting/flow/utils/importing_utils.py +0 -227
- waldiez/exporting/models/models_exporter.py +0 -199
- waldiez/exporting/models/utils.py +0 -174
- waldiez/exporting/skills/__init__.py +0 -9
- waldiez/exporting/skills/skills_exporter.py +0 -176
- waldiez/exporting/skills/utils.py +0 -369
- waldiez/models/agents/agent/teachability.py +0 -70
- waldiez/models/agents/rag_user/rag_user.py +0 -60
- waldiez/models/agents/swarm_agent/__init__.py +0 -50
- waldiez/models/agents/swarm_agent/after_work.py +0 -179
- waldiez/models/agents/swarm_agent/on_condition.py +0 -105
- waldiez/models/agents/swarm_agent/on_condition_available.py +0 -142
- waldiez/models/agents/swarm_agent/on_condition_target.py +0 -40
- waldiez/models/agents/swarm_agent/swarm_agent.py +0 -107
- waldiez/models/agents/swarm_agent/swarm_agent_data.py +0 -124
- waldiez/models/flow/utils.py +0 -232
- waldiez/models/skill/__init__.py +0 -16
- waldiez/models/skill/extra_requirements.py +0 -36
- waldiez/models/skill/skill_data.py +0 -53
- waldiez/models/skill/skill_type.py +0 -8
- waldiez/running/running.py +0 -369
- waldiez/utils/pysqlite3_checker.py +0 -308
- waldiez/utils/rdps_checker.py +0 -122
- waldiez-0.4.7.dist-info/RECORD +0 -149
- /waldiez/models/agents/{captain_agent → captain}/__init__.py +0 -0
- /waldiez/models/agents/{captain_agent → captain}/captain_agent_lib_entry.py +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/WHEEL +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/entry_points.txt +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -2,19 +2,29 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
"""Base agent class to be inherited by all agents."""
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import warnings
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
6
7
|
|
|
7
|
-
from pydantic import Field
|
|
8
|
+
from pydantic import Field, field_validator
|
|
8
9
|
from typing_extensions import Annotated, Literal
|
|
9
10
|
|
|
10
|
-
from ...common import
|
|
11
|
+
from ...common import (
|
|
12
|
+
WaldiezBase,
|
|
13
|
+
WaldiezGroupOrNestedTarget,
|
|
14
|
+
WaldiezHandoff,
|
|
15
|
+
now,
|
|
16
|
+
)
|
|
11
17
|
from .agent_data import WaldiezAgentData
|
|
12
18
|
from .agent_type import WaldiezAgentType
|
|
13
19
|
from .code_execution import WaldiezAgentCodeExecutionConfig
|
|
20
|
+
from .nested_chat import WaldiezAgentNestedChat, WaldiezAgentNestedChatMessage
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from ...chat import WaldiezChat
|
|
14
24
|
|
|
15
25
|
|
|
16
26
|
class WaldiezAgent(WaldiezBase):
|
|
17
|
-
"""Waldiez Agent.
|
|
27
|
+
"""Waldiez Agent to be inherited by all other agents.
|
|
18
28
|
|
|
19
29
|
Attributes
|
|
20
30
|
----------
|
|
@@ -28,9 +38,9 @@ class WaldiezAgent(WaldiezBase):
|
|
|
28
38
|
The name of the agent.
|
|
29
39
|
description : str
|
|
30
40
|
The description of the agent.
|
|
31
|
-
tags :
|
|
41
|
+
tags : list[str]
|
|
32
42
|
Tags for this agent.
|
|
33
|
-
requirements :
|
|
43
|
+
requirements : list[str]
|
|
34
44
|
Python requirements for the agent.
|
|
35
45
|
created_at : str
|
|
36
46
|
The date and time when the agent was created.
|
|
@@ -42,9 +52,9 @@ class WaldiezAgent(WaldiezBase):
|
|
|
42
52
|
|
|
43
53
|
Functions
|
|
44
54
|
---------
|
|
45
|
-
|
|
46
|
-
Validate the
|
|
47
|
-
validate_linked_models(model_ids:
|
|
55
|
+
validate_linked_tools(tool_ids: list[str], agent_ids: list[str])
|
|
56
|
+
Validate the tools linked to the agent.
|
|
57
|
+
validate_linked_models(model_ids: list[str])
|
|
48
58
|
Validate the models linked to the agent.
|
|
49
59
|
"""
|
|
50
60
|
|
|
@@ -58,15 +68,15 @@ class WaldiezAgent(WaldiezBase):
|
|
|
58
68
|
title="Type",
|
|
59
69
|
description="The type of the 'node' in a graph.",
|
|
60
70
|
),
|
|
61
|
-
]
|
|
71
|
+
] = "agent"
|
|
62
72
|
agent_type: Annotated[
|
|
63
73
|
WaldiezAgentType,
|
|
64
74
|
Field(
|
|
65
75
|
...,
|
|
66
76
|
title="Agent type",
|
|
67
77
|
description=(
|
|
68
|
-
"The type of the agent:
|
|
69
|
-
"
|
|
78
|
+
"The type of the agent: user_proxy, assistant, group_manager, "
|
|
79
|
+
"rag_user_proxy or reasoning"
|
|
70
80
|
),
|
|
71
81
|
),
|
|
72
82
|
]
|
|
@@ -76,27 +86,27 @@ class WaldiezAgent(WaldiezBase):
|
|
|
76
86
|
description: Annotated[
|
|
77
87
|
str,
|
|
78
88
|
Field(
|
|
79
|
-
"Agent's description",
|
|
89
|
+
default="Agent's description",
|
|
80
90
|
title="Description",
|
|
81
91
|
description="The description of the agent",
|
|
82
92
|
),
|
|
83
|
-
]
|
|
93
|
+
] = "Agent's description"
|
|
84
94
|
tags: Annotated[
|
|
85
|
-
|
|
95
|
+
list[str],
|
|
86
96
|
Field(
|
|
87
97
|
title="Tags",
|
|
88
98
|
description="Tags of the agent",
|
|
89
99
|
default_factory=list,
|
|
90
100
|
),
|
|
91
|
-
]
|
|
101
|
+
] = []
|
|
92
102
|
requirements: Annotated[
|
|
93
|
-
|
|
103
|
+
list[str],
|
|
94
104
|
Field(
|
|
95
105
|
title="Requirements",
|
|
96
106
|
description="Python requirements for the agent",
|
|
97
107
|
default_factory=list,
|
|
98
108
|
),
|
|
99
|
-
]
|
|
109
|
+
] = []
|
|
100
110
|
created_at: Annotated[
|
|
101
111
|
str,
|
|
102
112
|
Field(
|
|
@@ -118,34 +128,195 @@ class WaldiezAgent(WaldiezBase):
|
|
|
118
128
|
Field(
|
|
119
129
|
title="Data",
|
|
120
130
|
description="The data (properties) of the agent",
|
|
121
|
-
default_factory=WaldiezAgentData,
|
|
131
|
+
default_factory=WaldiezAgentData, # pyright: ignore
|
|
122
132
|
),
|
|
123
133
|
]
|
|
124
134
|
|
|
135
|
+
_handoffs: Annotated[
|
|
136
|
+
list[WaldiezHandoff],
|
|
137
|
+
Field(
|
|
138
|
+
init=False, # this is not a field in the constructor
|
|
139
|
+
default_factory=list[WaldiezHandoff],
|
|
140
|
+
title="Handoffs",
|
|
141
|
+
description=(
|
|
142
|
+
"A list of handoffs (target ids) to register. "
|
|
143
|
+
"These are used to transfer control to another agent or chat."
|
|
144
|
+
),
|
|
145
|
+
),
|
|
146
|
+
] = []
|
|
147
|
+
|
|
148
|
+
_checked_nested_chats: Annotated[bool, Field(init=False, default=False)] = (
|
|
149
|
+
False
|
|
150
|
+
)
|
|
151
|
+
_checked_handoffs: Annotated[bool, Field(init=False, default=False)] = False
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def handoffs(self) -> list[WaldiezHandoff]:
|
|
155
|
+
"""Get the handoffs for this agent.
|
|
156
|
+
|
|
157
|
+
Returns
|
|
158
|
+
-------
|
|
159
|
+
list[WaldiezHandoff]
|
|
160
|
+
The list of handoffs for this agent.
|
|
161
|
+
|
|
162
|
+
Raises
|
|
163
|
+
------
|
|
164
|
+
RuntimeError
|
|
165
|
+
If handoffs have not been gathered yet.
|
|
166
|
+
"""
|
|
167
|
+
if not self._checked_handoffs:
|
|
168
|
+
raise RuntimeError(
|
|
169
|
+
"Handoffs have not been gathered yet. "
|
|
170
|
+
"Call gather_handoffs() first."
|
|
171
|
+
)
|
|
172
|
+
return self._handoffs
|
|
173
|
+
|
|
174
|
+
@field_validator("agent_type")
|
|
175
|
+
@classmethod
|
|
176
|
+
def validate_agent_type(cls, v: WaldiezAgentType) -> WaldiezAgentType:
|
|
177
|
+
"""Validate the agent type.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
v : WaldiezAgentType
|
|
182
|
+
The agent type.
|
|
183
|
+
|
|
184
|
+
Returns
|
|
185
|
+
-------
|
|
186
|
+
WaldiezAgentType
|
|
187
|
+
The validated agent type.
|
|
188
|
+
|
|
189
|
+
Raises
|
|
190
|
+
------
|
|
191
|
+
ValueError
|
|
192
|
+
If the agent type is not valid.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
def _get_warning_message(old_type: str, new_type: str) -> str:
|
|
196
|
+
return (
|
|
197
|
+
f"The agent type '{old_type}' is deprecated. "
|
|
198
|
+
f"Use '{new_type}' instead."
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
if v == "user":
|
|
202
|
+
warnings.warn(
|
|
203
|
+
_get_warning_message("user", "user_proxy"),
|
|
204
|
+
DeprecationWarning,
|
|
205
|
+
stacklevel=2,
|
|
206
|
+
)
|
|
207
|
+
return "user_proxy"
|
|
208
|
+
if v == "rag_user":
|
|
209
|
+
warnings.warn(
|
|
210
|
+
_get_warning_message("rag_user", "rag_user_proxy"),
|
|
211
|
+
DeprecationWarning,
|
|
212
|
+
stacklevel=2,
|
|
213
|
+
)
|
|
214
|
+
return "rag_user_proxy"
|
|
215
|
+
return v
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def is_group_member(self) -> bool:
|
|
219
|
+
"""Check if the agent is a group member.
|
|
220
|
+
|
|
221
|
+
Returns
|
|
222
|
+
-------
|
|
223
|
+
bool
|
|
224
|
+
True if the agent is a group member, False otherwise.
|
|
225
|
+
"""
|
|
226
|
+
return (
|
|
227
|
+
self.agent_type not in ("group_manager", "manager")
|
|
228
|
+
and self.data.parent_id is not None
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
@property
|
|
232
|
+
def is_captain(self) -> bool:
|
|
233
|
+
"""Check if the agent is a captain.
|
|
234
|
+
|
|
235
|
+
Returns
|
|
236
|
+
-------
|
|
237
|
+
bool
|
|
238
|
+
True if the agent is a captain, False otherwise.
|
|
239
|
+
"""
|
|
240
|
+
return self.agent_type == "captain"
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
def is_reasoning(self) -> bool:
|
|
244
|
+
"""Check if the agent is a reasoning agent.
|
|
245
|
+
|
|
246
|
+
Returns
|
|
247
|
+
-------
|
|
248
|
+
bool
|
|
249
|
+
True if the agent is a reasoning agent, False otherwise.
|
|
250
|
+
"""
|
|
251
|
+
return self.agent_type == "reasoning"
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def is_user(self) -> bool:
|
|
255
|
+
"""Check if the agent is a user.
|
|
256
|
+
|
|
257
|
+
Returns
|
|
258
|
+
-------
|
|
259
|
+
bool
|
|
260
|
+
True if the agent is a user, False otherwise.
|
|
261
|
+
"""
|
|
262
|
+
return self.agent_type in (
|
|
263
|
+
"user",
|
|
264
|
+
"user_proxy",
|
|
265
|
+
"rag_user",
|
|
266
|
+
"rag_user_proxy",
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def is_rag_user(self) -> bool:
|
|
271
|
+
"""Check if the agent is a RAG user.
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
bool
|
|
276
|
+
True if the agent is a RAG user, False otherwise.
|
|
277
|
+
"""
|
|
278
|
+
return self.agent_type in ("rag_user", "rag_user_proxy")
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def is_group_manager(self) -> bool:
|
|
282
|
+
"""Check if the agent is a group manager.
|
|
283
|
+
|
|
284
|
+
Returns
|
|
285
|
+
-------
|
|
286
|
+
bool
|
|
287
|
+
True if the agent is a group manager, False otherwise.
|
|
288
|
+
"""
|
|
289
|
+
return self.agent_type in ("group_manager", "manager")
|
|
290
|
+
|
|
125
291
|
@property
|
|
126
292
|
def ag2_class(self) -> str:
|
|
127
293
|
"""Return the AG2 class of the agent."""
|
|
128
294
|
class_name = "ConversableAgent"
|
|
129
|
-
if self.
|
|
130
|
-
|
|
295
|
+
if self.is_group_member:
|
|
296
|
+
if (
|
|
297
|
+
getattr(self.data, "is_multimodal", False) is True
|
|
298
|
+
): # pragma: no branch
|
|
299
|
+
class_name = "MultimodalConversableAgent"
|
|
300
|
+
return class_name
|
|
131
301
|
if self.agent_type == "assistant":
|
|
132
|
-
|
|
133
|
-
|
|
302
|
+
if getattr(self.data, "is_multimodal", False) is True:
|
|
303
|
+
class_name = "MultimodalConversableAgent"
|
|
304
|
+
else:
|
|
305
|
+
class_name = "AssistantAgent"
|
|
306
|
+
if self.is_user:
|
|
134
307
|
class_name = "UserProxyAgent"
|
|
135
|
-
if self.
|
|
136
|
-
class_name = "GroupChatManager"
|
|
137
|
-
if self.agent_type == "rag_user":
|
|
308
|
+
if self.is_rag_user:
|
|
138
309
|
class_name = "RetrieveUserProxyAgent"
|
|
139
|
-
if self.
|
|
140
|
-
class_name = "SwarmAgent"
|
|
141
|
-
if self.agent_type == "reasoning":
|
|
310
|
+
if self.is_reasoning:
|
|
142
311
|
class_name = "ReasoningAgent"
|
|
143
|
-
if self.
|
|
312
|
+
if self.is_captain:
|
|
144
313
|
class_name = "CaptainAgent"
|
|
145
|
-
|
|
314
|
+
if self.is_group_manager:
|
|
315
|
+
class_name = "GroupChatManager"
|
|
316
|
+
return class_name # pragma: no cover
|
|
146
317
|
|
|
147
318
|
@property
|
|
148
|
-
def ag2_imports(self) ->
|
|
319
|
+
def ag2_imports(self) -> set[str]:
|
|
149
320
|
"""Return the AG2 imports of the agent."""
|
|
150
321
|
agent_class = self.ag2_class
|
|
151
322
|
imports = {"import autogen"}
|
|
@@ -153,8 +324,6 @@ class WaldiezAgent(WaldiezBase):
|
|
|
153
324
|
imports.add("from autogen import AssistantAgent")
|
|
154
325
|
elif agent_class == "UserProxyAgent":
|
|
155
326
|
imports.add("from autogen import UserProxyAgent")
|
|
156
|
-
elif agent_class == "GroupChatManager":
|
|
157
|
-
imports.add("from autogen import GroupChatManager")
|
|
158
327
|
elif agent_class == "RetrieveUserProxyAgent":
|
|
159
328
|
imports.add(
|
|
160
329
|
"from autogen.agentchat.contrib.retrieve_user_proxy_agent "
|
|
@@ -165,16 +334,6 @@ class WaldiezAgent(WaldiezBase):
|
|
|
165
334
|
"from autogen.agentchat.contrib.multimodal_conversable_agent "
|
|
166
335
|
"import MultimodalConversableAgent"
|
|
167
336
|
)
|
|
168
|
-
elif agent_class == "SwarmAgent":
|
|
169
|
-
imports.add(
|
|
170
|
-
"from autogen import "
|
|
171
|
-
"register_hand_off, "
|
|
172
|
-
"AfterWork, "
|
|
173
|
-
"OnCondition, "
|
|
174
|
-
"UpdateSystemMessage, "
|
|
175
|
-
"AfterWorkOption, "
|
|
176
|
-
"SwarmResult"
|
|
177
|
-
)
|
|
178
337
|
elif agent_class == "ReasoningAgent":
|
|
179
338
|
imports.add(
|
|
180
339
|
"from autogen.agents.experimental import ReasoningAgent"
|
|
@@ -184,39 +343,41 @@ class WaldiezAgent(WaldiezBase):
|
|
|
184
343
|
"from autogen.agentchat.contrib.captainagent "
|
|
185
344
|
"import CaptainAgent"
|
|
186
345
|
)
|
|
187
|
-
|
|
188
|
-
imports.add("import
|
|
346
|
+
elif agent_class == "GroupChatManager": # pragma: no branch
|
|
347
|
+
imports.add("from autogen import GroupChat")
|
|
348
|
+
imports.add("from autogen.agentchat import GroupChatManager")
|
|
349
|
+
imports.add("from autogen.agentchat.group import ContextVariables")
|
|
189
350
|
return imports
|
|
190
351
|
|
|
191
|
-
def
|
|
192
|
-
self,
|
|
352
|
+
def validate_linked_tools(
|
|
353
|
+
self, tool_ids: list[str], agent_ids: list[str]
|
|
193
354
|
) -> None:
|
|
194
|
-
"""Validate the
|
|
355
|
+
"""Validate the tools.
|
|
195
356
|
|
|
196
357
|
Parameters
|
|
197
358
|
----------
|
|
198
|
-
|
|
199
|
-
The list of
|
|
200
|
-
agent_ids :
|
|
359
|
+
tool_ids : list[str]
|
|
360
|
+
The list of tool IDs.
|
|
361
|
+
agent_ids : list[str]
|
|
201
362
|
The list of agent IDs.
|
|
202
363
|
|
|
203
364
|
Raises
|
|
204
365
|
------
|
|
205
366
|
ValueError
|
|
206
|
-
If a
|
|
367
|
+
If a tool or agent is not found
|
|
207
368
|
"""
|
|
208
|
-
# if the config dict has
|
|
209
|
-
for
|
|
210
|
-
if
|
|
369
|
+
# if the config dict has tools, make sure they can be found
|
|
370
|
+
for tool in self.data.tools:
|
|
371
|
+
if tool.id not in tool_ids:
|
|
211
372
|
raise ValueError(
|
|
212
|
-
f"
|
|
373
|
+
f"Tool '{tool.id}' not found in agent's {self.id} tools"
|
|
213
374
|
)
|
|
214
|
-
if
|
|
375
|
+
if tool.executor_id not in agent_ids:
|
|
215
376
|
raise ValueError(
|
|
216
|
-
f"Agent '{
|
|
377
|
+
f"Agent '{tool.executor_id}' not found in agents"
|
|
217
378
|
)
|
|
218
379
|
|
|
219
|
-
def validate_linked_models(self, model_ids:
|
|
380
|
+
def validate_linked_models(self, model_ids: list[str]) -> None:
|
|
220
381
|
"""Validate the models.
|
|
221
382
|
|
|
222
383
|
Parameters
|
|
@@ -236,13 +397,13 @@ class WaldiezAgent(WaldiezBase):
|
|
|
236
397
|
f"Model '{model}' not found in agent's {self.id} models"
|
|
237
398
|
)
|
|
238
399
|
|
|
239
|
-
def validate_code_execution(self,
|
|
400
|
+
def validate_code_execution(self, tool_ids: list[str]) -> None:
|
|
240
401
|
"""Validate the code execution config.
|
|
241
402
|
|
|
242
403
|
Parameters
|
|
243
404
|
----------
|
|
244
|
-
|
|
245
|
-
The list of
|
|
405
|
+
tool_ids : list[str]
|
|
406
|
+
The list of tool IDs.
|
|
246
407
|
|
|
247
408
|
Raises
|
|
248
409
|
------
|
|
@@ -254,7 +415,247 @@ class WaldiezAgent(WaldiezBase):
|
|
|
254
415
|
self.data.code_execution_config, WaldiezAgentCodeExecutionConfig
|
|
255
416
|
):
|
|
256
417
|
for function in self.data.code_execution_config.functions:
|
|
257
|
-
if function not in
|
|
418
|
+
if function not in tool_ids:
|
|
258
419
|
raise ValueError(
|
|
259
|
-
f"Function '{function}' not found in
|
|
420
|
+
f"Function '{function}' not found in tools"
|
|
260
421
|
)
|
|
422
|
+
|
|
423
|
+
def gather_nested_chats(
|
|
424
|
+
self,
|
|
425
|
+
all_agents: list["WaldiezAgent"],
|
|
426
|
+
all_chats: list["WaldiezChat"],
|
|
427
|
+
) -> None:
|
|
428
|
+
"""Gather the nested chats for the agent.
|
|
429
|
+
|
|
430
|
+
Parameters
|
|
431
|
+
----------
|
|
432
|
+
all_agents : list["WaldiezAgent"]
|
|
433
|
+
All the agents in the flow.
|
|
434
|
+
all_chats : list["WaldiezChat"]
|
|
435
|
+
All the chats in the flow.
|
|
436
|
+
"""
|
|
437
|
+
if self._checked_nested_chats:
|
|
438
|
+
return
|
|
439
|
+
self._checked_nested_chats = True
|
|
440
|
+
all_chat_ids = {chat.id for chat in all_chats}
|
|
441
|
+
all_agent_ids = {agent.id for agent in all_agents}
|
|
442
|
+
# only use chats that do have messages and "triggered_by"
|
|
443
|
+
nested_chats: list[WaldiezAgentNestedChat] = []
|
|
444
|
+
for chat in self.data.nested_chats:
|
|
445
|
+
if not chat.messages or not chat.triggered_by: # pragma: no cover
|
|
446
|
+
continue
|
|
447
|
+
# make sure the ids exist
|
|
448
|
+
chat.messages = [
|
|
449
|
+
message
|
|
450
|
+
for message in chat.messages
|
|
451
|
+
if message.id in all_chat_ids
|
|
452
|
+
]
|
|
453
|
+
chat.triggered_by = [
|
|
454
|
+
agent_id
|
|
455
|
+
for agent_id in chat.triggered_by
|
|
456
|
+
if agent_id in all_agent_ids
|
|
457
|
+
]
|
|
458
|
+
if chat.messages and chat.triggered_by: # pragma: no branch
|
|
459
|
+
nested_chats.append(chat)
|
|
460
|
+
self.data.nested_chats = nested_chats
|
|
461
|
+
|
|
462
|
+
def gather_handoff_ids(
|
|
463
|
+
self,
|
|
464
|
+
group_chats: list["WaldiezChat"],
|
|
465
|
+
nested_chat_id: str,
|
|
466
|
+
) -> None:
|
|
467
|
+
"""Gather all the handoff IDs for this agent.
|
|
468
|
+
|
|
469
|
+
This method will gather all the handoff IDs from the agent's data,
|
|
470
|
+
including those that might not be passed in data.handoffs.
|
|
471
|
+
|
|
472
|
+
Parameters
|
|
473
|
+
----------
|
|
474
|
+
group_chats : list["WaldiezChat"]
|
|
475
|
+
The list of group chats that this agent is part of.
|
|
476
|
+
nested_chat_id : str
|
|
477
|
+
The ID of the nested chat to include in handoffs if it exists.
|
|
478
|
+
|
|
479
|
+
"""
|
|
480
|
+
existing_handoffs = set(self.data.handoffs)
|
|
481
|
+
has_nested_chat = len(self.data.nested_chats) > 0 and any(
|
|
482
|
+
chat.messages for chat in self.data.nested_chats
|
|
483
|
+
)
|
|
484
|
+
# Step 1: Add missing group chat handoffs
|
|
485
|
+
# These are chats between group members (equivalent to groupEdges)
|
|
486
|
+
for chat in group_chats:
|
|
487
|
+
if chat.id not in existing_handoffs:
|
|
488
|
+
self.data.handoffs.append(chat.id)
|
|
489
|
+
existing_handoffs.add(chat.id)
|
|
490
|
+
|
|
491
|
+
# Step 2: Add nested chat if it exists and is not already in handoffs
|
|
492
|
+
if (
|
|
493
|
+
has_nested_chat and nested_chat_id not in existing_handoffs
|
|
494
|
+
): # pragma: no branch
|
|
495
|
+
self.data.handoffs.append(nested_chat_id)
|
|
496
|
+
existing_handoffs.add(nested_chat_id)
|
|
497
|
+
|
|
498
|
+
# Step 3: Validate all handoffs still exist
|
|
499
|
+
# Remove any handoffs that reference non-existent chats
|
|
500
|
+
valid_chat_ids = {chat.id for chat in group_chats}
|
|
501
|
+
if has_nested_chat: # pragma: no branch
|
|
502
|
+
valid_chat_ids.add(nested_chat_id)
|
|
503
|
+
|
|
504
|
+
# Filter out invalid handoffs
|
|
505
|
+
self.data.handoffs = [
|
|
506
|
+
handoff
|
|
507
|
+
for handoff in self.data.handoffs
|
|
508
|
+
if handoff in valid_chat_ids
|
|
509
|
+
]
|
|
510
|
+
|
|
511
|
+
def gather_handoffs(
|
|
512
|
+
self,
|
|
513
|
+
all_agents: list["WaldiezAgent"],
|
|
514
|
+
all_chats: list["WaldiezChat"],
|
|
515
|
+
) -> None:
|
|
516
|
+
"""Gather all the handoffs including.
|
|
517
|
+
|
|
518
|
+
Including ones that might not be passed in data.handoffs.
|
|
519
|
+
|
|
520
|
+
Parameters
|
|
521
|
+
----------
|
|
522
|
+
all_agents : list["WaldiezAgent"]
|
|
523
|
+
The list of all agents in the flow.
|
|
524
|
+
all_chats : list["WaldiezChat"]
|
|
525
|
+
The list of all chats in the flow.
|
|
526
|
+
|
|
527
|
+
"""
|
|
528
|
+
self.gather_nested_chats(all_agents, all_chats)
|
|
529
|
+
if not self.is_group_member or self._checked_handoffs:
|
|
530
|
+
return
|
|
531
|
+
nested_chat_id = "nested-chat"
|
|
532
|
+
self._checked_handoffs = True
|
|
533
|
+
group_chats, group_nested_chats = self._get_agent_chats(
|
|
534
|
+
all_agents, all_chats
|
|
535
|
+
)
|
|
536
|
+
if group_nested_chats: # pragma: no branch
|
|
537
|
+
self._ensure_one_nested_chat(group_nested_chats)
|
|
538
|
+
self.gather_handoff_ids(
|
|
539
|
+
group_chats=group_chats, nested_chat_id=nested_chat_id
|
|
540
|
+
)
|
|
541
|
+
# generate the actual handoff instances
|
|
542
|
+
for handoff_id in self.data.handoffs:
|
|
543
|
+
if handoff_id == nested_chat_id:
|
|
544
|
+
nested_chat_handoff = self._generate_handoff_from_nested(
|
|
545
|
+
group_nested_chats
|
|
546
|
+
)
|
|
547
|
+
if nested_chat_handoff: # pragma: no branch
|
|
548
|
+
self._handoffs.append(nested_chat_handoff)
|
|
549
|
+
else:
|
|
550
|
+
chat = next(
|
|
551
|
+
(chat for chat in group_chats if chat.id == handoff_id),
|
|
552
|
+
None,
|
|
553
|
+
)
|
|
554
|
+
if chat: # pragma: no branch
|
|
555
|
+
self._handoffs.append(chat.as_handoff())
|
|
556
|
+
|
|
557
|
+
def _ensure_one_nested_chat(
|
|
558
|
+
self,
|
|
559
|
+
group_nested_chats: list["WaldiezChat"],
|
|
560
|
+
) -> None:
|
|
561
|
+
"""Ensure that there is at least one nested chat."""
|
|
562
|
+
if not self.data.nested_chats: # pragma: no branch
|
|
563
|
+
# create one from the group chats.
|
|
564
|
+
triggered_by = [self.id]
|
|
565
|
+
messages = [
|
|
566
|
+
WaldiezAgentNestedChatMessage(id=chat.id, is_reply=False)
|
|
567
|
+
for chat in group_nested_chats
|
|
568
|
+
]
|
|
569
|
+
chats_with_condition = [
|
|
570
|
+
chat
|
|
571
|
+
for chat in group_nested_chats
|
|
572
|
+
if chat.condition.is_not_empty()
|
|
573
|
+
]
|
|
574
|
+
if not chats_with_condition:
|
|
575
|
+
chat_with_condition = group_nested_chats[0]
|
|
576
|
+
else:
|
|
577
|
+
chat_with_condition = chats_with_condition[0]
|
|
578
|
+
nested_chat = WaldiezAgentNestedChat(
|
|
579
|
+
triggered_by=triggered_by,
|
|
580
|
+
messages=messages,
|
|
581
|
+
condition=chat_with_condition.condition, # pyright: ignore
|
|
582
|
+
available=chat_with_condition.available, # pyright: ignore
|
|
583
|
+
)
|
|
584
|
+
self.data.nested_chats.append(nested_chat)
|
|
585
|
+
|
|
586
|
+
def _generate_handoff_from_nested(
|
|
587
|
+
self,
|
|
588
|
+
group_nested_chats: list["WaldiezChat"],
|
|
589
|
+
) -> WaldiezHandoff | None:
|
|
590
|
+
"""Generate a handoff from a nested chat.
|
|
591
|
+
|
|
592
|
+
Parameters
|
|
593
|
+
----------
|
|
594
|
+
group_nested_chats : list["WaldiezChat"]
|
|
595
|
+
The list of nested (out of the group) chats
|
|
596
|
+
that this agent is part of.
|
|
597
|
+
|
|
598
|
+
Returns
|
|
599
|
+
-------
|
|
600
|
+
WaldiezHandoff | None
|
|
601
|
+
A handoff instance if a nested chat with messages exists,
|
|
602
|
+
otherwise None.
|
|
603
|
+
"""
|
|
604
|
+
if not group_nested_chats:
|
|
605
|
+
return None
|
|
606
|
+
# Check if we have any nested chats with messages
|
|
607
|
+
if not self.data.nested_chats or not any(
|
|
608
|
+
chat.messages for chat in self.data.nested_chats
|
|
609
|
+
):
|
|
610
|
+
return None
|
|
611
|
+
# get the first (and probably only) nested chat
|
|
612
|
+
nested_chat = self.data.nested_chats[0]
|
|
613
|
+
target = WaldiezGroupOrNestedTarget(
|
|
614
|
+
target_type="NestedChatTarget",
|
|
615
|
+
value=[message.id for message in nested_chat.messages],
|
|
616
|
+
)
|
|
617
|
+
return WaldiezHandoff(
|
|
618
|
+
target=target,
|
|
619
|
+
available=nested_chat.available,
|
|
620
|
+
condition=nested_chat.condition,
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
def _get_agent_chats(
|
|
624
|
+
self,
|
|
625
|
+
all_agents: list["WaldiezAgent"],
|
|
626
|
+
all_chats: list["WaldiezChat"],
|
|
627
|
+
) -> tuple[list["WaldiezChat"], list["WaldiezChat"]]:
|
|
628
|
+
"""Get all chats originating from this agent.
|
|
629
|
+
|
|
630
|
+
Parameters
|
|
631
|
+
----------
|
|
632
|
+
all_agents : list["WaldiezAgent"]
|
|
633
|
+
The list of all agents.
|
|
634
|
+
all_chats : list["WaldiezChat"]
|
|
635
|
+
The list of all chats if the flow.
|
|
636
|
+
|
|
637
|
+
Returns
|
|
638
|
+
-------
|
|
639
|
+
tuple[list["WaldiezChat"], list["WaldiezChat"]]
|
|
640
|
+
A tuple containing two lists:
|
|
641
|
+
- group_chats: Chats that are between group members.
|
|
642
|
+
- group_nested_chats: Chats that are from this agent to an agent
|
|
643
|
+
that is not a group member.
|
|
644
|
+
"""
|
|
645
|
+
agent_chats: list["WaldiezChat"] = [
|
|
646
|
+
chat for chat in all_chats if chat.source == self.id
|
|
647
|
+
]
|
|
648
|
+
group_chats: list["WaldiezChat"] = []
|
|
649
|
+
group_nested_chats: list["WaldiezChat"] = []
|
|
650
|
+
# make sure we have prepared the nested chats
|
|
651
|
+
for chat in agent_chats:
|
|
652
|
+
target_agent = next(
|
|
653
|
+
(agent for agent in all_agents if agent.id == chat.target),
|
|
654
|
+
None,
|
|
655
|
+
)
|
|
656
|
+
if target_agent: # pragma: no branch
|
|
657
|
+
if target_agent.is_group_member:
|
|
658
|
+
group_chats.append(chat)
|
|
659
|
+
else:
|
|
660
|
+
group_nested_chats.append(chat)
|
|
661
|
+
return group_chats, group_nested_chats
|