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,128 @@
1
+ """Skills/tools related string generation functions.
2
+
3
+ Functions
4
+ ---------
5
+ get_agent_skill_registration
6
+ Get an agent's skill registration string.
7
+ export_skills
8
+ Get the skills content and secrets.
9
+ """
10
+
11
+ from pathlib import Path
12
+ from typing import Dict, List, Optional, Set, Tuple, Union
13
+
14
+ from waldiez.models import WaldiezSkill
15
+
16
+ from ..utils import get_escaped_string
17
+
18
+
19
+ def get_agent_skill_registration(
20
+ caller_name: str,
21
+ executor_name: str,
22
+ skill_name: str,
23
+ skill_description: str,
24
+ ) -> str:
25
+ """Get the agent skill string and secrets.
26
+
27
+ Parameters
28
+ ----------
29
+ caller_name : str
30
+ The name of the caller (agent).
31
+ executor_name : str
32
+ The name of the executor (agent).
33
+ skill_name : str
34
+ The name of the skill.
35
+ skill_description : str
36
+ The skill description.
37
+
38
+ Returns
39
+ -------
40
+ str
41
+ The agent skill string.
42
+
43
+ Example
44
+ -------
45
+ ```python
46
+ >>> get_agent_skill_registration(
47
+ ... caller_name="agent1",
48
+ ... executor_name="agent2",
49
+ ... skill_name="skill1",
50
+ ... skill_description="A skill that does something.",
51
+ ... )
52
+ register_function(
53
+ skill1,
54
+ caller=agent1,
55
+ executor=agent2,
56
+ name="skill1",
57
+ description="A skill that does something.",
58
+ )
59
+ ```
60
+ """
61
+ skill_description = get_escaped_string(skill_description)
62
+ content = f"""register_function(
63
+ {skill_name},
64
+ caller={caller_name},
65
+ executor={executor_name},
66
+ name="{skill_name}",
67
+ description="{skill_description}",
68
+ )"""
69
+ return content
70
+
71
+
72
+ def export_skills(
73
+ skills: List[WaldiezSkill],
74
+ skill_names: Dict[str, str],
75
+ output_dir: Optional[Union[str, Path]] = None,
76
+ ) -> Tuple[Set[str], Set[Tuple[str, str]]]:
77
+ """Get the skills' contents and secrets.
78
+
79
+ If `output_dir` is provided, the contents are saved to that directory.
80
+
81
+ Parameters
82
+ ----------
83
+ skills : List[WaldiezSkill]
84
+ The skills.
85
+ skill_names : Dict[str, str]
86
+ The skill names.
87
+ output_dir : Optional[Union[str, Path]]
88
+ The output directory to save the skills to.
89
+
90
+ Returns
91
+ -------
92
+ Tuple[Set[str], Set[Tuple[str, str]]]
93
+ - The skill imports to use in the main file.
94
+ - The skill secrets to set as environment variables.
95
+
96
+ Example
97
+ -------
98
+ ```python
99
+ >>> from waldiez.models import WaldiezSkill, WaldiezSkillData
100
+ >>> skill1 = WaldiezSkill(
101
+ ... id="ws-1",
102
+ ... name="skill1",
103
+ ... description="A skill that does something.",
104
+ ... tags=["skill", "skill1"],
105
+ ... requirements=[],
106
+ ... data=WaldiezSkillData(
107
+ ... content="def skill1():\\n pass",
108
+ ... secrets={"API_KEY": "1234567890"},
109
+ ... )
110
+ >>> skill_names = {"ws-1": "skill1"}
111
+ >>> export_skills([skill1], skill_names, None)
112
+ ({'from skill1 import skill1'}, {('API_KEY', '1234567890')})
113
+ ```
114
+ """
115
+ skill_imports: Set[str] = set()
116
+ skill_secrets: Set[Tuple[str, str]] = set()
117
+ for skill in skills:
118
+ skill_name = skill_names[skill.id]
119
+ skill_imports.add(f"from {skill_name} import {skill_name}")
120
+ skill_secrets.update(skill.secrets.items())
121
+ if not output_dir:
122
+ continue
123
+ if not isinstance(output_dir, Path):
124
+ output_dir = Path(output_dir)
125
+ skill_file = output_dir / f"{skill_name}.py"
126
+ with skill_file.open("w", encoding="utf-8") as f:
127
+ f.write(skill.content)
128
+ return skill_imports, skill_secrets
@@ -0,0 +1,34 @@
1
+ """Generic utils to be used for exporting."""
2
+
3
+ from .comments import comment, get_comment, get_pylint_ignore_comment
4
+ from .importing import add_autogen_dot_import, get_imports_string
5
+ from .logging_utils import (
6
+ get_logging_start_string,
7
+ get_logging_stop_string,
8
+ get_sqlite_to_csv_call_string,
9
+ get_sqlite_to_csv_string,
10
+ )
11
+ from .method_utils import get_method_string
12
+ from .naming import (
13
+ get_escaped_string,
14
+ get_valid_instance_name,
15
+ get_valid_python_variable_name,
16
+ )
17
+ from .object_string import get_object_string
18
+
19
+ __all__ = [
20
+ "add_autogen_dot_import",
21
+ "comment",
22
+ "get_logging_start_string",
23
+ "get_logging_stop_string",
24
+ "get_pylint_ignore_comment",
25
+ "get_sqlite_to_csv_string",
26
+ "get_sqlite_to_csv_call_string",
27
+ "get_imports_string",
28
+ "get_comment",
29
+ "get_escaped_string",
30
+ "get_method_string",
31
+ "get_object_string",
32
+ "get_valid_instance_name",
33
+ "get_valid_python_variable_name",
34
+ ]
@@ -0,0 +1,136 @@
1
+ """Comment related string generation functions.
2
+ Functions
3
+ ---------
4
+ comment
5
+ Get a comment string.
6
+ get_comment
7
+ Get a comment string for some common keys (notebook headings).
8
+ get_pylint_ignore_comment
9
+ Get the pylint ignore comment string.
10
+ """
11
+
12
+ from typing import List, Optional
13
+
14
+ from typing_extensions import Literal
15
+
16
+ PYLINT_RULES = [
17
+ "line-too-long",
18
+ "unknown-option-value",
19
+ "unused-argument",
20
+ "unused-import",
21
+ "invalid-name",
22
+ "import-error",
23
+ "inconsistent-quotes",
24
+ "missing-function-docstring",
25
+ "missing-param-doc",
26
+ "missing-return-doc",
27
+ ]
28
+
29
+
30
+ def comment(notebook: bool, hashtags: int = 1) -> str:
31
+ """Get the comment string.
32
+
33
+ Parameters
34
+ ----------
35
+ notebook : bool
36
+ Whether the comment is for a notebook or not.
37
+ hashtags : int, optional
38
+ The number of hashtags (for notebooks), by default 1.
39
+
40
+ Returns
41
+ -------
42
+ str
43
+ The comment string.
44
+ Example
45
+ -------
46
+ ```python
47
+ >>> comment(True, 2)
48
+ '## '
49
+ >>> comment(False)
50
+ '# '
51
+ ```
52
+ """
53
+ content = "# "
54
+ if notebook:
55
+ content += "#" * hashtags + " "
56
+ return content
57
+
58
+
59
+ def get_comment(
60
+ key: Literal["agents", "skills", "models", "nested", "run", "logging"],
61
+ for_notebook: bool,
62
+ ) -> str:
63
+ """Get a comment string for some common keys.
64
+
65
+ The key is a heading (in a notebook) or just a comment (in a script).
66
+
67
+ Parameters
68
+ ----------
69
+ key : Literal["agents", "skills", "models", "nested", "run", "logging"]
70
+ The key.
71
+ for_notebook : bool
72
+ Whether the comment is for a notebook.
73
+
74
+ Returns
75
+ -------
76
+ str
77
+ The comment string.
78
+
79
+ Example
80
+ -------
81
+ ```python
82
+ >>> get_comment("agents", True)
83
+
84
+ '## Agents'
85
+ >>> get_comment("skills", False)
86
+
87
+ '# Skills'
88
+ ```
89
+ """
90
+ # pylint: disable=too-many-return-statements
91
+ if key == "agents":
92
+ return "\n" + comment(for_notebook, 2) + "Agents\n"
93
+ if key == "skills":
94
+ return "\n" + comment(for_notebook, 2) + "Skills\n"
95
+ if key == "models":
96
+ return "\n" + comment(for_notebook, 2) + "Models\n"
97
+ if key == "nested":
98
+ return "\n" + comment(for_notebook, 2) + "Nested Chats\n"
99
+ if key == "run":
100
+ return "\n" + comment(for_notebook, 2) + "Run the flow\n"
101
+ if key == "logging":
102
+ return "\n" + comment(for_notebook, 2) + "Start Logging\n"
103
+ return comment(for_notebook)
104
+
105
+
106
+ def get_pylint_ignore_comment(
107
+ notebook: bool, rules: Optional[List[str]] = None
108
+ ) -> str:
109
+ """Get the pylint ignore comment string.
110
+
111
+ Parameters
112
+ ----------
113
+ notebook : bool
114
+ Whether the comment is for a notebook.
115
+ rules : Optional[List[str]], optional
116
+ The pylint rules to ignore, by default None.
117
+
118
+ Returns
119
+ -------
120
+ str
121
+ The pylint ignore comment string.
122
+
123
+ Example
124
+ -------
125
+ ```python
126
+ >>> get_pylint_ignore_comment(True, ["invalid-name", "line-too-long"])
127
+
128
+ # pylint: disable=invalid-name, line-too-long
129
+ ```
130
+ """
131
+ if not rules:
132
+ rules = PYLINT_RULES
133
+ line = "# pylint: disable=" + ",".join(rules)
134
+ if notebook is True:
135
+ line = "\n" + line
136
+ return line + "\n"
@@ -0,0 +1,267 @@
1
+ """Importing related string generation functions.
2
+
3
+ Functions
4
+ ---------
5
+ add_autogen_dot_import
6
+ Add an autogen dot import (from autogen.{x.y} import {z}).
7
+ get_imports_string
8
+ Get the imports for the whole file/flow.
9
+ """
10
+
11
+ from typing import Dict, List, Optional, Set, Tuple
12
+
13
+ DEFAULT_TYPING_IMPORTS = {
14
+ "Any",
15
+ "Callable",
16
+ "Dict",
17
+ "List",
18
+ "Optional",
19
+ "Tuple",
20
+ "Union",
21
+ }
22
+
23
+
24
+ def add_autogen_dot_import(
25
+ current_imports: Dict[str, List[str]], new_import: Tuple[str, str]
26
+ ) -> Dict[str, List[str]]:
27
+ """Add an autogen dot import (from autogen.{x} import {y}).
28
+
29
+ Parameters
30
+ ----------
31
+ current_imports : Dict[str, List[str]]
32
+ The current autogen dot imports.
33
+ new_import : Tuple[str, str]
34
+ The new import.
35
+
36
+ Returns
37
+ -------
38
+ Dict[str, List[str]]
39
+ The updated imports.
40
+
41
+ Example
42
+ -------
43
+ ```python
44
+ >>> current_imports = {"a": ["b", "c"], "d": ["e"]}
45
+ >>> new_import = ("a", "f")
46
+ >>> add_autogen_dot_import(current_imports, new_import)
47
+ {'a': ['b', 'c', 'f'], 'd': ['e']}
48
+ # and the final string would be:
49
+ from autogen.a import b, c, f
50
+ from autogen.d import e
51
+ ```
52
+ """
53
+ dot_part, module_part = new_import
54
+ if not module_part:
55
+ return current_imports
56
+ imports_copy = current_imports.copy()
57
+ if dot_part not in current_imports:
58
+ imports_copy[dot_part] = []
59
+ imports_copy[dot_part].append(module_part)
60
+ return imports_copy
61
+
62
+
63
+ def get_imports_string(
64
+ imports: Set[str],
65
+ skill_imports: Set[str],
66
+ typing_imports: Optional[Set[str]] = None,
67
+ builtin_imports: Optional[Set[str]] = None,
68
+ other_imports: Optional[Set[str]] = None,
69
+ ) -> str:
70
+ """Get the imports.
71
+
72
+ Parameters
73
+ ----------
74
+ imports : Set[str]
75
+ The flow imports (e.g. from autogen.{x[y.z]} import {w}).
76
+ skill_imports : Set[str]
77
+ The skill imports.
78
+ typing_imports : Set[str], optional
79
+ The typing imports, by default None.
80
+ builtin_imports : Set[str], optional
81
+ The builtin imports, by default None.
82
+ other_imports : Set[str], optional
83
+ Other third party imports, by default None.
84
+
85
+ Returns
86
+ -------
87
+ str
88
+ The imports string.
89
+
90
+ Example
91
+ -------
92
+ ```python
93
+ >>> autogen_imports = {"from autogen import a", "from autogen.b import c"}
94
+ >>> skill_imports = {"from skill_name import skill_name"}
95
+ >>> get_imports_string(autogen_imports, skill_imports)
96
+
97
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
98
+ from typing_extensions import Annotated
99
+
100
+ from autogen import a
101
+ from autogen.b import c
102
+
103
+ from skill_name import skill_name'
104
+ ```
105
+ """
106
+ if not typing_imports:
107
+ typing_imports = DEFAULT_TYPING_IMPORTS
108
+ if not builtin_imports:
109
+ builtin_imports = set()
110
+ if not other_imports:
111
+ other_imports = set()
112
+ string = _get_builtin_imports_string(builtin_imports, typing_imports)
113
+ string += _get_third_party_imports_string(imports, other_imports)
114
+ string += _get_skill_imports_string(skill_imports)
115
+ string = "\n\n".join([line for line in string.split("\n\n") if line])
116
+ while not string.endswith("\n\n"):
117
+ string += "\n"
118
+ return string
119
+
120
+
121
+ # pylint: disable=line-too-long
122
+ def _get_builtin_imports_string(
123
+ builtin_imports: Set[str],
124
+ typing_imports: Set[str],
125
+ include_annotations: bool = True,
126
+ ) -> str:
127
+ """Get the builtin imports."""
128
+ imports = []
129
+ from_imports = []
130
+ for imp in sorted(builtin_imports):
131
+ if imp.startswith("from "):
132
+ from_imports.append(imp)
133
+ elif imp.startswith("import "):
134
+ imports.append(imp)
135
+ else:
136
+ imports.append(f"import {imp}")
137
+ if typing_imports:
138
+ without_from_typing = []
139
+ for typing_import in typing_imports:
140
+ if typing_import.startswith("from typing import "):
141
+ without_from_typing.extend(
142
+ typing_import.split("from typing import ")[1].split(", ")
143
+ )
144
+ else:
145
+ without_from_typing.append(typing_import)
146
+ from_imports.append(
147
+ "from typing import "
148
+ + ", ".join(sorted(without_from_typing))
149
+ + " # noqa"
150
+ )
151
+ if include_annotations:
152
+ from_imports.append("from typing_extensions import Annotated")
153
+ string = (
154
+ "\n".join(sorted(imports)) + "\n\n" + "\n".join(sorted(from_imports))
155
+ )
156
+ return string
157
+
158
+
159
+ def _get_autogen_import(import_string: str) -> List[str]:
160
+ """Get the autogen import.
161
+
162
+ In case the import is a "full" import statement,
163
+ we keep only the module to import.
164
+ """
165
+ things = []
166
+ if import_string.startswith("from autogen import "):
167
+ import_part = import_string.split("from autogen import ")[1]
168
+ things = import_part.split(", ")
169
+ return things
170
+
171
+
172
+ def _prepare_imports(
173
+ autogen_imports: Set[str],
174
+ autogen_dot_imports: Dict[str, List[str]],
175
+ other_imports: Set[str],
176
+ ) -> Tuple[List[str], Dict[str, List[str]]]:
177
+ plain_imports = [] # plain `import {x}`
178
+ autogen_imports_list = [] # from autogen import {y}
179
+ for autogen_import in autogen_imports:
180
+ autogen_imports_list.extend(_get_autogen_import(autogen_import))
181
+ from_imports_dict: Dict[str, List[str]] = {
182
+ "autogen": autogen_imports_list,
183
+ }
184
+ # from autogen.{z} import {w} # z could be "a.b.c.."
185
+ for autogen_dot_package, autogen_dot_modules in autogen_dot_imports.items():
186
+ sub_package = f"autogen.{autogen_dot_package}"
187
+ if sub_package not in from_imports_dict:
188
+ from_imports_dict[sub_package] = []
189
+ from_imports_dict[sub_package].extend(autogen_dot_modules)
190
+ for imp in other_imports:
191
+ if imp.startswith("from "):
192
+ line_parts = imp.split("from ")
193
+ package = line_parts[1].split(" import ")[0]
194
+ if package not in from_imports_dict:
195
+ from_imports_dict[package] = []
196
+ import_part = line_parts[1].split(" import ")[1]
197
+ things = import_part.split(", ")
198
+ from_imports_dict[package].extend(things)
199
+ elif imp.startswith("import "):
200
+ plain_imports.append(imp)
201
+ else:
202
+ plain_imports.append(f"import {imp}")
203
+ plain_imports.sort()
204
+ return plain_imports, from_imports_dict
205
+
206
+
207
+ def _get_autogen_imports(
208
+ imports: Set[str],
209
+ ) -> Tuple[Set[str], Dict[str, List[str]], Set[str]]:
210
+ """Get the autogen imports."""
211
+ autogen_imports = set()
212
+ _autogen_dot_imports: Dict[str, List[str]] = {}
213
+ remaining_imports: Set[str] = set()
214
+ for imp in imports:
215
+ if imp.startswith("from autogen import "):
216
+ autogen_imports.add(imp)
217
+ elif imp.startswith("from autogen."):
218
+ parts = imp.split("from autogen.")[1].split(" import ")
219
+ if len(parts) == 2:
220
+ package = parts[0]
221
+ module = parts[1]
222
+ if package not in _autogen_dot_imports:
223
+ _autogen_dot_imports[package] = []
224
+ _autogen_dot_imports[package].append(module)
225
+ else:
226
+ remaining_imports.add(imp)
227
+ # sort the autogen imports
228
+ autogen_imports = set(sorted(list(autogen_imports)))
229
+ autogen_dot_imports = {}
230
+ # sort the autogen dot imports (both keys and values)
231
+ sorted_keys = sorted(_autogen_dot_imports.keys())
232
+ for key in sorted_keys:
233
+ autogen_dot_imports[key] = sorted(_autogen_dot_imports[key])
234
+ return autogen_imports, autogen_dot_imports, remaining_imports
235
+
236
+
237
+ def _get_third_party_imports_string(
238
+ imports: Set[str],
239
+ other_imports: Set[str],
240
+ ) -> str:
241
+ """Get the third party imports."""
242
+ autogen_imports, autogen_dot_imports, rest = _get_autogen_imports(imports)
243
+ rest.update(other_imports)
244
+ plain_imports, from_imports_dict = _prepare_imports(
245
+ autogen_imports=autogen_imports,
246
+ autogen_dot_imports=autogen_dot_imports,
247
+ other_imports=rest,
248
+ )
249
+ from_imports = []
250
+ # pylint: disable=inconsistent-quotes
251
+ for package, modules in from_imports_dict.items():
252
+ # remove duplicates
253
+ modules = sorted(set(modules))
254
+ if modules:
255
+ from_imports.append(f"from {package} import {', '.join(modules)}")
256
+ string = (
257
+ "\n\n" + "\n".join(plain_imports) + "\n\n" + "\n".join(from_imports)
258
+ )
259
+ return string
260
+
261
+
262
+ def _get_skill_imports_string(skill_imports: Set[str]) -> str:
263
+ """Get the skill imports."""
264
+ if not skill_imports:
265
+ return ""
266
+ string = "\n\n" + "\n".join(sorted(skill_imports)) + "\n"
267
+ return string