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.

Files changed (94) hide show
  1. waldiez/__init__.py +15 -0
  2. waldiez/__main__.py +6 -0
  3. waldiez/_version.py +3 -0
  4. waldiez/cli.py +162 -0
  5. waldiez/exporter.py +293 -0
  6. waldiez/exporting/__init__.py +14 -0
  7. waldiez/exporting/agents/__init__.py +5 -0
  8. waldiez/exporting/agents/agent.py +229 -0
  9. waldiez/exporting/agents/agent_skills.py +67 -0
  10. waldiez/exporting/agents/code_execution.py +67 -0
  11. waldiez/exporting/agents/group_manager.py +209 -0
  12. waldiez/exporting/agents/llm_config.py +53 -0
  13. waldiez/exporting/agents/rag_user/__init__.py +5 -0
  14. waldiez/exporting/agents/rag_user/chroma_utils.py +134 -0
  15. waldiez/exporting/agents/rag_user/mongo_utils.py +83 -0
  16. waldiez/exporting/agents/rag_user/pgvector_utils.py +93 -0
  17. waldiez/exporting/agents/rag_user/qdrant_utils.py +112 -0
  18. waldiez/exporting/agents/rag_user/rag_user.py +165 -0
  19. waldiez/exporting/agents/rag_user/vector_db.py +119 -0
  20. waldiez/exporting/agents/teachability.py +37 -0
  21. waldiez/exporting/agents/termination_message.py +45 -0
  22. waldiez/exporting/chats/__init__.py +14 -0
  23. waldiez/exporting/chats/chats.py +46 -0
  24. waldiez/exporting/chats/helpers.py +395 -0
  25. waldiez/exporting/chats/nested.py +264 -0
  26. waldiez/exporting/flow/__init__.py +5 -0
  27. waldiez/exporting/flow/def_main.py +37 -0
  28. waldiez/exporting/flow/flow.py +185 -0
  29. waldiez/exporting/models/__init__.py +193 -0
  30. waldiez/exporting/skills/__init__.py +128 -0
  31. waldiez/exporting/utils/__init__.py +34 -0
  32. waldiez/exporting/utils/comments.py +136 -0
  33. waldiez/exporting/utils/importing.py +267 -0
  34. waldiez/exporting/utils/logging_utils.py +203 -0
  35. waldiez/exporting/utils/method_utils.py +35 -0
  36. waldiez/exporting/utils/naming.py +127 -0
  37. waldiez/exporting/utils/object_string.py +81 -0
  38. waldiez/io_stream.py +181 -0
  39. waldiez/models/__init__.py +107 -0
  40. waldiez/models/agents/__init__.py +65 -0
  41. waldiez/models/agents/agent/__init__.py +21 -0
  42. waldiez/models/agents/agent/agent.py +190 -0
  43. waldiez/models/agents/agent/agent_data.py +162 -0
  44. waldiez/models/agents/agent/code_execution.py +71 -0
  45. waldiez/models/agents/agent/linked_skill.py +30 -0
  46. waldiez/models/agents/agent/nested_chat.py +73 -0
  47. waldiez/models/agents/agent/teachability.py +68 -0
  48. waldiez/models/agents/agent/termination_message.py +167 -0
  49. waldiez/models/agents/agents.py +129 -0
  50. waldiez/models/agents/assistant/__init__.py +6 -0
  51. waldiez/models/agents/assistant/assistant.py +41 -0
  52. waldiez/models/agents/assistant/assistant_data.py +29 -0
  53. waldiez/models/agents/group_manager/__init__.py +19 -0
  54. waldiez/models/agents/group_manager/group_manager.py +87 -0
  55. waldiez/models/agents/group_manager/group_manager_data.py +91 -0
  56. waldiez/models/agents/group_manager/speakers.py +211 -0
  57. waldiez/models/agents/rag_user/__init__.py +26 -0
  58. waldiez/models/agents/rag_user/rag_user.py +58 -0
  59. waldiez/models/agents/rag_user/rag_user_data.py +32 -0
  60. waldiez/models/agents/rag_user/retrieve_config.py +592 -0
  61. waldiez/models/agents/rag_user/vector_db_config.py +162 -0
  62. waldiez/models/agents/user_proxy/__init__.py +6 -0
  63. waldiez/models/agents/user_proxy/user_proxy.py +41 -0
  64. waldiez/models/agents/user_proxy/user_proxy_data.py +30 -0
  65. waldiez/models/chat/__init__.py +22 -0
  66. waldiez/models/chat/chat.py +129 -0
  67. waldiez/models/chat/chat_data.py +326 -0
  68. waldiez/models/chat/chat_message.py +304 -0
  69. waldiez/models/chat/chat_nested.py +160 -0
  70. waldiez/models/chat/chat_summary.py +110 -0
  71. waldiez/models/common/__init__.py +38 -0
  72. waldiez/models/common/base.py +63 -0
  73. waldiez/models/common/method_utils.py +165 -0
  74. waldiez/models/flow/__init__.py +9 -0
  75. waldiez/models/flow/flow.py +302 -0
  76. waldiez/models/flow/flow_data.py +87 -0
  77. waldiez/models/model/__init__.py +11 -0
  78. waldiez/models/model/model.py +169 -0
  79. waldiez/models/model/model_data.py +86 -0
  80. waldiez/models/skill/__init__.py +9 -0
  81. waldiez/models/skill/skill.py +129 -0
  82. waldiez/models/skill/skill_data.py +37 -0
  83. waldiez/models/waldiez.py +301 -0
  84. waldiez/py.typed +0 -0
  85. waldiez/runner.py +304 -0
  86. waldiez/stream/__init__.py +7 -0
  87. waldiez/stream/consumer.py +139 -0
  88. waldiez/stream/provider.py +339 -0
  89. waldiez/stream/server.py +412 -0
  90. waldiez-0.1.0.dist-info/METADATA +181 -0
  91. waldiez-0.1.0.dist-info/RECORD +94 -0
  92. waldiez-0.1.0.dist-info/WHEEL +4 -0
  93. waldiez-0.1.0.dist-info/entry_points.txt +2 -0
  94. waldiez-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,129 @@
