waldiez 0.1.0__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 +15 -0
- waldiez/__main__.py +6 -0
- waldiez/_version.py +3 -0
- waldiez/cli.py +162 -0
- waldiez/exporter.py +293 -0
- waldiez/exporting/__init__.py +14 -0
- waldiez/exporting/agents/__init__.py +5 -0
- waldiez/exporting/agents/agent.py +229 -0
- waldiez/exporting/agents/agent_skills.py +67 -0
- waldiez/exporting/agents/code_execution.py +67 -0
- waldiez/exporting/agents/group_manager.py +209 -0
- waldiez/exporting/agents/llm_config.py +53 -0
- waldiez/exporting/agents/rag_user/__init__.py +5 -0
- waldiez/exporting/agents/rag_user/chroma_utils.py +134 -0
- waldiez/exporting/agents/rag_user/mongo_utils.py +83 -0
- waldiez/exporting/agents/rag_user/pgvector_utils.py +93 -0
- waldiez/exporting/agents/rag_user/qdrant_utils.py +112 -0
- waldiez/exporting/agents/rag_user/rag_user.py +165 -0
- waldiez/exporting/agents/rag_user/vector_db.py +119 -0
- waldiez/exporting/agents/teachability.py +37 -0
- waldiez/exporting/agents/termination_message.py +45 -0
- waldiez/exporting/chats/__init__.py +14 -0
- waldiez/exporting/chats/chats.py +46 -0
- waldiez/exporting/chats/helpers.py +395 -0
- waldiez/exporting/chats/nested.py +264 -0
- waldiez/exporting/flow/__init__.py +5 -0
- waldiez/exporting/flow/def_main.py +37 -0
- waldiez/exporting/flow/flow.py +185 -0
- waldiez/exporting/models/__init__.py +193 -0
- waldiez/exporting/skills/__init__.py +128 -0
- waldiez/exporting/utils/__init__.py +34 -0
- waldiez/exporting/utils/comments.py +136 -0
- waldiez/exporting/utils/importing.py +267 -0
- waldiez/exporting/utils/logging_utils.py +203 -0
- waldiez/exporting/utils/method_utils.py +35 -0
- waldiez/exporting/utils/naming.py +127 -0
- waldiez/exporting/utils/object_string.py +81 -0
- waldiez/io_stream.py +181 -0
- waldiez/models/__init__.py +107 -0
- waldiez/models/agents/__init__.py +65 -0
- waldiez/models/agents/agent/__init__.py +21 -0
- waldiez/models/agents/agent/agent.py +190 -0
- waldiez/models/agents/agent/agent_data.py +162 -0
- waldiez/models/agents/agent/code_execution.py +71 -0
- waldiez/models/agents/agent/linked_skill.py +30 -0
- waldiez/models/agents/agent/nested_chat.py +73 -0
- waldiez/models/agents/agent/teachability.py +68 -0
- waldiez/models/agents/agent/termination_message.py +167 -0
- waldiez/models/agents/agents.py +129 -0
- waldiez/models/agents/assistant/__init__.py +6 -0
- waldiez/models/agents/assistant/assistant.py +41 -0
- waldiez/models/agents/assistant/assistant_data.py +29 -0
- waldiez/models/agents/group_manager/__init__.py +19 -0
- waldiez/models/agents/group_manager/group_manager.py +87 -0
- waldiez/models/agents/group_manager/group_manager_data.py +91 -0
- waldiez/models/agents/group_manager/speakers.py +211 -0
- waldiez/models/agents/rag_user/__init__.py +26 -0
- waldiez/models/agents/rag_user/rag_user.py +58 -0
- waldiez/models/agents/rag_user/rag_user_data.py +32 -0
- waldiez/models/agents/rag_user/retrieve_config.py +592 -0
- waldiez/models/agents/rag_user/vector_db_config.py +162 -0
- waldiez/models/agents/user_proxy/__init__.py +6 -0
- waldiez/models/agents/user_proxy/user_proxy.py +41 -0
- waldiez/models/agents/user_proxy/user_proxy_data.py +30 -0
- waldiez/models/chat/__init__.py +22 -0
- waldiez/models/chat/chat.py +129 -0
- waldiez/models/chat/chat_data.py +326 -0
- waldiez/models/chat/chat_message.py +304 -0
- waldiez/models/chat/chat_nested.py +160 -0
- waldiez/models/chat/chat_summary.py +110 -0
- waldiez/models/common/__init__.py +38 -0
- waldiez/models/common/base.py +63 -0
- waldiez/models/common/method_utils.py +165 -0
- waldiez/models/flow/__init__.py +9 -0
- waldiez/models/flow/flow.py +302 -0
- waldiez/models/flow/flow_data.py +87 -0
- waldiez/models/model/__init__.py +11 -0
- waldiez/models/model/model.py +169 -0
- waldiez/models/model/model_data.py +86 -0
- waldiez/models/skill/__init__.py +9 -0
- waldiez/models/skill/skill.py +129 -0
- waldiez/models/skill/skill_data.py +37 -0
- waldiez/models/waldiez.py +301 -0
- waldiez/py.typed +0 -0
- waldiez/runner.py +304 -0
- waldiez/stream/__init__.py +7 -0
- waldiez/stream/consumer.py +139 -0
- waldiez/stream/provider.py +339 -0
- waldiez/stream/server.py +412 -0
- waldiez-0.1.0.dist-info/METADATA +181 -0
- waldiez-0.1.0.dist-info/RECORD +94 -0
- waldiez-0.1.0.dist-info/WHEEL +4 -0
- waldiez-0.1.0.dist-info/entry_points.txt +2 -0
- waldiez-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Waldiez Agent Nested Chat."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from typing_extensions import Annotated
|
|
7
|
+
|
|
8
|
+
from ...common import WaldiezBase
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class WaldiezAgentNestedChatMessage(WaldiezBase):
|
|
12
|
+
"""Waldiez Agent nested chat message.
|
|
13
|
+
|
|
14
|
+
A reference to a chat's message or reply in a nested chat
|
|
15
|
+
|
|
16
|
+
Attributes
|
|
17
|
+
----------
|
|
18
|
+
id : str
|
|
19
|
+
The id of the chat.
|
|
20
|
+
is_reply : bool
|
|
21
|
+
Whether to use the reply in the chat or not.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
id: Annotated[
|
|
25
|
+
str, Field(..., title="ID", description="The id of the chat.")
|
|
26
|
+
]
|
|
27
|
+
is_reply: Annotated[
|
|
28
|
+
bool,
|
|
29
|
+
Field(
|
|
30
|
+
False,
|
|
31
|
+
title="Is reply",
|
|
32
|
+
description="Whether to use the reply in the chat or not.",
|
|
33
|
+
alias="isReply",
|
|
34
|
+
),
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class WaldiezAgentNestedChat(WaldiezBase):
|
|
39
|
+
"""Waldiez Agent Nested Chat.
|
|
40
|
+
|
|
41
|
+
Attributes
|
|
42
|
+
----------
|
|
43
|
+
triggered_by : List[WaldiezAgentNestedChatMessage]
|
|
44
|
+
A list of chats (id and is_reply) to determine
|
|
45
|
+
the triggering of the nested chat.
|
|
46
|
+
messages : List[WaldiezAgentNestedChatMessage]
|
|
47
|
+
The list of messages (chat ids and 'is_reply'z)
|
|
48
|
+
to include the in the nested chat registration.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
triggered_by: Annotated[
|
|
52
|
+
List[WaldiezAgentNestedChatMessage],
|
|
53
|
+
Field(
|
|
54
|
+
title="Triggered By",
|
|
55
|
+
description=(
|
|
56
|
+
"A list of chats (id and is_reply) to determine"
|
|
57
|
+
"the triggering of the nested chat."
|
|
58
|
+
),
|
|
59
|
+
alias="triggeredBy",
|
|
60
|
+
default_factory=list,
|
|
61
|
+
),
|
|
62
|
+
]
|
|
63
|
+
messages: Annotated[
|
|
64
|
+
List[WaldiezAgentNestedChatMessage],
|
|
65
|
+
Field(
|
|
66
|
+
title="Messages",
|
|
67
|
+
description=(
|
|
68
|
+
"The list of messages (chat ids and 'is_reply'z)"
|
|
69
|
+
"to include the in the nested chat registration."
|
|
70
|
+
),
|
|
71
|
+
default_factory=list,
|
|
72
|
+
),
|
|
73
|
+
]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Waldiez Agent Teachability."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
from typing_extensions import Annotated, Literal
|
|
5
|
+
|
|
6
|
+
from ...common import WaldiezBase
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WaldiezAgentTeachability(WaldiezBase):
|
|
10
|
+
"""Waldiez Agent Teachability.
|
|
11
|
+
|
|
12
|
+
Attributes
|
|
13
|
+
----------
|
|
14
|
+
enabled : bool
|
|
15
|
+
Whether the teachability is enabled.
|
|
16
|
+
verbosity : Literal[0, 1, 2, 3]
|
|
17
|
+
The verbosity level of the teachability. Default: 0
|
|
18
|
+
reset_db : bool
|
|
19
|
+
Whether to reset the database. Default: False
|
|
20
|
+
recall_threshold : float
|
|
21
|
+
The recall threshold. Default: 1.5
|
|
22
|
+
max_num_retrievals : int
|
|
23
|
+
The maximum number of retrievals. Default: 10
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
enabled: Annotated[
|
|
27
|
+
bool,
|
|
28
|
+
Field(
|
|
29
|
+
False,
|
|
30
|
+
title="Enabled",
|
|
31
|
+
description="Whether the teachability is enabled.",
|
|
32
|
+
),
|
|
33
|
+
]
|
|
34
|
+
verbosity: Annotated[
|
|
35
|
+
Literal[0, 1, 2, 3],
|
|
36
|
+
Field(
|
|
37
|
+
0,
|
|
38
|
+
title="Verbosity",
|
|
39
|
+
description="The verbosity level of the teachability.",
|
|
40
|
+
),
|
|
41
|
+
]
|
|
42
|
+
reset_db: Annotated[
|
|
43
|
+
bool,
|
|
44
|
+
Field(
|
|
45
|
+
False,
|
|
46
|
+
title="Reset DB",
|
|
47
|
+
description="Whether to reset the database.",
|
|
48
|
+
alias="resetDb",
|
|
49
|
+
),
|
|
50
|
+
]
|
|
51
|
+
recall_threshold: Annotated[
|
|
52
|
+
float,
|
|
53
|
+
Field(
|
|
54
|
+
1.5,
|
|
55
|
+
title="Recall threshold",
|
|
56
|
+
description="The recall threshold.",
|
|
57
|
+
alias="recallThreshold",
|
|
58
|
+
),
|
|
59
|
+
]
|
|
60
|
+
max_num_retrievals: Annotated[
|
|
61
|
+
int,
|
|
62
|
+
Field(
|
|
63
|
+
10,
|
|
64
|
+
title="Max num retrievals",
|
|
65
|
+
description="The maximum number of retrievals.",
|
|
66
|
+
alias="maxMumRetrievals",
|
|
67
|
+
),
|
|
68
|
+
]
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""Waldiez Agent Termination Message Check."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import ConfigDict, Field, model_validator
|
|
6
|
+
from pydantic.alias_generators import to_camel
|
|
7
|
+
from typing_extensions import Annotated, Literal, Self
|
|
8
|
+
|
|
9
|
+
from ...common import WaldiezBase, WaldiezMethodName, check_function
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WaldiezAgentTerminationMessage(WaldiezBase):
|
|
13
|
+
"""Waldiez Agent Termination Message Check.
|
|
14
|
+
|
|
15
|
+
Attributes
|
|
16
|
+
----------
|
|
17
|
+
type : Literal["none", "keyword", "method"]
|
|
18
|
+
The type of the termination check to use: "none", "keyword", "method"
|
|
19
|
+
keywords : List[str]
|
|
20
|
+
If the type is "keyword", the keywords to search in the message.
|
|
21
|
+
criterion : Optional[Literal["found", "ending", "exact"]] = None
|
|
22
|
+
If the type is "keyword", the criterion to use (e.g.: in, endswith, ==)
|
|
23
|
+
method_content: Optional[str]
|
|
24
|
+
If the type is "method", the code of the method to use.
|
|
25
|
+
The method must be called `is_termination_message`,
|
|
26
|
+
have one argument (`message`) which is a dict, and
|
|
27
|
+
return a bool (whether the message is a termination message or not.)
|
|
28
|
+
string : str
|
|
29
|
+
The value of the termination message.
|
|
30
|
+
|
|
31
|
+
Functions
|
|
32
|
+
---------
|
|
33
|
+
validate_termination_message() -> Self
|
|
34
|
+
Validate the termination message configuration.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
model_config = ConfigDict(
|
|
38
|
+
extra="forbid",
|
|
39
|
+
alias_generator=to_camel,
|
|
40
|
+
populate_by_name=True,
|
|
41
|
+
frozen=False,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
type: Annotated[
|
|
45
|
+
Literal["none", "keyword", "method"],
|
|
46
|
+
Field(
|
|
47
|
+
"none",
|
|
48
|
+
title="Type",
|
|
49
|
+
description=(
|
|
50
|
+
"The type of the termination check to use: "
|
|
51
|
+
"none, keyword, method"
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
]
|
|
55
|
+
keywords: Annotated[
|
|
56
|
+
List[str],
|
|
57
|
+
Field(
|
|
58
|
+
default_factory=list,
|
|
59
|
+
title="Keywords",
|
|
60
|
+
description=(
|
|
61
|
+
"If the type is `keyword`,"
|
|
62
|
+
" the keywords to search in the message."
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
]
|
|
66
|
+
criterion: Annotated[
|
|
67
|
+
Optional[Literal["found", "ending", "exact"]],
|
|
68
|
+
Field(
|
|
69
|
+
"exact",
|
|
70
|
+
title="Criterion",
|
|
71
|
+
description=(
|
|
72
|
+
"If the type is `keyword`, "
|
|
73
|
+
"the criterion to use (e.g.: in, endswith, ==)"
|
|
74
|
+
),
|
|
75
|
+
),
|
|
76
|
+
]
|
|
77
|
+
method_content: Annotated[
|
|
78
|
+
Optional[str],
|
|
79
|
+
Field(
|
|
80
|
+
None,
|
|
81
|
+
title="Method content",
|
|
82
|
+
description=(
|
|
83
|
+
"If the type is `method`, the code of the method to use."
|
|
84
|
+
"The method must be called `is_termination_message`,"
|
|
85
|
+
"have one argument (`message`) which is a dict, and return a"
|
|
86
|
+
"bool (whether the message is a termination message or not.)"
|
|
87
|
+
),
|
|
88
|
+
),
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
_string: str = "None"
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def string(self) -> str:
|
|
95
|
+
"""Get the value of the termination message.
|
|
96
|
+
|
|
97
|
+
- If the type is "none", the value is "None".
|
|
98
|
+
- If the type is "keyword", the value is a lambda function that checks
|
|
99
|
+
if any of the keywords comply with the criterion.
|
|
100
|
+
- If the type is "method", the value is the method content.
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
str
|
|
105
|
+
The value of the termination message.
|
|
106
|
+
"""
|
|
107
|
+
return self._string
|
|
108
|
+
|
|
109
|
+
def _validate_method_content(self) -> None:
|
|
110
|
+
"""Validate the method content."""
|
|
111
|
+
if not self.method_content:
|
|
112
|
+
raise ValueError(
|
|
113
|
+
"Method content is required for method termination."
|
|
114
|
+
)
|
|
115
|
+
expected_function_name: WaldiezMethodName = "is_termination_message"
|
|
116
|
+
valid, error_or_content = check_function(
|
|
117
|
+
self.method_content, expected_function_name
|
|
118
|
+
)
|
|
119
|
+
if not valid:
|
|
120
|
+
raise ValueError(error_or_content)
|
|
121
|
+
self._string = error_or_content
|
|
122
|
+
|
|
123
|
+
def _validate_keyword(self) -> None:
|
|
124
|
+
"""Validate the keyword termination configuration."""
|
|
125
|
+
if not self.keywords:
|
|
126
|
+
raise ValueError("Keywords are required for keyword termination.")
|
|
127
|
+
if self.criterion not in ["found", "ending", "exact"]:
|
|
128
|
+
raise ValueError(f"Invalid criterion: {self.criterion}")
|
|
129
|
+
# pylint: disable=inconsistent-quotes
|
|
130
|
+
keywords_str = ", ".join([f'"{keyword}"' for keyword in self.keywords])
|
|
131
|
+
if self.criterion == "found":
|
|
132
|
+
self._string = (
|
|
133
|
+
'lambda x: any(x.get("content", "") and '
|
|
134
|
+
'keyword in x.get("content", "") '
|
|
135
|
+
f"for keyword in [{keywords_str}])"
|
|
136
|
+
)
|
|
137
|
+
if self.criterion == "ending":
|
|
138
|
+
self._string = (
|
|
139
|
+
'lambda x: any(x.get("content", "").endswith(keyword) '
|
|
140
|
+
f"for keyword in [{keywords_str}])"
|
|
141
|
+
)
|
|
142
|
+
if self.criterion == "exact":
|
|
143
|
+
self._string = (
|
|
144
|
+
'lambda x: any(x.get("content", "") == keyword '
|
|
145
|
+
f"for keyword in [{keywords_str}])"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
@model_validator(mode="after")
|
|
149
|
+
def validate_termination_message(self) -> Self:
|
|
150
|
+
"""Validate the termination message configuration.
|
|
151
|
+
|
|
152
|
+
Raises
|
|
153
|
+
------
|
|
154
|
+
ValueError
|
|
155
|
+
If the configuration is invalid.
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
WaldiezAgentTerminationMessage
|
|
159
|
+
The validated termination message configuration.
|
|
160
|
+
"""
|
|
161
|
+
if self.type == "method":
|
|
162
|
+
self._validate_method_content()
|
|
163
|
+
if self.type == "keyword":
|
|
164
|
+
self._validate_keyword()
|
|
165
|
+
if self.type == "none":
|
|
166
|
+
self._string = "None"
|
|
167
|
+
return self
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""Waldiez agents model."""
|
|
2
|
+
|
|
3
|
+
from typing import Iterator, List
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, model_validator
|
|
6
|
+
from typing_extensions import Annotated, Self
|
|
7
|
+
|
|
8
|
+
from ..common import WaldiezBase
|
|
9
|
+
from .agent import WaldiezAgent
|
|
10
|
+
from .assistant import WaldiezAssistant
|
|
11
|
+
from .group_manager.group_manager import WaldiezGroupManager
|
|
12
|
+
from .rag_user import WaldiezRagUser
|
|
13
|
+
from .user_proxy import WaldiezUserProxy
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class WaldiezAgents(WaldiezBase):
|
|
17
|
+
"""Waldiez agents model.
|
|
18
|
+
|
|
19
|
+
Attributes
|
|
20
|
+
----------
|
|
21
|
+
users : List[WaldiezUserProxy]
|
|
22
|
+
User proxy agents.
|
|
23
|
+
assistants : List[WaldiezAssistant]
|
|
24
|
+
Assistant agents.
|
|
25
|
+
managers : List[WaldiezGroupManager]
|
|
26
|
+
Group chat mangers.
|
|
27
|
+
rag_users : List[WaldiezRagUser]
|
|
28
|
+
RAG user agents.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
users: Annotated[
|
|
32
|
+
List[WaldiezUserProxy],
|
|
33
|
+
Field(
|
|
34
|
+
title="Users.",
|
|
35
|
+
description="User proxy agents",
|
|
36
|
+
default_factory=list,
|
|
37
|
+
),
|
|
38
|
+
]
|
|
39
|
+
assistants: Annotated[
|
|
40
|
+
List[WaldiezAssistant],
|
|
41
|
+
Field(
|
|
42
|
+
title="Assistants.",
|
|
43
|
+
description="Assistant agents",
|
|
44
|
+
default_factory=list,
|
|
45
|
+
),
|
|
46
|
+
]
|
|
47
|
+
managers: Annotated[
|
|
48
|
+
List[WaldiezGroupManager],
|
|
49
|
+
Field(
|
|
50
|
+
title="Managers.",
|
|
51
|
+
description="Group chat mangers",
|
|
52
|
+
default_factory=list,
|
|
53
|
+
),
|
|
54
|
+
]
|
|
55
|
+
rag_users: Annotated[
|
|
56
|
+
List[WaldiezRagUser],
|
|
57
|
+
Field(
|
|
58
|
+
title="RAG Users.",
|
|
59
|
+
description="RAG user agents",
|
|
60
|
+
default_factory=list,
|
|
61
|
+
),
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def members(self) -> Iterator[WaldiezAgent]:
|
|
66
|
+
"""Get all agents.
|
|
67
|
+
|
|
68
|
+
Yields
|
|
69
|
+
------
|
|
70
|
+
WaldiezAgent
|
|
71
|
+
The agents.
|
|
72
|
+
"""
|
|
73
|
+
yield from self.users
|
|
74
|
+
yield from self.assistants
|
|
75
|
+
yield from self.managers
|
|
76
|
+
yield from self.rag_users
|
|
77
|
+
|
|
78
|
+
@model_validator(mode="after")
|
|
79
|
+
def validate_agents(self) -> Self:
|
|
80
|
+
"""Validate the agents.
|
|
81
|
+
|
|
82
|
+
- At least two agents are required.
|
|
83
|
+
- All the agent IDs must be unique.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
WaldiezAgents
|
|
88
|
+
The agents.
|
|
89
|
+
|
|
90
|
+
Raises
|
|
91
|
+
------
|
|
92
|
+
ValueError
|
|
93
|
+
If the agents are invalid.
|
|
94
|
+
"""
|
|
95
|
+
all_agent_ids = [agent.id for agent in self.members]
|
|
96
|
+
if len(all_agent_ids) < 2:
|
|
97
|
+
raise ValueError("At least two agents are required.")
|
|
98
|
+
if len(all_agent_ids) != len(set(all_agent_ids)):
|
|
99
|
+
raise ValueError("Agent IDs must be unique.")
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
def validate_flow(self, model_ids: List[str], skill_ids: List[str]) -> None:
|
|
103
|
+
"""Validate the flow of the agents.
|
|
104
|
+
|
|
105
|
+
- Validate the linked models (the referenced model ids must exist).
|
|
106
|
+
- Validate the linked skills (the referenced skill ids must exist).
|
|
107
|
+
- Validate the code execution (the referenced functions must exist).
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
model_ids : List[str]
|
|
112
|
+
The list of model IDs.
|
|
113
|
+
skill_ids : List[str]
|
|
114
|
+
The list of skill IDs.
|
|
115
|
+
|
|
116
|
+
Raises
|
|
117
|
+
------
|
|
118
|
+
ValueError
|
|
119
|
+
If the flow is invalid.
|
|
120
|
+
"""
|
|
121
|
+
all_agent_ids = [agent.id for agent in self.members]
|
|
122
|
+
for agent in self.members:
|
|
123
|
+
agent.validate_linked_models(model_ids)
|
|
124
|
+
agent.validate_linked_skills(skill_ids, agent_ids=all_agent_ids)
|
|
125
|
+
agent.validate_code_execution(skill_ids=skill_ids)
|
|
126
|
+
if agent.agent_type == "manager" and isinstance(
|
|
127
|
+
agent, WaldiezGroupManager
|
|
128
|
+
):
|
|
129
|
+
agent.validate_transitions(agent_ids=all_agent_ids)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Assistant agent model."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
from typing_extensions import Annotated, Literal
|
|
5
|
+
|
|
6
|
+
from ..agent import WaldiezAgent
|
|
7
|
+
from .assistant_data import WaldiezAssistantData
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class WaldiezAssistant(WaldiezAgent):
|
|
11
|
+
"""Assistant agent model.
|
|
12
|
+
|
|
13
|
+
A `WaldiezAgent` with agent_type `assistant` and
|
|
14
|
+
default `human_input_mode`: `"NEVER"`
|
|
15
|
+
See `WaldiezAgent`,`WaldiezAssistantData`,`WaldiezAgentData` for more info.
|
|
16
|
+
|
|
17
|
+
Attributes
|
|
18
|
+
----------
|
|
19
|
+
agent_type : Literal["assistant"]
|
|
20
|
+
The agent type: 'assistant' for an assistant agent
|
|
21
|
+
data : WaldiezAssistantData
|
|
22
|
+
The assistant agent's data
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
agent_type: Annotated[
|
|
26
|
+
Literal["assistant"],
|
|
27
|
+
Field(
|
|
28
|
+
"assistant",
|
|
29
|
+
title="Agent type",
|
|
30
|
+
description="The agent type in a graph: 'assistant'",
|
|
31
|
+
alias="agentType",
|
|
32
|
+
),
|
|
33
|
+
]
|
|
34
|
+
data: Annotated[
|
|
35
|
+
WaldiezAssistantData,
|
|
36
|
+
Field(
|
|
37
|
+
title="Data",
|
|
38
|
+
description="The assistant agent's data",
|
|
39
|
+
default_factory=WaldiezAssistantData,
|
|
40
|
+
),
|
|
41
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Assistant agent data model."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
from typing_extensions import Annotated, Literal
|
|
5
|
+
|
|
6
|
+
from ..agent import WaldiezAgentData
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class WaldiezAssistantData(WaldiezAgentData):
|
|
10
|
+
"""Assistant agent data class.
|
|
11
|
+
|
|
12
|
+
The data for an agent with `human_input_mode` set to `"ALWAYS"` as default.
|
|
13
|
+
See the parent's docs (`WaldiezAgentData`) for the rest of the properties.
|
|
14
|
+
|
|
15
|
+
Attributes
|
|
16
|
+
----------
|
|
17
|
+
human_input_mode : Literal["ALWAYS", "NEVER", "TERMINATE"]
|
|
18
|
+
The human input mode, Defaults to `NEVER`
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
human_input_mode: Annotated[
|
|
22
|
+
Literal["ALWAYS", "NEVER", "TERMINATE"],
|
|
23
|
+
Field(
|
|
24
|
+
"NEVER",
|
|
25
|
+
title="Human input mode",
|
|
26
|
+
description="The human input mode, Defaults to `NEVER`",
|
|
27
|
+
alias="humanInputMode",
|
|
28
|
+
),
|
|
29
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Group chat manger agent."""
|
|
2
|
+
|
|
3
|
+
from .group_manager import WaldiezGroupManager
|
|
4
|
+
from .group_manager_data import WaldiezGroupManagerData
|
|
5
|
+
from .speakers import (
|
|
6
|
+
WaldiezGroupManagerSpeakers,
|
|
7
|
+
WaldiezGroupManagerSpeakersSelectionMethod,
|
|
8
|
+
WaldiezGroupManagerSpeakersSelectionMode,
|
|
9
|
+
WaldiezGroupManagerSpeakersTransitionsType,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"WaldiezGroupManager",
|
|
14
|
+
"WaldiezGroupManagerData",
|
|
15
|
+
"WaldiezGroupManagerSpeakers",
|
|
16
|
+
"WaldiezGroupManagerSpeakersSelectionMethod",
|
|
17
|
+
"WaldiezGroupManagerSpeakersSelectionMode",
|
|
18
|
+
"WaldiezGroupManagerSpeakersTransitionsType",
|
|
19
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Group chat manager agent."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from typing_extensions import Annotated
|
|
7
|
+
|
|
8
|
+
from ..agent import WaldiezAgent
|
|
9
|
+
from .group_manager_data import WaldiezGroupManagerData
|
|
10
|
+
from .speakers import WaldiezGroupManagerSpeakers
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class WaldiezGroupManager(WaldiezAgent):
|
|
14
|
+
"""Group chat manager agent.
|
|
15
|
+
|
|
16
|
+
A `WaldiezAgent` with agent_type `manager`, `human_input_mode`: `"NEVER"`
|
|
17
|
+
and chat group related config for the agent.
|
|
18
|
+
Also see `WaldiezAgent`, `WaldiezGroupManagerData`, `WaldiezAgentData`
|
|
19
|
+
|
|
20
|
+
Attributes
|
|
21
|
+
----------
|
|
22
|
+
agent_type : Literal["manager"]
|
|
23
|
+
The agent type: 'manager' for a group manager agent
|
|
24
|
+
data : WaldiezGroupManagerData
|
|
25
|
+
The group manager agent's data.
|
|
26
|
+
|
|
27
|
+
Functions
|
|
28
|
+
---------
|
|
29
|
+
validate_transitions(agent_ids: List[str])
|
|
30
|
+
Validate the transitions.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
agent_type: Annotated[
|
|
34
|
+
Literal["manager"],
|
|
35
|
+
Field(
|
|
36
|
+
"manager",
|
|
37
|
+
title="Agent type",
|
|
38
|
+
description="The agent type: 'manager' for a group manager agent",
|
|
39
|
+
alias="agentType",
|
|
40
|
+
),
|
|
41
|
+
]
|
|
42
|
+
data: Annotated[
|
|
43
|
+
WaldiezGroupManagerData,
|
|
44
|
+
Field(
|
|
45
|
+
title="Data",
|
|
46
|
+
description="The group manager agent's data",
|
|
47
|
+
default_factory=WaldiezGroupManagerData,
|
|
48
|
+
),
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
def validate_transitions(self, agent_ids: List[str]) -> None:
|
|
52
|
+
"""Validate the transitions.
|
|
53
|
+
|
|
54
|
+
If the selection mode is `transition`:
|
|
55
|
+
|
|
56
|
+
- if `allow_repeat` is a list of agent_ids,
|
|
57
|
+
make sure these ids exist.
|
|
58
|
+
- make sure the `allowed_or_disallowed_transitions` mapping
|
|
59
|
+
has valid agent ids.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
agent_ids : List[str]
|
|
64
|
+
The list of agent IDs.
|
|
65
|
+
|
|
66
|
+
Raises
|
|
67
|
+
------
|
|
68
|
+
ValueError
|
|
69
|
+
If the transitions are invalid.
|
|
70
|
+
"""
|
|
71
|
+
speakers: WaldiezGroupManagerSpeakers = self.data.speakers
|
|
72
|
+
if speakers.selection_mode != "transition":
|
|
73
|
+
return
|
|
74
|
+
allow_repeat = speakers.allow_repeat
|
|
75
|
+
if isinstance(allow_repeat, list):
|
|
76
|
+
for agent_id in allow_repeat:
|
|
77
|
+
if agent_id not in agent_ids:
|
|
78
|
+
raise ValueError(f"Invalid agent id: {agent_id}")
|
|
79
|
+
for (
|
|
80
|
+
agent_id,
|
|
81
|
+
transitions,
|
|
82
|
+
) in speakers.allowed_or_disallowed_transitions.items():
|
|
83
|
+
if agent_id not in agent_ids:
|
|
84
|
+
raise ValueError(f"Invalid agent id: {agent_id}")
|
|
85
|
+
for agent_id in transitions:
|
|
86
|
+
if agent_id not in agent_ids:
|
|
87
|
+
raise ValueError(f"Invalid agent id: {agent_id}")
|