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.

Files changed (138) hide show
  1. waldiez/__init__.py +2 -0
  2. waldiez/__main__.py +2 -0
  3. waldiez/_version.py +3 -1
  4. waldiez/cli.py +13 -3
  5. waldiez/cli_extras.py +4 -3
  6. waldiez/conflict_checker.py +4 -3
  7. waldiez/exporter.py +28 -105
  8. waldiez/exporting/__init__.py +8 -9
  9. waldiez/exporting/agent/__init__.py +7 -0
  10. waldiez/exporting/agent/agent_exporter.py +279 -0
  11. waldiez/exporting/agent/utils/__init__.py +23 -0
  12. waldiez/exporting/agent/utils/agent_class_name.py +34 -0
  13. waldiez/exporting/agent/utils/agent_imports.py +50 -0
  14. waldiez/exporting/{agents → agent/utils}/code_execution.py +9 -11
  15. waldiez/exporting/{agents → agent/utils}/group_manager.py +47 -35
  16. waldiez/exporting/{agents → agent/utils}/rag_user/__init__.py +2 -0
  17. waldiez/exporting/{agents → agent/utils}/rag_user/chroma_utils.py +22 -17
  18. waldiez/exporting/{agents → agent/utils}/rag_user/mongo_utils.py +14 -10
  19. waldiez/exporting/{agents → agent/utils}/rag_user/pgvector_utils.py +12 -8
  20. waldiez/exporting/{agents → agent/utils}/rag_user/qdrant_utils.py +11 -8
  21. waldiez/exporting/{agents → agent/utils}/rag_user/rag_user.py +78 -55
  22. waldiez/exporting/{agents → agent/utils}/rag_user/vector_db.py +10 -8
  23. waldiez/exporting/agent/utils/swarm_agent.py +463 -0
  24. waldiez/exporting/{agents → agent/utils}/teachability.py +10 -6
  25. waldiez/exporting/{agents → agent/utils}/termination_message.py +7 -8
  26. waldiez/exporting/base/__init__.py +25 -0
  27. waldiez/exporting/base/agent_position.py +75 -0
  28. waldiez/exporting/base/base_exporter.py +118 -0
  29. waldiez/exporting/base/export_position.py +48 -0
  30. waldiez/exporting/base/import_position.py +23 -0
  31. waldiez/exporting/base/mixin.py +134 -0
  32. waldiez/exporting/base/utils/__init__.py +18 -0
  33. waldiez/exporting/{utils → base/utils}/comments.py +12 -55
  34. waldiez/exporting/{utils → base/utils}/naming.py +14 -4
  35. waldiez/exporting/base/utils/path_check.py +68 -0
  36. waldiez/exporting/{utils/object_string.py → base/utils/to_string.py} +21 -20
  37. waldiez/exporting/chats/__init__.py +5 -12
  38. waldiez/exporting/chats/chats_exporter.py +240 -0
  39. waldiez/exporting/chats/utils/__init__.py +15 -0
  40. waldiez/exporting/chats/utils/common.py +81 -0
  41. waldiez/exporting/chats/{nested.py → utils/nested.py} +125 -86
  42. waldiez/exporting/chats/utils/sequential.py +244 -0
  43. waldiez/exporting/chats/utils/single_chat.py +313 -0
  44. waldiez/exporting/chats/utils/swarm.py +207 -0
  45. waldiez/exporting/flow/__init__.py +5 -3
  46. waldiez/exporting/flow/flow_exporter.py +503 -0
  47. waldiez/exporting/flow/utils/__init__.py +47 -0
  48. waldiez/exporting/flow/utils/agent_utils.py +204 -0
  49. waldiez/exporting/flow/utils/chat_utils.py +71 -0
  50. waldiez/exporting/flow/utils/def_main.py +62 -0
  51. waldiez/exporting/flow/utils/flow_content.py +112 -0
  52. waldiez/exporting/flow/utils/flow_names.py +115 -0
  53. waldiez/exporting/flow/utils/importing_utils.py +182 -0
  54. waldiez/exporting/{utils → flow/utils}/logging_utils.py +34 -31
  55. waldiez/exporting/models/__init__.py +7 -242
  56. waldiez/exporting/models/models_exporter.py +192 -0
  57. waldiez/exporting/models/utils.py +166 -0
  58. waldiez/exporting/skills/__init__.py +7 -161
  59. waldiez/exporting/skills/skills_exporter.py +169 -0
  60. waldiez/exporting/skills/utils.py +281 -0
  61. waldiez/models/__init__.py +25 -7
  62. waldiez/models/agents/__init__.py +70 -0
  63. waldiez/models/agents/agent/__init__.py +11 -1
  64. waldiez/models/agents/agent/agent.py +9 -4
  65. waldiez/models/agents/agent/agent_data.py +3 -1
  66. waldiez/models/agents/agent/code_execution.py +2 -0
  67. waldiez/models/agents/agent/linked_skill.py +2 -0
  68. waldiez/models/agents/agent/nested_chat.py +2 -0
  69. waldiez/models/agents/agent/teachability.py +2 -0
  70. waldiez/models/agents/agent/termination_message.py +49 -13
  71. waldiez/models/agents/agents.py +15 -3
  72. waldiez/models/agents/assistant/__init__.py +2 -0
  73. waldiez/models/agents/assistant/assistant.py +2 -0
  74. waldiez/models/agents/assistant/assistant_data.py +2 -0
  75. waldiez/models/agents/group_manager/__init__.py +9 -1
  76. waldiez/models/agents/group_manager/group_manager.py +2 -0
  77. waldiez/models/agents/group_manager/group_manager_data.py +2 -0
  78. waldiez/models/agents/group_manager/speakers.py +49 -13
  79. waldiez/models/agents/rag_user/__init__.py +21 -4
  80. waldiez/models/agents/rag_user/rag_user.py +3 -1
  81. waldiez/models/agents/rag_user/rag_user_data.py +2 -0
  82. waldiez/models/agents/rag_user/retrieve_config.py +268 -17
  83. waldiez/models/agents/rag_user/vector_db_config.py +5 -3
  84. waldiez/models/agents/swarm_agent/__init__.py +49 -0
  85. waldiez/models/agents/swarm_agent/after_work.py +178 -0
  86. waldiez/models/agents/swarm_agent/on_condition.py +103 -0
  87. waldiez/models/agents/swarm_agent/on_condition_available.py +140 -0
  88. waldiez/models/agents/swarm_agent/on_condition_target.py +40 -0
  89. waldiez/models/agents/swarm_agent/swarm_agent.py +107 -0
  90. waldiez/models/agents/swarm_agent/swarm_agent_data.py +125 -0
  91. waldiez/models/agents/swarm_agent/update_system_message.py +144 -0
  92. waldiez/models/agents/user_proxy/__init__.py +2 -0
  93. waldiez/models/agents/user_proxy/user_proxy.py +2 -0
  94. waldiez/models/agents/user_proxy/user_proxy_data.py +2 -0
  95. waldiez/models/chat/__init__.py +21 -3
  96. waldiez/models/chat/chat.py +241 -7
  97. waldiez/models/chat/chat_data.py +192 -48
  98. waldiez/models/chat/chat_message.py +153 -144
  99. waldiez/models/chat/chat_nested.py +33 -53
  100. waldiez/models/chat/chat_summary.py +2 -0
  101. waldiez/models/common/__init__.py +6 -6
  102. waldiez/models/common/base.py +4 -1
  103. waldiez/models/common/method_utils.py +163 -83
  104. waldiez/models/flow/__init__.py +2 -0
  105. waldiez/models/flow/flow.py +176 -40
  106. waldiez/models/flow/flow_data.py +63 -2
  107. waldiez/models/flow/utils.py +172 -0
  108. waldiez/models/model/__init__.py +2 -0
  109. waldiez/models/model/model.py +30 -9
  110. waldiez/models/model/model_data.py +3 -1
  111. waldiez/models/skill/__init__.py +4 -1
  112. waldiez/models/skill/skill.py +30 -2
  113. waldiez/models/skill/skill_data.py +2 -0
  114. waldiez/models/waldiez.py +28 -4
  115. waldiez/runner.py +142 -228
  116. waldiez/running/__init__.py +33 -0
  117. waldiez/running/environment.py +83 -0
  118. waldiez/running/gen_seq_diagram.py +185 -0
  119. waldiez/running/running.py +300 -0
  120. {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/METADATA +35 -28
  121. waldiez-0.3.1.dist-info/RECORD +125 -0
  122. waldiez-0.3.1.dist-info/licenses/LICENSE +201 -0
  123. waldiez/exporting/agents/__init__.py +0 -5
  124. waldiez/exporting/agents/agent.py +0 -236
  125. waldiez/exporting/agents/agent_skills.py +0 -67
  126. waldiez/exporting/agents/llm_config.py +0 -53
  127. waldiez/exporting/chats/chats.py +0 -46
  128. waldiez/exporting/chats/helpers.py +0 -420
  129. waldiez/exporting/flow/def_main.py +0 -32
  130. waldiez/exporting/flow/flow.py +0 -189
  131. waldiez/exporting/utils/__init__.py +0 -36
  132. waldiez/exporting/utils/importing.py +0 -265
  133. waldiez/exporting/utils/method_utils.py +0 -35
  134. waldiez/exporting/utils/path_check.py +0 -51
  135. waldiez-0.2.2.dist-info/RECORD +0 -92
  136. waldiez-0.2.2.dist-info/licenses/LICENSE +0 -21
  137. {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/WHEEL +0 -0
  138. {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/entry_points.txt +0 -0
waldiez/__init__.py CHANGED
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Waldiez package."""
2
4
 
3
5
  import logging
waldiez/__main__.py CHANGED
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Waldiez entrypoint when called as a module."""
2
4
 
3
5
  from .cli import app
waldiez/_version.py CHANGED
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Version information for Waldiez."""
2
4
 
3
- __version__ = "0.2.2"
5
+ __version__ = "0.3.1"
waldiez/cli.py CHANGED
@@ -1,6 +1,8 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=missing-function-docstring,missing-param-doc,missing-raises-doc # noqa: E501
1
4
  """Command line interface to convert or run a waldiez file."""
2
5
 
3
- # pylint: disable=missing-function-docstring,missing-param-doc,missing-raises-doc # noqa: E501
4
6
  import json
5
7
  import logging
6
8
  import os
@@ -9,6 +11,7 @@ import warnings
9
11
  from pathlib import Path
10
12
  from typing import TYPE_CHECKING, Optional
11
13
 
14
+ import anyio
12
15
  import typer
13
16
  from typing_extensions import Annotated
14
17
 
@@ -87,6 +90,10 @@ def run(
87
90
  ),
88
91
  ) -> None:
89
92
  """Run a Waldiez flow."""
93
+ # swarm without a user,
94
+ # creates a new user (this has a default code execution with docker)
95
+ # temp (until we handle/detect docker setup)
96
+ os.environ["AUTOGEN_USE_DOCKER"] = "0"
90
97
  output_path = _get_output_path(output, force)
91
98
  with file.open("r", encoding="utf-8") as _file:
92
99
  try:
@@ -96,14 +103,17 @@ def run(
96
103
  raise typer.Exit(code=1) from error
97
104
  waldiez = Waldiez.from_dict(data)
98
105
  runner = WaldiezRunner(waldiez)
99
- results = runner.run(output_path=output_path)
106
+ if waldiez.is_async:
107
+ results = anyio.run(runner.a_run, output_path)
108
+ else:
109
+ results = runner.run(output_path=output_path)
100
110
  logger = _get_logger()
101
111
  if isinstance(results, list):
102
112
  logger.info("Results:")
103
113
  for result in results:
104
114
  _log_result(result, logger)
105
115
  sep = "-" * 80
106
- print(f"\n{sep}\n")
116
+ print("\n" + f"{sep}" + "\n")
107
117
  else:
108
118
  _log_result(results, logger)
109
119
 
waldiez/cli_extras.py CHANGED
@@ -1,6 +1,7 @@
1
- # type: ignore
2
- # flake8: noqa
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
3
  # pylint: skip-file
4
+ # type: ignore
4
5
  # isort: skip_file
5
6
  """Extra typer commands for CLI."""
6
7
 
@@ -20,7 +21,7 @@ except BaseException:
20
21
  pass
21
22
 
22
23
  try:
23
- import waldiez_jupyter
24
+ import waldiez_jupyter # noqa: F401
24
25
 
25
26
  HAVE_JUPYTER = True
26
27
  except BaseException:
@@ -1,6 +1,7 @@
1
- """Check for conflicts with 'autogen-agentchat' package."""
2
-
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
3
  # pylint: disable=line-too-long
4
+ """Check for conflicts with 'autogen-agentchat' package."""
4
5
 
5
6
  import sys
6
7
  from importlib.metadata import PackageNotFoundError, version
@@ -16,7 +17,7 @@ def check_conflicts() -> None: # pragma: no cover
16
17
  "in the current environment, \n"
17
18
  "which conflicts with 'ag2' / 'pyautogen'.\n"
18
19
  "Please uninstall 'autogen-agentchat': \n"
19
- f"{sys.executable} -m pip uninstall -y autogen-agentchat \n"
20
+ f"{sys.executable} -m pip uninstall -y autogen-agentchat" + "\n"
20
21
  "And install 'pyautogen' (and/or 'waldiez') again: \n"
21
22
  f"{sys.executable} -m pip install --force pyautogen waldiez"
22
23
  )
waldiez/exporter.py CHANGED
@@ -1,5 +1,6 @@
1
- """Waldiez exporter.
2
-
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """
3
4
  The role of the exporter is to export the model's data
4
5
  to an autogen's flow with one or more chats.
5
6
 
@@ -8,8 +9,8 @@ to trigger the chat(s).
8
9
  If additional tools/skills are used,
9
10
  they are exported as their `skill_name` in the same directory with
10
11
  the `flow.py` file. So the `flow.py` could have entries like:
11
- `form {skill1_name} import {skill1_name}`
12
- `form {skill2_name} import {skill2_name}`
12
+ `form {flow_name}_{skill1_name} import {skill1_name}`
13
+ `form {flow_name}_{skill2_name} import {skill2_name}`
13
14
  """
14
15
 
15
16
  # pylint: disable=inconsistent-quotes
@@ -19,16 +20,10 @@ import shutil
19
20
  import subprocess
20
21
  import sys
21
22
  from pathlib import Path
22
- from typing import Dict, List, Optional, Union
23
+ from typing import List, Optional, Union
23
24
 
24
- from .exporting import comment, export_flow, get_valid_instance_name
25
- from .models import (
26
- Waldiez,
27
- WaldiezAgent,
28
- WaldiezChat,
29
- WaldiezModel,
30
- WaldiezSkill,
31
- )
25
+ from .exporting import FlowExporter
26
+ from .models import Waldiez
32
27
 
33
28
 
34
29
  class WaldiezExporter:
@@ -38,15 +33,6 @@ class WaldiezExporter:
38
33
  waldiez (Waldiez): The Waldiez instance.
39
34
  """
40
35
 
41
- _agent_names: Dict[str, str]
42
- _model_names: Dict[str, str]
43
- _skill_names: Dict[str, str]
44
- _chat_names: Dict[str, str]
45
- _chats: List[WaldiezChat]
46
- _skills: List[WaldiezSkill]
47
- _models: List[WaldiezModel]
48
- _agents: List[WaldiezAgent]
49
-
50
36
  def __init__(self, waldiez: Waldiez) -> None:
51
37
  """Initialize the Waldiez exporter.
52
38
 
@@ -54,7 +40,7 @@ class WaldiezExporter:
54
40
  waldiez (Waldiez): The Waldiez instance.
55
41
  """
56
42
  self.waldiez = waldiez
57
- self._initialize()
43
+ # self._initialize()
58
44
 
59
45
  @classmethod
60
46
  def load(cls, file_path: Path) -> "WaldiezExporter":
@@ -73,56 +59,6 @@ class WaldiezExporter:
73
59
  waldiez = Waldiez.load(file_path)
74
60
  return cls(waldiez)
75
61
 
76
- def _initialize(
77
- self,
78
- ) -> None:
79
- """Get all the names in the flow.
80
-
81
- We need to make sure that no duplicate names are used,
82
- and that the names can be used as python variables.
83
- """
84
- all_names: Dict[str, str] = {}
85
- agent_names: Dict[str, str] = {}
86
- model_names: Dict[str, str] = {}
87
- skill_names: Dict[str, str] = {}
88
- chat_names: Dict[str, str] = {}
89
- chats: List[WaldiezChat] = []
90
- skills: List[WaldiezSkill] = []
91
- models: List[WaldiezModel] = []
92
- agents: List[WaldiezAgent] = []
93
- for agent in self.waldiez.agents:
94
- all_names = get_valid_instance_name(
95
- (agent.id, agent.name), all_names, prefix="wa"
96
- )
97
- agent_names[agent.id] = all_names[agent.id]
98
- agents.append(agent)
99
- for model in self.waldiez.models:
100
- all_names = get_valid_instance_name(
101
- (model.id, model.name), all_names, prefix="wm"
102
- )
103
- model_names[model.id] = all_names[model.id]
104
- models.append(model)
105
- for skill in self.waldiez.skills:
106
- all_names = get_valid_instance_name(
107
- (skill.id, skill.name), all_names, prefix="ws"
108
- )
109
- skill_names[skill.id] = all_names[skill.id]
110
- skills.append(skill)
111
- for chat in self.waldiez.flow.data.chats:
112
- all_names = get_valid_instance_name(
113
- (chat.id, chat.name), all_names, prefix="wc"
114
- )
115
- chat_names[chat.id] = all_names[chat.id]
116
- chats.append(chat)
117
- self._agent_names = agent_names
118
- self._model_names = model_names
119
- self._skill_names = skill_names
120
- self._chat_names = chat_names
121
- self._chats = chats
122
- self._skills = skills
123
- self._models = models
124
- self._agents = agents
125
-
126
62
  def export(self, path: Union[str, Path], force: bool = False) -> None:
127
63
  """Export the Waldiez instance.
128
64
 
@@ -175,25 +111,17 @@ class WaldiezExporter:
175
111
  RuntimeError
176
112
  If the notebook could not be generated.
177
113
  """
178
- content = f"{comment(True)}{self.waldiez.name}" + "\n\n"
179
- content += f"{comment(True, 2)}Dependencies" + "\n\n"
180
- content += "import sys\n"
181
- requirements = " ".join(self.waldiez.requirements)
182
- if requirements:
183
- content += (
184
- f"# !{{sys.executable}} -m pip install -q {requirements}" + "\n"
185
- )
186
- content += export_flow(
114
+ # we first create a .py file with the content
115
+ # and then convert it to a notebook using jupytext
116
+ exporter = FlowExporter(
187
117
  waldiez=self.waldiez,
188
- agents=(self._agents, self._agent_names),
189
- chats=(self._chats, self._chat_names),
190
- models=(self._models, self._model_names),
191
- skills=(self._skills, self._skill_names),
192
118
  output_dir=path.parent,
193
- notebook=True,
119
+ for_notebook=True,
194
120
  )
195
- # we first create a .py file with the content
196
- # and then convert it to a notebook using jupytext
121
+ output = exporter.export()
122
+ content = output["content"]
123
+ if not content:
124
+ raise RuntimeError("Could not generate notebook")
197
125
  py_path = path.with_suffix(".tmp.py")
198
126
  with open(py_path, "w", encoding="utf-8", newline="\n") as f:
199
127
  f.write(content)
@@ -226,26 +154,21 @@ class WaldiezExporter:
226
154
  ----------
227
155
  path : Path
228
156
  The path to export to.
157
+
158
+ Raises
159
+ ------
160
+ RuntimeError
161
+ If the python script could not be generated.
229
162
  """
230
- content = "#!/usr/bin/env python\n"
231
- content += f'"""{self.waldiez.name}\n\n'
232
- content += f"{self.waldiez.description}\n\n"
233
- content += f"Tags: {', '.join(self.waldiez.tags)}\n\n"
234
- content += f"Requirements: {', '.join(self.waldiez.requirements)}\n\n"
235
- content += '"""\n\n'
236
- content += "# cspell: disable\n"
237
- content += "# flake8: noqa\n\n"
238
- content += export_flow(
163
+ exporter = FlowExporter(
239
164
  waldiez=self.waldiez,
240
- agents=(self._agents, self._agent_names),
241
- chats=(self._chats, self._chat_names),
242
- models=(self._models, self._model_names),
243
- skills=(self._skills, self._skill_names),
244
165
  output_dir=path.parent,
245
- notebook=False,
166
+ for_notebook=False,
246
167
  )
247
- content += '\n\nif __name__ == "__main__":\n'
248
- content += " print(main())\n"
168
+ output = exporter.export()
169
+ content = output["content"]
170
+ if not content:
171
+ raise RuntimeError("Could not generate python script")
249
172
  with open(path, "w", encoding="utf-8", newline="\n") as file:
250
173
  file.write(content)
251
174
 
@@ -1,14 +1,13 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Tools for exporting agents, models, skills and chats to strings."""
2
4
 
3
- from .flow import export_flow
4
- from .models import export_models
5
- from .skills import export_skills
6
- from .utils import comment, get_valid_instance_name
5
+ from .flow import FlowExporter
6
+ from .models import ModelsExporter
7
+ from .skills import SkillsExporter
7
8
 
8
9
  __all__ = [
9
- "export_flow",
10
- "comment",
11
- "get_valid_instance_name",
12
- "export_models",
13
- "export_skills",
10
+ "FlowExporter",
11
+ "ModelsExporter",
12
+ "SkillsExporter",
14
13
  ]
@@ -0,0 +1,7 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Agents exporter."""
4
+
5
+ from .agent_exporter import AgentExporter
6
+
7
+ __all__ = ["AgentExporter"]
@@ -0,0 +1,279 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-many-return-statements,too-many-instance-attributes
4
+ """Export agents."""
5
+
6
+ from pathlib import Path
7
+ from typing import Callable, Dict, List, Optional, Tuple, Union
8
+
9
+ from waldiez.models import WaldiezAgent, WaldiezChat
10
+
11
+ from ..base import (
12
+ AgentPosition,
13
+ AgentPositions,
14
+ BaseExporter,
15
+ ExporterMixin,
16
+ ExporterReturnType,
17
+ ExportPosition,
18
+ ImportPosition,
19
+ )
20
+ from .utils import (
21
+ get_agent_class_name,
22
+ get_agent_code_execution_config,
23
+ get_agent_imports,
24
+ get_group_manager_extras,
25
+ get_is_termination_message,
26
+ get_rag_user_extras,
27
+ get_swarm_extras,
28
+ )
29
+
30
+
31
+ class AgentExporter(BaseExporter, ExporterMixin):
32
+ """Agents exporter."""
33
+
34
+ def __init__(
35
+ self,
36
+ agent: WaldiezAgent,
37
+ agent_names: Dict[str, str],
38
+ model_names: Dict[str, str],
39
+ skill_names: Dict[str, str],
40
+ chats: Tuple[List[WaldiezChat], Dict[str, str]],
41
+ is_async: bool,
42
+ group_chat_members: List[WaldiezAgent],
43
+ for_notebook: bool,
44
+ arguments_resolver: Callable[[WaldiezAgent], List[str]],
45
+ output_dir: Optional[Union[str, Path]] = None,
46
+ ) -> None:
47
+ """Initialize the agents exporter.
48
+
49
+ Parameters
50
+ ----------
51
+ agent : WaldiezAgent
52
+ The agent to export.
53
+ agent_names : Dict[str, str]
54
+ The agent ids to names mapping.
55
+ model_names : Dict[str, str]
56
+ The model ids to names mapping.
57
+ skill_names : Dict[str, str]
58
+ The skill ids to names mapping.
59
+ all_chats : List[WaldiezChat]
60
+ All the chats in the flow.
61
+ chat_names : Dict[str, str]
62
+ The chat ids to names mapping.
63
+ is_async : bool
64
+ Whether the whole flow is async.
65
+ for_notebook : bool
66
+ Whether the exporter is for a notebook.
67
+ output_dir : Optional[Union[str, Path]], optional
68
+ The output directory, by default None
69
+ """
70
+ self.for_notebook = for_notebook
71
+ self.agent = agent
72
+ self.agent_names = agent_names
73
+ if output_dir is not None and not isinstance(output_dir, Path):
74
+ output_dir = Path(output_dir)
75
+ self.output_dir = output_dir
76
+ self.model_names = model_names
77
+ self.skill_names = skill_names
78
+ self.arguments_resolver = arguments_resolver
79
+ self.group_chat_members = group_chat_members
80
+ self.chats = chats
81
+ self.is_async = is_async
82
+ self._agent_name = agent_names[agent.id]
83
+ self._agent_class = get_agent_class_name(self.agent)
84
+ # content, argument, import
85
+ self._code_execution = get_agent_code_execution_config(
86
+ agent=self.agent,
87
+ agent_name=self._agent_name,
88
+ skill_names=self.skill_names,
89
+ )
90
+ # before_rag, retrieve_arg, rag_imports
91
+ self._rag = get_rag_user_extras(
92
+ agent=self.agent,
93
+ agent_name=self._agent_name,
94
+ model_names=self.model_names,
95
+ path_resolver=self.path_resolver,
96
+ serializer=self.serializer,
97
+ )
98
+ # before_manager, group_chat_arg
99
+ self._group_chat = get_group_manager_extras(
100
+ agent=self.agent,
101
+ agent_names=self.agent_names,
102
+ group_chat_members=self.group_chat_members,
103
+ serializer=self.serializer,
104
+ )
105
+ # before_agent, extra args, handoff_registrations
106
+ self._swarm = get_swarm_extras(
107
+ agent=self.agent,
108
+ agent_names=self.agent_names,
109
+ skill_names=self.skill_names,
110
+ chats=self.chats,
111
+ is_async=self.is_async,
112
+ serializer=self.serializer,
113
+ string_escape=self.string_escape,
114
+ )
115
+ # before_agent, termination_arg
116
+ self._termination = get_is_termination_message(
117
+ agent=self.agent, agent_name=self._agent_name
118
+ )
119
+
120
+ def get_imports(self) -> Optional[List[Tuple[str, ImportPosition]]]:
121
+ """Get the imports.
122
+
123
+ Returns
124
+ -------
125
+ Optional[Tuple[str, ImportPosition]]
126
+ The imports.
127
+ """
128
+ position = ImportPosition.THIRD_PARTY
129
+ # default imports based on the agent class.
130
+ agent_imports = get_agent_imports(self._agent_class)
131
+ # if code execution is enabled, update the imports.
132
+ if self._code_execution[2]:
133
+ agent_imports.add(self._code_execution[2])
134
+ # if RAG is enabled, update the imports.
135
+ if self._rag[2]:
136
+ agent_imports.update(self._rag[2])
137
+ # if the agent has skills, add the register_function import.
138
+ if self.agent.data.skills:
139
+ agent_imports.add("from autogen import register_function")
140
+ return [(import_string, position) for import_string in agent_imports]
141
+
142
+ def get_system_message_arg(self) -> str:
143
+ """Get the system message argument.
144
+
145
+ Returns
146
+ -------
147
+ str
148
+ The system message argument.
149
+ """
150
+ if not self.agent.data.system_message:
151
+ return ""
152
+ system_message = self.string_escape(self.agent.data.system_message)
153
+ return ",\n system_message=" + f'"{system_message}"'
154
+
155
+ def get_before_export(
156
+ self,
157
+ ) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
158
+ """Generate the content before the main export.
159
+
160
+ Returns
161
+ -------
162
+ Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
163
+ The exported content before the main export and its position.
164
+ """
165
+ before_agent_string = ""
166
+ if self._code_execution[0] and self._code_execution[2]:
167
+ before_agent_string += self._code_execution[0]
168
+ if self._termination[1]:
169
+ before_agent_string += self._termination[1]
170
+ if self._group_chat[0]:
171
+ before_agent_string += self._group_chat[0]
172
+ if self._rag[0]:
173
+ before_agent_string += self._rag[0]
174
+ if self._swarm[0]:
175
+ before_agent_string += self._swarm[0]
176
+ if before_agent_string:
177
+ return [
178
+ (
179
+ before_agent_string,
180
+ AgentPosition(self.agent, AgentPositions.BEFORE),
181
+ )
182
+ ]
183
+ return None
184
+
185
+ def get_after_export(
186
+ self,
187
+ ) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
188
+ """Generate the content after the main export.
189
+
190
+ Returns
191
+ -------
192
+ Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
193
+ The exported content after the main export and its position.
194
+ """
195
+ after_agent_string = ""
196
+ if self._swarm[2]:
197
+ after_agent_string += self._swarm[2]
198
+ if after_agent_string:
199
+ return [
200
+ (
201
+ after_agent_string,
202
+ AgentPosition(self.agent, AgentPositions.AFTER_ALL),
203
+ )
204
+ ]
205
+ return None
206
+
207
+ def generate(self) -> Optional[str]:
208
+ """Generate the exported agent.
209
+
210
+ Returns
211
+ -------
212
+ Optional[str]
213
+ The exported agent.
214
+ """
215
+ agent = self.agent
216
+ agent_name = self._agent_name
217
+ agent_class = self._agent_class
218
+ retrieve_arg = self._rag[1]
219
+ group_chat_arg = self._group_chat[1]
220
+ is_termination = self._termination[0]
221
+ code_execution_arg = self._code_execution[1]
222
+ system_message_arg = self.get_system_message_arg()
223
+ default_auto_reply: str = "None"
224
+ if agent.data.agent_default_auto_reply:
225
+ default_auto_reply = (
226
+ f'"{self.string_escape(agent.data.agent_default_auto_reply)}"'
227
+ )
228
+ agent_str = f"""{agent_name} = {agent_class}(
229
+ name="{agent_name}",
230
+ description="{agent.description}"{system_message_arg},
231
+ human_input_mode="{agent.data.human_input_mode}",
232
+ max_consecutive_auto_reply={agent.data.max_consecutive_auto_reply},
233
+ default_auto_reply={default_auto_reply},
234
+ code_execution_config={code_execution_arg},
235
+ is_termination_msg={is_termination},{group_chat_arg}{retrieve_arg}
236
+ """
237
+ if self._swarm[1]:
238
+ agent_str += self._swarm[1]
239
+ # e.g. llm_config=...
240
+ other_args = self.arguments_resolver(agent)
241
+ if other_args:
242
+ agent_str += ",\n".join(other_args)
243
+ if not agent_str.endswith("\n"):
244
+ agent_str += "\n"
245
+ agent_str += ")"
246
+ return agent_str
247
+
248
+ def export(self) -> ExporterReturnType:
249
+ """Export the agent.
250
+
251
+ Returns
252
+ -------
253
+ ExporterReturnType
254
+ The exported agent.
255
+ """
256
+ agent_string = self.generate() or ""
257
+ is_group_manager = self.agent.agent_type == "group_manager"
258
+ after_export = self.get_after_export() or []
259
+ content: Optional[str] = agent_string
260
+ if is_group_manager and agent_string:
261
+ content = None
262
+ # make sure the group manager is defined
263
+ # after the rest of the agents.
264
+ # to avoid issues with (for example):
265
+ # 'group_manager_group_chat = GroupChat(
266
+ # # assistant and rag_user should be defined first
267
+ # ' agents=[assistant, rag_user],
268
+ # ' enable_clear_history=True,
269
+ # ...
270
+ after_export.append(
271
+ (agent_string, AgentPosition(None, AgentPositions.AFTER_ALL, 0))
272
+ )
273
+ return {
274
+ "content": content,
275
+ "imports": self.get_imports(),
276
+ "environment_variables": [],
277
+ "before_export": self.get_before_export(),
278
+ "after_export": after_export,
279
+ }
@@ -0,0 +1,23 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Utility functions for generating agent related strings."""
4
+
5
+ from .agent_class_name import get_agent_class_name
6
+ from .agent_imports import get_agent_imports
7
+ from .code_execution import get_agent_code_execution_config
8
+ from .group_manager import get_group_manager_extras
9
+ from .rag_user import get_rag_user_extras
10
+ from .swarm_agent import get_swarm_extras
11
+ from .teachability import get_agent_teachability_string
12
+ from .termination_message import get_is_termination_message
13
+
14
+ __all__ = [
15
+ "get_agent_class_name",
16
+ "get_agent_imports",
17
+ "get_agent_code_execution_config",
18
+ "get_agent_teachability_string",
19
+ "get_group_manager_extras",
20
+ "get_is_termination_message",
21
+ "get_rag_user_extras",
22
+ "get_swarm_extras",
23
+ ]
@@ -0,0 +1,34 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Get the agent class name."""
4
+
5
+ from waldiez.models import WaldiezAgent
6
+
7
+
8
+ # pylint: disable=too-many-return-statements
9
+ def get_agent_class_name(agent: WaldiezAgent) -> str:
10
+ """Get the agent class name.
11
+
12
+ Parameters
13
+ ----------
14
+ agent : WaldiezAgent
15
+ The agent.
16
+
17
+ Returns
18
+ -------
19
+ str
20
+ The agent class name.
21
+ """
22
+ if agent.data.is_multimodal:
23
+ return "MultimodalConversableAgent"
24
+ if agent.agent_type == "assistant":
25
+ return "AssistantAgent"
26
+ if agent.agent_type == "user":
27
+ return "UserProxyAgent"
28
+ if agent.agent_type == "manager":
29
+ return "GroupChatManager"
30
+ if agent.agent_type == "rag_user":
31
+ return "RetrieveUserProxyAgent"
32
+ if agent.agent_type == "swarm":
33
+ return "SwarmAgent"
34
+ return "ConversableAgent" # pragma: no cover