1
+ """Waldiez Skill model."""
2
+
3
+ from typing import Dict, List
4
+
5
+ from pydantic import Field, model_validator
6
+ from typing_extensions import Annotated, Literal, Self
7
+
8
+ from ..common import WaldiezBase, now, parse_code_string
9
+ from .skill_data import WaldiezSkillData
10
+
11
+
12
+ class WaldiezSkill(WaldiezBase):
13
+ """Waldiez Skill.
14
+
15
+ Attributes
16
+ ----------
17
+ id : str
18
+ The ID of the skill.
19
+ type : Literal["skill"]
20
+ The type of the "node" in a graph: "skill".
21
+ name : str
22
+ The name of the skill.
23
+ description : str
24
+ The description of the skill.
25
+ tags : List[str]
26
+ The tags of the skill.
27
+ requirements : List[str]
28
+ The requirements of the skill.
29
+ created_at : str
30
+ The date and time when the skill was created.
31
+ updated_at : str
32
+ The date and time when the skill was last updated.
33
+ data : WaldiezSkillData
34
+ The data of the skill. See `WaldiezSkillData`.
35
+ """
36
+
37
+ id: Annotated[
38
+ str, Field(..., title="ID", description="The ID of the skill.")
39
+ ]
40
+ type: Annotated[
41
+ Literal["skill"],
42
+ Field(
43
+ default="skill",
44
+ title="Type",
45
+ description="The type of the 'node' in a graph.",
46
+ ),
47
+ ]
48
+ name: Annotated[
49
+ str, Field(..., title="Name", description="The name of the skill.")
50
+ ]
51
+ description: Annotated[
52
+ str,
53
+ Field(
54
+ ...,
55
+ title="Description",
56
+ description="The description of the skill.",
57
+ ),
58
+ ]
59
+ tags: Annotated[
60
+ List[str],
61
+ Field(
62
+ title="Tags",
63
+ description="The tags of the skill.",
64
+ default_factory=list,
65
+ ),
66
+ ]
67
+ requirements: Annotated[
68
+ List[str],
69
+ Field(
70
+ title="Requirements",
71
+ description="The requirements of the skill.",
72
+ default_factory=list,
73
+ ),
74
+ ]
75
+ data: Annotated[
76
+ WaldiezSkillData,
77
+ Field(..., title="Data", description="The data of the skill."),
78
+ ]
79
+ created_at: Annotated[
80
+ str,
81
+ Field(
82
+ default_factory=now,
83
+ title="Created At",
84
+ description="The date and time when the skill was created.",
85
+ ),
86
+ ]
87
+ updated_at: Annotated[
88
+ str,
89
+ Field(
90
+ default_factory=now,
91
+ title="Updated At",
92
+ description="The date and time when the skill was last updated.",
93
+ ),
94
+ ]
95
+
96
+ @model_validator(mode="after")
97
+ def validate_data(self) -> Self:
98
+ """Validate the data.
99
+
100
+ Returns
101
+ -------
102
+ WaldiezSkill
103
+ The skill.
104
+
105
+ Raises
106
+ ------
107
+ ValueError
108
+ If the skill name is not in the content.
109
+ If the skill content is invalid.
110
+ """
111
+ search = f"def {self.name}("
112
+ if search not in self.data.content:
113
+ raise ValueError(
114
+ f"The skill name '{self.name}' is not in the content."
115
+ )
116
+ error, tree = parse_code_string(self.data.content)
117
+ if error is not None or tree is None:
118
+ raise ValueError(f"Invalid skill content: {error}")
119
+ return self
120
+
121
+ @property
122
+ def content(self) -> str:
123
+ """Get the content (source) of the skill."""
124
+ return self.data.content
125
+
126
+ @property
127
+ def secrets(self) -> Dict[str, str]:
128
+ """Get the secrets (environment variables) of the skill."""
129
+ return self.data.secrets or {}
@@ -0,0 +1,37 @@
1
+ """Waldiez Skill model."""
2
+
3
+ from typing import Dict
4
+
5
+ from pydantic import Field
6
+ from typing_extensions import Annotated
7
+
8
+ from ..common import WaldiezBase
9
+
10
+
11
+ class WaldiezSkillData(WaldiezBase):
12
+ """Waldiez Skill Data.
13
+
14
+ Attributes
15
+ ----------
16
+ content : str
17
+ The content (source code) of the skill.
18
+ secrets : Dict[str, str]
19
+ The secrets (environment variables) of the skill.
20
+ """
21
+
22
+ content: Annotated[
23
+ str,
24
+ Field(
25
+ ...,
26
+ title="Content",
27
+ description="The content (source code) of the skill.",
28
+ ),
29
+ ]
30
+ secrets: Annotated[
31
+ Dict[str, str],
32
+ Field(
33
+ default_factory=dict,
34
+ title="Secrets",
35
+ description="The secrets (environment variables) of the skill.",
36
+ ),
37
+ ]
@@ -0,0 +1,301 @@
1
+ """Waldiez data class.
2
+
3
+ A Waldiez class contains all the information that is needed to generate
4
+ and run an autogen workflow. It has the model/LLM configurations, the agent
5
+ definitions and their optional additional skills to be used.
6
+ """
7
+
8
+ import json
9
+ from dataclasses import dataclass
10
+ from pathlib import Path
11
+ from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
12
+
13
+ # let's be strict with autogen version
14
+ from autogen.version import __version__ as autogen_version # type: ignore
15
+
16
+ from .agents import WaldiezAgent
17
+ from .chat import WaldiezChat
18
+ from .flow import WaldiezFlow
19
+ from .model import WaldiezModel
20
+ from .skill import WaldiezSkill
21
+
22
+
23
+ @dataclass(frozen=True, slots=True)
24
+ class Waldiez:
25
+ """Waldiez data class.
26
+
27
+ It contains all the information to generate and run an autogen workflow.
28
+ """
29
+
30
+ flow: WaldiezFlow
31
+
32
+ @classmethod
33
+ def from_dict(
34
+ cls,
35
+ data: Dict[str, Any],
36
+ flow_id: Optional[str] = None,
37
+ name: Optional[str] = None,
38
+ description: Optional[str] = None,
39
+ tags: Optional[List[str]] = None,
40
+ requirements: Optional[List[str]] = None,
41
+ ) -> "Waldiez":
42
+ """Create a Waldiez from dict.
43
+
44
+ Parameters
45
+ ----------
46
+ data : Dict[str, Any]
47
+ The data.
48
+ flow_id : Optional[str], optional
49
+ The flow id, by default None (retrieved from data or generated).
50
+ name : Optional[str], optional
51
+ The name, by default None (retrieved from data).
52
+ description : Optional[str], optional
53
+ The description, by default None (retrieved from data).
54
+ tags : Optional[List[str]], optional
55
+ The tags, by default None (retrieved from data).
56
+ requirements : Optional[List[str]], optional
57
+ The requirements, by default None (retrieved from data).
58
+
59
+ Returns
60
+ -------
61
+ Waldiez
62
+ The Waldiez.
63
+ """
64
+ flow = _get_flow(
65
+ data,
66
+ flow_id=flow_id,
67
+ name=name,
68
+ description=description,
69
+ tags=tags,
70
+ requirements=requirements,
71
+ )
72
+ return cls(flow=WaldiezFlow.model_validate(flow))
73
+
74
+ @classmethod
75
+ def load(
76
+ cls,
77
+ waldiez_file: Union[str, Path],
78
+ name: Optional[str] = None,
79
+ description: Optional[str] = None,
80
+ tags: Optional[List[str]] = None,
81
+ requirements: Optional[List[str]] = None,
82
+ ) -> "Waldiez":
83
+ """Load a Waldiez from a file.
84
+
85
+ Parameters
86
+ ----------
87
+ waldiez_file : Union[str, Path]
88
+ The Waldiez file.
89
+ name : Optional[str], optional
90
+ The name, by default None.
91
+ description : Optional[str], optional
92
+ The description, by default None.
93
+ tags : Optional[List[str]], optional
94
+ The tags, by default None.
95
+ requirements : Optional[List[str]], optional
96
+ The requirements, by default None.
97
+
98
+ Returns
99
+ -------
100
+ Waldiez
101
+ The Waldiez.
102
+
103
+ Raises
104
+ ------
105
+ ValueError
106
+ If the file is not found or invalid JSON.
107
+ """
108
+ data: Dict[str, Any] = {}
109
+ if not Path(waldiez_file).exists():
110
+ raise ValueError(f"File not found: {waldiez_file}")
111
+ with open(waldiez_file, "r", encoding="utf-8") as file:
112
+ try:
113
+ data = json.load(file)
114
+ except json.decoder.JSONDecodeError as error:
115
+ raise ValueError(f"Invalid JSON: {waldiez_file}") from error
116
+ return cls.from_dict(
117
+ data,
118
+ name=name,
119
+ description=description,
120
+ tags=tags,
121
+ requirements=requirements,
122
+ )
123
+
124
+ def model_dump_json(
125
+ self, by_alias: bool = True, indent: Optional[int] = None
126
+ ) -> str:
127
+ """Get the model dump json.
128
+
129
+ We use `by_alias=True` by default to use the alias (toCamel).
130
+
131
+ Parameters
132
+ ----------
133
+ by_alias : bool, optional
134
+ Use alias (toCamel), by default True.
135
+ indent : Optional[int], optional
136
+ The indent, by default None.
137
+
138
+ Returns
139
+ -------
140
+ str
141
+ The model dump json.
142
+ """
143
+ return self.flow.model_dump_json(by_alias=by_alias, indent=indent)
144
+
145
+ @property
146
+ def has_rag_agents(self) -> bool:
147
+ """Check if the flow has RAG agents."""
148
+ return any(agent.agent_type == "rag_user" for agent in self.agents)
149
+
150
+ @property
151
+ def chats(self) -> List[Tuple[WaldiezChat, WaldiezAgent, WaldiezAgent]]:
152
+ """Get the chats."""
153
+ return self.flow.ordered_flow
154
+
155
+ @property
156
+ def agents(self) -> Iterator[WaldiezAgent]:
157
+ """Get the agents.
158
+
159
+ Yields
160
+ -------
161
+ WaldiezAgent
162
+ The flow agents.
163
+ """
164
+ yield from self.flow.data.agents.members
165
+
166
+ @property
167
+ def skills(self) -> Iterator[WaldiezSkill]:
168
+ """Get the flow skills.
169
+
170
+ Yields
171
+ -------
172
+ WaldiezSkill
173
+ The skills.
174
+ """
175
+ yield from self.flow.data.skills
176
+
177
+ @property
178
+ def models(self) -> Iterator[WaldiezModel]:
179
+ """Get the models.
180
+
181
+ Yields
182
+ -------
183
+ WaldiezModel
184
+ The flow models.
185
+ """
186
+ yield from self.flow.data.models
187
+
188
+ @property
189
+ def name(self) -> str:
190
+ """Get the flow name."""
191
+ return self.flow.name or "Waldiez Flow"
192
+
193
+ @property
194
+ def description(self) -> str:
195
+ """Get the flow description."""
196
+ return self.flow.description or "Waldiez Flow description"
197
+
198
+ @property
199
+ def tags(self) -> List[str]:
200
+ """Get the flow tags."""
201
+ return self.flow.tags
202
+
203
+ @property
204
+ def requirements(self) -> List[str]:
205
+ """Get the flow requirements."""
206
+ requirements_list = filter(
207
+ lambda requirement: not (
208
+ requirement.startswith("pyautogen")
209
+ or requirement.startswith("autogen-agentchat")
210
+ ),
211
+ self.flow.requirements,
212
+ )
213
+ requirements = set(requirements_list)
214
+ if self.has_rag_agents:
215
+ requirements.add(
216
+ f"autogen-agentchat[retrievechat]=={autogen_version}"
217
+ )
218
+ else:
219
+ requirements.add(f"autogen-agentchat=={autogen_version}")
220
+ # ref: https://github.com/microsoft/autogen/blob/main/setup.py
221
+ models_with_additional_requirements = [
222
+ "together",
223
+ "gemini",
224
+ "mistral",
225
+ "groq",
226
+ "anthropic",
227
+ "cohere",
228
+ "bedrock",
229
+ ]
230
+ for model in self.models:
231
+ if model.data.api_type in models_with_additional_requirements:
232
+ requirements.add(
233
+ f"autogen-agentchat[{model.data.api_type}]=="
234
+ f"{autogen_version}"
235
+ )
236
+ return list(requirements)
237
+
238
+ def get_flow_env_vars(self) -> List[Tuple[str, str]]:
239
+ """Get the flow environment variables.
240
+
241
+ Returns
242
+ -------
243
+ List[Tuple[str, str]]
244
+ The environment variables for the flow.
245
+ """
246
+ env_vars: List[Tuple[str, str]] = []
247
+ for skill in self.skills:
248
+ for secret_key, secret_value in skill.secrets.items():
249
+ env_vars.append((secret_key, secret_value))
250
+ return env_vars
251
+
252
+ def get_group_chat_members(self, agent: WaldiezAgent) -> List[WaldiezAgent]:
253
+ """Get the chat members that connect to a group chat manger agent.
254
+
255
+ Parameters
256
+ ----------
257
+ agent : WaldiezAgent
258
+ The agent (group chat manager).
259
+
260
+ Returns
261
+ -------
262
+ List[WaldiezAgent]
263
+ The group chat members.
264
+ """
265
+ if agent.agent_type != "manager":
266
+ return []
267
+ return self.flow.get_group_chat_members(agent.id)
268
+
269
+
270
+ def _get_flow(
271
+ data: Dict[str, Any],
272
+ flow_id: Optional[str] = None,
273
+ name: Optional[str] = None,
274
+ description: Optional[str] = None,
275
+ tags: Optional[List[str]] = None,
276
+ requirements: Optional[List[str]] = None,
277
+ ) -> Dict[str, Any]:
278
+ """Get the flow."""
279
+ item_type = data.get("type", "flow")
280
+ if item_type != "flow":
281
+ # empty flow (from exported model/skill ?)
282
+ raise ValueError(f"Invalid flow type: {item_type}")
283
+ from_args = {
284
+ "id": flow_id,
285
+ "name": name,
286
+ "description": description,
287
+ "tags": tags,
288
+ "requirements": requirements,
289
+ }
290
+ for key, value in from_args.items():
291
+ if value:
292
+ data[key] = value
293
+ if "name" not in data:
294
+ data["name"] = "Waldiez Flow"
295
+ if "description" not in data:
296
+ data["description"] = "Waldiez Flow description"
297
+ if "tags" not in data:
298
+ data["tags"] = []
299
+ if "requirements" not in data:
300
+ data["requirements"] = []
301
+ return data
waldiez/py.typed ADDED
File without changes