waldiez 0.2.2__py3-none-any.whl → 0.3.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 +2 -0
- waldiez/__main__.py +2 -0
- waldiez/_version.py +3 -1
- waldiez/cli.py +13 -3
- waldiez/cli_extras.py +4 -3
- waldiez/conflict_checker.py +4 -3
- waldiez/exporter.py +28 -105
- waldiez/exporting/__init__.py +8 -9
- waldiez/exporting/agent/__init__.py +7 -0
- waldiez/exporting/agent/agent_exporter.py +279 -0
- waldiez/exporting/agent/utils/__init__.py +23 -0
- waldiez/exporting/agent/utils/agent_class_name.py +34 -0
- waldiez/exporting/agent/utils/agent_imports.py +50 -0
- waldiez/exporting/{agents → agent/utils}/code_execution.py +9 -11
- waldiez/exporting/{agents → agent/utils}/group_manager.py +47 -35
- waldiez/exporting/{agents → agent/utils}/rag_user/__init__.py +2 -0
- waldiez/exporting/{agents → agent/utils}/rag_user/chroma_utils.py +22 -17
- waldiez/exporting/{agents → agent/utils}/rag_user/mongo_utils.py +14 -10
- waldiez/exporting/{agents → agent/utils}/rag_user/pgvector_utils.py +12 -8
- waldiez/exporting/{agents → agent/utils}/rag_user/qdrant_utils.py +11 -8
- waldiez/exporting/{agents → agent/utils}/rag_user/rag_user.py +78 -55
- waldiez/exporting/{agents → agent/utils}/rag_user/vector_db.py +10 -8
- waldiez/exporting/agent/utils/swarm_agent.py +463 -0
- waldiez/exporting/{agents → agent/utils}/teachability.py +10 -6
- waldiez/exporting/{agents → agent/utils}/termination_message.py +7 -8
- waldiez/exporting/base/__init__.py +25 -0
- waldiez/exporting/base/agent_position.py +75 -0
- waldiez/exporting/base/base_exporter.py +118 -0
- waldiez/exporting/base/export_position.py +48 -0
- waldiez/exporting/base/import_position.py +23 -0
- waldiez/exporting/base/mixin.py +134 -0
- waldiez/exporting/base/utils/__init__.py +18 -0
- waldiez/exporting/{utils → base/utils}/comments.py +12 -55
- waldiez/exporting/{utils → base/utils}/naming.py +14 -4
- waldiez/exporting/base/utils/path_check.py +68 -0
- waldiez/exporting/{utils/object_string.py → base/utils/to_string.py} +21 -20
- waldiez/exporting/chats/__init__.py +5 -12
- waldiez/exporting/chats/chats_exporter.py +240 -0
- waldiez/exporting/chats/utils/__init__.py +15 -0
- waldiez/exporting/chats/utils/common.py +81 -0
- waldiez/exporting/chats/{nested.py → utils/nested.py} +125 -86
- waldiez/exporting/chats/utils/sequential.py +244 -0
- waldiez/exporting/chats/utils/single_chat.py +313 -0
- waldiez/exporting/chats/utils/swarm.py +207 -0
- waldiez/exporting/flow/__init__.py +5 -3
- waldiez/exporting/flow/flow_exporter.py +503 -0
- waldiez/exporting/flow/utils/__init__.py +47 -0
- waldiez/exporting/flow/utils/agent_utils.py +204 -0
- waldiez/exporting/flow/utils/chat_utils.py +71 -0
- waldiez/exporting/flow/utils/def_main.py +62 -0
- waldiez/exporting/flow/utils/flow_content.py +112 -0
- waldiez/exporting/flow/utils/flow_names.py +115 -0
- waldiez/exporting/flow/utils/importing_utils.py +179 -0
- waldiez/exporting/{utils → flow/utils}/logging_utils.py +34 -31
- waldiez/exporting/models/__init__.py +7 -242
- waldiez/exporting/models/models_exporter.py +192 -0
- waldiez/exporting/models/utils.py +166 -0
- waldiez/exporting/skills/__init__.py +7 -161
- waldiez/exporting/skills/skills_exporter.py +169 -0
- waldiez/exporting/skills/utils.py +281 -0
- waldiez/models/__init__.py +25 -7
- waldiez/models/agents/__init__.py +70 -0
- waldiez/models/agents/agent/__init__.py +11 -1
- waldiez/models/agents/agent/agent.py +9 -4
- waldiez/models/agents/agent/agent_data.py +3 -1
- waldiez/models/agents/agent/code_execution.py +2 -0
- waldiez/models/agents/agent/linked_skill.py +2 -0
- waldiez/models/agents/agent/nested_chat.py +2 -0
- waldiez/models/agents/agent/teachability.py +2 -0
- waldiez/models/agents/agent/termination_message.py +49 -13
- waldiez/models/agents/agents.py +15 -3
- waldiez/models/agents/assistant/__init__.py +2 -0
- waldiez/models/agents/assistant/assistant.py +2 -0
- waldiez/models/agents/assistant/assistant_data.py +2 -0
- waldiez/models/agents/group_manager/__init__.py +9 -1
- waldiez/models/agents/group_manager/group_manager.py +2 -0
- waldiez/models/agents/group_manager/group_manager_data.py +2 -0
- waldiez/models/agents/group_manager/speakers.py +49 -13
- waldiez/models/agents/rag_user/__init__.py +21 -4
- waldiez/models/agents/rag_user/rag_user.py +3 -1
- waldiez/models/agents/rag_user/rag_user_data.py +2 -0
- waldiez/models/agents/rag_user/retrieve_config.py +268 -17
- waldiez/models/agents/rag_user/vector_db_config.py +5 -3
- waldiez/models/agents/swarm_agent/__init__.py +49 -0
- waldiez/models/agents/swarm_agent/after_work.py +178 -0
- waldiez/models/agents/swarm_agent/on_condition.py +103 -0
- waldiez/models/agents/swarm_agent/on_condition_available.py +140 -0
- waldiez/models/agents/swarm_agent/on_condition_target.py +40 -0
- waldiez/models/agents/swarm_agent/swarm_agent.py +107 -0
- waldiez/models/agents/swarm_agent/swarm_agent_data.py +125 -0
- waldiez/models/agents/swarm_agent/update_system_message.py +144 -0
- waldiez/models/agents/user_proxy/__init__.py +2 -0
- waldiez/models/agents/user_proxy/user_proxy.py +2 -0
- waldiez/models/agents/user_proxy/user_proxy_data.py +2 -0
- waldiez/models/chat/__init__.py +21 -3
- waldiez/models/chat/chat.py +241 -7
- waldiez/models/chat/chat_data.py +192 -48
- waldiez/models/chat/chat_message.py +153 -144
- waldiez/models/chat/chat_nested.py +33 -53
- waldiez/models/chat/chat_summary.py +2 -0
- waldiez/models/common/__init__.py +6 -6
- waldiez/models/common/base.py +4 -1
- waldiez/models/common/method_utils.py +163 -83
- waldiez/models/flow/__init__.py +2 -0
- waldiez/models/flow/flow.py +176 -40
- waldiez/models/flow/flow_data.py +63 -2
- waldiez/models/flow/utils.py +172 -0
- waldiez/models/model/__init__.py +2 -0
- waldiez/models/model/model.py +25 -6
- waldiez/models/model/model_data.py +3 -1
- waldiez/models/skill/__init__.py +4 -1
- waldiez/models/skill/skill.py +30 -2
- waldiez/models/skill/skill_data.py +2 -0
- waldiez/models/waldiez.py +28 -4
- waldiez/runner.py +142 -228
- waldiez/running/__init__.py +33 -0
- waldiez/running/environment.py +83 -0
- waldiez/running/gen_seq_diagram.py +185 -0
- waldiez/running/running.py +300 -0
- {waldiez-0.2.2.dist-info → waldiez-0.3.0.dist-info}/METADATA +32 -26
- waldiez-0.3.0.dist-info/RECORD +125 -0
- waldiez-0.3.0.dist-info/licenses/LICENSE +201 -0
- waldiez/exporting/agents/__init__.py +0 -5
- waldiez/exporting/agents/agent.py +0 -236
- waldiez/exporting/agents/agent_skills.py +0 -67
- waldiez/exporting/agents/llm_config.py +0 -53
- waldiez/exporting/chats/chats.py +0 -46
- waldiez/exporting/chats/helpers.py +0 -420
- waldiez/exporting/flow/def_main.py +0 -32
- waldiez/exporting/flow/flow.py +0 -189
- waldiez/exporting/utils/__init__.py +0 -36
- waldiez/exporting/utils/importing.py +0 -265
- waldiez/exporting/utils/method_utils.py +0 -35
- waldiez/exporting/utils/path_check.py +0 -51
- waldiez-0.2.2.dist-info/RECORD +0 -92
- waldiez-0.2.2.dist-info/licenses/LICENSE +0 -21
- {waldiez-0.2.2.dist-info → waldiez-0.3.0.dist-info}/WHEEL +0 -0
- {waldiez-0.2.2.dist-info → waldiez-0.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Export models (llm_configs)."""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
7
|
+
|
|
8
|
+
from waldiez.models import WaldiezAgent, WaldiezModel
|
|
9
|
+
|
|
10
|
+
from ..base import (
|
|
11
|
+
AgentPosition,
|
|
12
|
+
AgentPositions,
|
|
13
|
+
BaseExporter,
|
|
14
|
+
ExporterMixin,
|
|
15
|
+
ExporterReturnType,
|
|
16
|
+
ExportPosition,
|
|
17
|
+
ImportPosition,
|
|
18
|
+
)
|
|
19
|
+
from .utils import export_models, get_agent_llm_config_arg
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ModelsExporter(BaseExporter, ExporterMixin):
|
|
23
|
+
"""Models exporter."""
|
|
24
|
+
|
|
25
|
+
_exported_string: Optional[str]
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
flow_name: str,
|
|
30
|
+
agents: List[WaldiezAgent],
|
|
31
|
+
agent_names: Dict[str, str],
|
|
32
|
+
models: List[WaldiezModel],
|
|
33
|
+
model_names: Dict[str, str],
|
|
34
|
+
for_notebook: bool,
|
|
35
|
+
output_dir: Optional[Union[str, Path]] = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Initialize the models exporter.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
agents : List[WaldiezAgent]
|
|
42
|
+
The agents.
|
|
43
|
+
agent_names : Dict[str, str]
|
|
44
|
+
The agent names.
|
|
45
|
+
models : List[WaldiezModel]
|
|
46
|
+
The models.
|
|
47
|
+
model_names : Dict[str, str]
|
|
48
|
+
The model names.
|
|
49
|
+
output_dir : Optional[Union[str, Path]], optional
|
|
50
|
+
The output directory if any, by default None
|
|
51
|
+
"""
|
|
52
|
+
self.for_notebook = for_notebook
|
|
53
|
+
self.flow_name = flow_name
|
|
54
|
+
self.agents = agents
|
|
55
|
+
self.agent_names = agent_names
|
|
56
|
+
self.models = models
|
|
57
|
+
self.model_names = model_names
|
|
58
|
+
if output_dir is not None and not isinstance(output_dir, Path):
|
|
59
|
+
output_dir = Path(output_dir)
|
|
60
|
+
self.output_dir = output_dir
|
|
61
|
+
self._exported_string = None
|
|
62
|
+
|
|
63
|
+
def get_imports(self) -> Optional[List[Tuple[str, ImportPosition]]]:
|
|
64
|
+
"""Generate the imports string.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
Optional[Tuple[str, ImportPosition]]
|
|
69
|
+
The exported imports and the position of the imports.
|
|
70
|
+
"""
|
|
71
|
+
if not self.output_dir:
|
|
72
|
+
return None
|
|
73
|
+
file_path = self.output_dir / f"{self.flow_name}_api_keys.py"
|
|
74
|
+
if not file_path.exists():
|
|
75
|
+
# might be because the models are not exported yet
|
|
76
|
+
if not self._exported_string:
|
|
77
|
+
self.generate()
|
|
78
|
+
# if still not exported, return None
|
|
79
|
+
if not file_path.exists(): # pragma: no cover
|
|
80
|
+
return None
|
|
81
|
+
import_string = f"from {self.flow_name}_api_keys import (" + "\n"
|
|
82
|
+
import_string += f" get_{self.flow_name}_model_api_key," + "\n"
|
|
83
|
+
import_string += ")\n"
|
|
84
|
+
return [(import_string, ImportPosition.LOCAL)]
|
|
85
|
+
|
|
86
|
+
def get_after_export(
|
|
87
|
+
self,
|
|
88
|
+
) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
|
|
89
|
+
# fmt: off
|
|
90
|
+
"""Generate the after export strings.
|
|
91
|
+
|
|
92
|
+
The arguments for the agent's initialization.
|
|
93
|
+
example generated args:
|
|
94
|
+
>>> agent1 = ConversableAgent(
|
|
95
|
+
>>> ...
|
|
96
|
+
>>> llm_config=False,
|
|
97
|
+
>>> ...
|
|
98
|
+
>>> )
|
|
99
|
+
|
|
100
|
+
>>> agent2 = ConversableAgent(
|
|
101
|
+
>>> ...
|
|
102
|
+
>>> llm_config={
|
|
103
|
+
>>> "config_list": [
|
|
104
|
+
>>> model1_llm_config,
|
|
105
|
+
>>> model2_llm_config,
|
|
106
|
+
>>> ],
|
|
107
|
+
>>> },
|
|
108
|
+
>>> ...
|
|
109
|
+
>>> )
|
|
110
|
+
|
|
111
|
+
where `model1_llm_config` and `model2_llm_config`
|
|
112
|
+
are the exported models using `self.generate()`
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
|
|
117
|
+
The exported after export strings and their positions.
|
|
118
|
+
"""
|
|
119
|
+
# fmt: on
|
|
120
|
+
agent_llm_config_args: List[
|
|
121
|
+
Tuple[str, Union[ExportPosition, AgentPosition]]
|
|
122
|
+
] = []
|
|
123
|
+
for agent in self.agents:
|
|
124
|
+
agent_llm_config_args.append(
|
|
125
|
+
(
|
|
126
|
+
get_agent_llm_config_arg(
|
|
127
|
+
agent,
|
|
128
|
+
all_models=self.models,
|
|
129
|
+
model_names=self.model_names,
|
|
130
|
+
),
|
|
131
|
+
AgentPosition(
|
|
132
|
+
agent=agent, position=AgentPositions.AS_ARGUMENT
|
|
133
|
+
),
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
return agent_llm_config_args
|
|
137
|
+
|
|
138
|
+
def generate(self) -> str:
|
|
139
|
+
"""Export the models.
|
|
140
|
+
|
|
141
|
+
Returns
|
|
142
|
+
-------
|
|
143
|
+
str
|
|
144
|
+
The exported models.
|
|
145
|
+
"""
|
|
146
|
+
if not self._exported_string: # pragma: no cover
|
|
147
|
+
self._exported_string = export_models(
|
|
148
|
+
flow_name=self.flow_name,
|
|
149
|
+
all_models=self.models,
|
|
150
|
+
model_names=self.model_names,
|
|
151
|
+
output_dir=self.output_dir,
|
|
152
|
+
serializer=self.serializer,
|
|
153
|
+
)
|
|
154
|
+
return self._exported_string
|
|
155
|
+
|
|
156
|
+
def get_environment_variables(self) -> Optional[List[Tuple[str, str]]]:
|
|
157
|
+
"""Get the environment variables to set.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
-------
|
|
161
|
+
Optional[List[Tuple[str, str]]
|
|
162
|
+
The environment variables to set.
|
|
163
|
+
"""
|
|
164
|
+
env_vars = []
|
|
165
|
+
for model in self.models:
|
|
166
|
+
if model.api_key:
|
|
167
|
+
env_vars.append((model.api_key_env_key, model.api_key))
|
|
168
|
+
return env_vars
|
|
169
|
+
|
|
170
|
+
def export(self) -> ExporterReturnType:
|
|
171
|
+
"""Export the models.
|
|
172
|
+
|
|
173
|
+
Returns
|
|
174
|
+
-------
|
|
175
|
+
ExporterReturnType
|
|
176
|
+
The exported models,
|
|
177
|
+
the imports,
|
|
178
|
+
the before export strings,
|
|
179
|
+
the after export strings,
|
|
180
|
+
and the environment variables.
|
|
181
|
+
"""
|
|
182
|
+
exported_string = self.generate()
|
|
183
|
+
imports = self.get_imports()
|
|
184
|
+
after_export = self.get_after_export()
|
|
185
|
+
result: ExporterReturnType = {
|
|
186
|
+
"content": exported_string,
|
|
187
|
+
"imports": imports,
|
|
188
|
+
"before_export": None,
|
|
189
|
+
"after_export": after_export,
|
|
190
|
+
"environment_variables": None,
|
|
191
|
+
}
|
|
192
|
+
return result
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Model/LLM related string generation functions.
|
|
4
|
+
|
|
5
|
+
Functions
|
|
6
|
+
---------
|
|
7
|
+
export_models
|
|
8
|
+
Get the string representations of the LLM configs.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Callable, Dict, List, Optional
|
|
13
|
+
|
|
14
|
+
from waldiez.models import WaldiezAgent, WaldiezModel
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def export_models(
|
|
18
|
+
flow_name: str,
|
|
19
|
+
all_models: List[WaldiezModel],
|
|
20
|
+
model_names: Dict[str, str],
|
|
21
|
+
serializer: Callable[..., str],
|
|
22
|
+
output_dir: Optional[Path] = None,
|
|
23
|
+
) -> str:
|
|
24
|
+
"""Get the string representations of all the models in the flow.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
flow_name : str
|
|
29
|
+
The name of the flow.
|
|
30
|
+
all_models : List[WaldiezModel]
|
|
31
|
+
All the models in the flow.
|
|
32
|
+
model_names : Dict[str, str]
|
|
33
|
+
A mapping of model ids to model names.
|
|
34
|
+
serializer : Callable[..., str]
|
|
35
|
+
The serializer function.
|
|
36
|
+
output_dir : Optional[Path]
|
|
37
|
+
The output directory to write the api keys.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
str
|
|
42
|
+
The models' llm config string.
|
|
43
|
+
"""
|
|
44
|
+
content = ""
|
|
45
|
+
for model in all_models:
|
|
46
|
+
model_name = model_names[model.id]
|
|
47
|
+
model_config = model.get_llm_config()
|
|
48
|
+
model_config["api_key"] = (
|
|
49
|
+
f'get_{flow_name}_model_api_key("{model_name}")'
|
|
50
|
+
)
|
|
51
|
+
model_dict_str = serializer(model_config, tabs=0)
|
|
52
|
+
model_dict_str = model_dict_str.replace(
|
|
53
|
+
f'"get_{flow_name}_model_api_key("{model_name}")"',
|
|
54
|
+
f'get_{flow_name}_model_api_key("{model_name}")',
|
|
55
|
+
)
|
|
56
|
+
content += "\n" + f"{model_name}_llm_config = {model_dict_str}" + "\n"
|
|
57
|
+
if output_dir:
|
|
58
|
+
write_api_keys(flow_name, all_models, model_names, output_dir)
|
|
59
|
+
return content
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_agent_llm_config_arg(
|
|
63
|
+
agent: WaldiezAgent,
|
|
64
|
+
all_models: List[WaldiezModel],
|
|
65
|
+
model_names: Dict[str, str],
|
|
66
|
+
tabs: int = 1,
|
|
67
|
+
) -> str:
|
|
68
|
+
"""Get the string representation of the agent's llm config argument.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
agent : WaldiezAgent
|
|
73
|
+
The agent.
|
|
74
|
+
all_models : List[WaldiezModel]
|
|
75
|
+
All the models in the flow.
|
|
76
|
+
model_names : Dict[str, str]
|
|
77
|
+
A mapping of model ids to model names.
|
|
78
|
+
tabs : int, optional
|
|
79
|
+
The number of tabs for indentation, by default 1.
|
|
80
|
+
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
str
|
|
84
|
+
The agent's llm config argument to use.
|
|
85
|
+
"""
|
|
86
|
+
tab = " " * tabs if tabs > 0 else ""
|
|
87
|
+
if not agent.data.model_ids:
|
|
88
|
+
return f"{tab}llm_config=False," + "\n"
|
|
89
|
+
content = f"{tab}llm_config=" + "{\n"
|
|
90
|
+
content += f'{tab} "config_list": ['
|
|
91
|
+
got_at_least_one_model = False
|
|
92
|
+
for model_id in agent.data.model_ids:
|
|
93
|
+
model = next((m for m in all_models if m.id == model_id), None)
|
|
94
|
+
if model is not None:
|
|
95
|
+
model_name = model_names[model_id]
|
|
96
|
+
content += "\n" + f"{tab} {model_name}_llm_config,"
|
|
97
|
+
got_at_least_one_model = True
|
|
98
|
+
if not got_at_least_one_model: # pragma: no cover
|
|
99
|
+
return f"{tab}llm_config=False," + "\n"
|
|
100
|
+
content += "\n" + f"{tab} ]," + "\n"
|
|
101
|
+
content += tab + "},\n"
|
|
102
|
+
return content
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def write_api_keys(
|
|
106
|
+
flow_name: str,
|
|
107
|
+
all_models: List[WaldiezModel],
|
|
108
|
+
model_names: Dict[str, str],
|
|
109
|
+
output_dir: Path,
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Write the api keys to a separate file.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
flow_name : str
|
|
116
|
+
The name of the flow.
|
|
117
|
+
all_models : List[WaldiezModel]
|
|
118
|
+
All the models in the flow.
|
|
119
|
+
model_names : Dict[str, str]
|
|
120
|
+
A mapping of model ids to model names.
|
|
121
|
+
output_dir : Path
|
|
122
|
+
The output directory to write the api keys.
|
|
123
|
+
"""
|
|
124
|
+
flow_name_upper = flow_name.upper()
|
|
125
|
+
api_keys_content = f'''
|
|
126
|
+
"""API keys for the {flow_name} models."""
|
|
127
|
+
|
|
128
|
+
import os
|
|
129
|
+
|
|
130
|
+
__{flow_name_upper}_MODEL_API_KEYS__ = {{'''
|
|
131
|
+
for model in all_models:
|
|
132
|
+
model_name = model_names[model.id]
|
|
133
|
+
key_env = model.api_key_env_key
|
|
134
|
+
api_keys_content += (
|
|
135
|
+
"\n" + f' "{model_name}": '
|
|
136
|
+
f'{{"key": "{model.api_key}", "env_key": "{key_env}"}},'
|
|
137
|
+
)
|
|
138
|
+
api_keys_content += "\n}\n"
|
|
139
|
+
api_keys_content += f'''
|
|
140
|
+
|
|
141
|
+
def get_{flow_name}_model_api_key(model_name: str) -> str:
|
|
142
|
+
"""Get the api key for the model.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
model_name : str
|
|
147
|
+
The name of the model.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
str
|
|
152
|
+
The api key for the model.
|
|
153
|
+
"""
|
|
154
|
+
entry = __{flow_name_upper}_MODEL_API_KEYS__.get(model_name, {{}})
|
|
155
|
+
if not entry:
|
|
156
|
+
return ""
|
|
157
|
+
env_key = entry.get("env_key", "")
|
|
158
|
+
if env_key:
|
|
159
|
+
from_env = os.environ.get(env_key, "")
|
|
160
|
+
if from_env:
|
|
161
|
+
return from_env
|
|
162
|
+
return entry.get("key", "")
|
|
163
|
+
'''
|
|
164
|
+
file_name = f"{flow_name}_api_keys.py"
|
|
165
|
+
with open(output_dir / file_name, "w", encoding="utf-8", newline="\n") as f:
|
|
166
|
+
f.write(api_keys_content)
|
|
@@ -1,163 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Export skill."""
|
|
2
4
|
|
|
3
|
-
|
|
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
|
-
"""
|
|
5
|
+
from .skills_exporter import SkillsExporter
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
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 _write_skill_secrets(
|
|
73
|
-
skill: WaldiezSkill,
|
|
74
|
-
skill_name: str,
|
|
75
|
-
output_dir: Path,
|
|
76
|
-
) -> None:
|
|
77
|
-
"""Write the skill secrets to a file.
|
|
78
|
-
|
|
79
|
-
Parameters
|
|
80
|
-
----------
|
|
81
|
-
skill : WaldiezSkill
|
|
82
|
-
The skill.
|
|
83
|
-
skill_name : str
|
|
84
|
-
The name of the skill.
|
|
85
|
-
output_dir : Path
|
|
86
|
-
The output directory to save the secrets to.
|
|
87
|
-
"""
|
|
88
|
-
if not skill.secrets:
|
|
89
|
-
return
|
|
90
|
-
secrets_file = output_dir / f"{skill_name}_secrets.py"
|
|
91
|
-
with secrets_file.open("w", encoding="utf-8", newline="\n") as f:
|
|
92
|
-
f.write('"""Secrets for the skill."""\n')
|
|
93
|
-
f.write("from os import environ\n\n")
|
|
94
|
-
for key, value in skill.secrets.items():
|
|
95
|
-
f.write(f'environ["{key}"] = "{value}"\n')
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def export_skills(
|
|
99
|
-
skills: List[WaldiezSkill],
|
|
100
|
-
skill_names: Dict[str, str],
|
|
101
|
-
output_dir: Optional[Union[str, Path]] = None,
|
|
102
|
-
) -> Tuple[Set[str], Set[Tuple[str, str]]]:
|
|
103
|
-
"""Get the skills' contents and secrets.
|
|
104
|
-
|
|
105
|
-
If `output_dir` is provided, the contents are saved to that directory.
|
|
106
|
-
|
|
107
|
-
Parameters
|
|
108
|
-
----------
|
|
109
|
-
skills : List[WaldiezSkill]
|
|
110
|
-
The skills.
|
|
111
|
-
skill_names : Dict[str, str]
|
|
112
|
-
The skill names.
|
|
113
|
-
output_dir : Optional[Union[str, Path]]
|
|
114
|
-
The output directory to save the skills to.
|
|
115
|
-
|
|
116
|
-
Returns
|
|
117
|
-
-------
|
|
118
|
-
Tuple[Set[str], Set[Tuple[str, str]]]
|
|
119
|
-
- The skill imports to use in the main file.
|
|
120
|
-
- The skill secrets to set as environment variables.
|
|
121
|
-
|
|
122
|
-
Example
|
|
123
|
-
-------
|
|
124
|
-
```python
|
|
125
|
-
>>> from waldiez.models import WaldiezSkill, WaldiezSkillData
|
|
126
|
-
>>> skill1 = WaldiezSkill(
|
|
127
|
-
... id="ws-1",
|
|
128
|
-
... name="skill1",
|
|
129
|
-
... description="A skill that does something.",
|
|
130
|
-
... tags=["skill", "skill1"],
|
|
131
|
-
... requirements=[],
|
|
132
|
-
... data=WaldiezSkillData(
|
|
133
|
-
... content="def skill1():\\n pass",
|
|
134
|
-
... secrets={"API_KEY": "1234567890"},
|
|
135
|
-
... )
|
|
136
|
-
>>> skill_names = {"ws-1": "skill1"}
|
|
137
|
-
>>> export_skills([skill1], skill_names, None)
|
|
138
|
-
({'from skill1 import skill1'}, {('API_KEY', '1234567890')})
|
|
139
|
-
```
|
|
140
|
-
"""
|
|
141
|
-
skill_imports: Set[str] = set()
|
|
142
|
-
skill_secrets: Set[Tuple[str, str]] = set()
|
|
143
|
-
for skill in skills:
|
|
144
|
-
skill_name = skill_names[skill.id]
|
|
145
|
-
skill_secrets.update(skill.secrets.items())
|
|
146
|
-
if not output_dir:
|
|
147
|
-
skill_imports.add(f"from {skill_name} import {skill_name}")
|
|
148
|
-
continue
|
|
149
|
-
if not isinstance(output_dir, Path):
|
|
150
|
-
output_dir = Path(output_dir)
|
|
151
|
-
if not skill.secrets:
|
|
152
|
-
skill_imports.add(f"from {skill_name} import {skill_name}")
|
|
153
|
-
else:
|
|
154
|
-
# have the secrets before the skill
|
|
155
|
-
skill_imports.add(
|
|
156
|
-
f"import {skill_name}_secrets # noqa\n"
|
|
157
|
-
f"from {skill_name} import {skill_name}"
|
|
158
|
-
)
|
|
159
|
-
_write_skill_secrets(skill, skill_name, output_dir)
|
|
160
|
-
skill_file = output_dir / f"{skill_name}.py"
|
|
161
|
-
with skill_file.open("w", encoding="utf-8", newline="\n") as f:
|
|
162
|
-
f.write(skill.content)
|
|
163
|
-
return skill_imports, skill_secrets
|
|
7
|
+
__all__ = [
|
|
8
|
+
"SkillsExporter",
|
|
9
|
+
]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Skills/tools related string generation functions.
|
|
4
|
+
|
|
5
|
+
Functions
|
|
6
|
+
---------
|
|
7
|
+
get_agent_skill_registration
|
|
8
|
+
Get an agent's skill registration string.
|
|
9
|
+
export_skills
|
|
10
|
+
Get the skills content and secrets.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
15
|
+
|
|
16
|
+
from waldiez.models import WaldiezAgent, WaldiezSkill
|
|
17
|
+
|
|
18
|
+
from ..base import (
|
|
19
|
+
AgentPosition,
|
|
20
|
+
AgentPositions,
|
|
21
|
+
BaseExporter,
|
|
22
|
+
ExporterMixin,
|
|
23
|
+
ExporterReturnType,
|
|
24
|
+
ExportPosition,
|
|
25
|
+
ImportPosition,
|
|
26
|
+
)
|
|
27
|
+
from .utils import export_skills, get_agent_skill_registrations
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SkillsExporter(BaseExporter, ExporterMixin):
|
|
31
|
+
"""Skill exporter."""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
flow_name: str,
|
|
36
|
+
agents: List[WaldiezAgent],
|
|
37
|
+
agent_names: Dict[str, str],
|
|
38
|
+
skills: List[WaldiezSkill],
|
|
39
|
+
skill_names: Dict[str, str],
|
|
40
|
+
output_dir: Optional[Union[str, Path]] = None,
|
|
41
|
+
) -> None:
|
|
42
|
+
"""Initialize the skill exporter.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
flow_name : str
|
|
47
|
+
The name of the flow.
|
|
48
|
+
agents : List[WaldiezAgent]
|
|
49
|
+
The agents.
|
|
50
|
+
agent_names : Dict[str, str]
|
|
51
|
+
The agent names.
|
|
52
|
+
skills : List[WaldiezSkill]
|
|
53
|
+
The skills.
|
|
54
|
+
skill_names : Dict[str, str]
|
|
55
|
+
The skill names.
|
|
56
|
+
output_dir : Optional[Union[str, Path]], optional
|
|
57
|
+
The output directory if any, by default None
|
|
58
|
+
"""
|
|
59
|
+
self.flow_name = flow_name
|
|
60
|
+
self.agents = agents
|
|
61
|
+
self.agent_names = agent_names
|
|
62
|
+
self.skills = skills
|
|
63
|
+
self.skill_names = skill_names
|
|
64
|
+
self.output_dir = output_dir
|
|
65
|
+
self.skill_imports, self.skill_secrets, self.skills_contents = (
|
|
66
|
+
export_skills(
|
|
67
|
+
flow_name=flow_name,
|
|
68
|
+
skills=skills,
|
|
69
|
+
skill_names=skill_names,
|
|
70
|
+
output_dir=output_dir,
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def get_environment_variables(self) -> List[Tuple[str, str]]:
|
|
75
|
+
"""Get the environment variables to set.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
List[Tuple[str, str]]
|
|
80
|
+
The environment variables to set.
|
|
81
|
+
"""
|
|
82
|
+
return self.skill_secrets
|
|
83
|
+
|
|
84
|
+
def get_imports(self) -> List[Tuple[str, ImportPosition]]:
|
|
85
|
+
""" "Generate the imports string.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
Tuple[str, int]
|
|
90
|
+
The exported imports and the position of the imports.
|
|
91
|
+
"""
|
|
92
|
+
if not self.skill_imports:
|
|
93
|
+
return []
|
|
94
|
+
imports: List[Tuple[str, ImportPosition]] = []
|
|
95
|
+
for skill_import in self.skill_imports:
|
|
96
|
+
if (skill_import, ImportPosition.LOCAL) not in imports:
|
|
97
|
+
imports.append((skill_import, ImportPosition.LOCAL))
|
|
98
|
+
return imports
|
|
99
|
+
|
|
100
|
+
def get_before_export(
|
|
101
|
+
self,
|
|
102
|
+
) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
|
|
103
|
+
"""Generate the content before the main export.
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
|
|
108
|
+
The exported content before the main export and its position.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
def generate(self) -> Optional[str]:
|
|
112
|
+
"""Generate the main export.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
Optional[str]
|
|
117
|
+
The exported content.
|
|
118
|
+
"""
|
|
119
|
+
return self.skills_contents
|
|
120
|
+
|
|
121
|
+
def get_after_export(
|
|
122
|
+
self,
|
|
123
|
+
) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
|
|
124
|
+
"""Generate the content after the main export.
|
|
125
|
+
|
|
126
|
+
Returns
|
|
127
|
+
-------
|
|
128
|
+
Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
|
|
129
|
+
The exported content after the main export and its position.
|
|
130
|
+
"""
|
|
131
|
+
agent_registrations: List[
|
|
132
|
+
Tuple[str, Union[ExportPosition, AgentPosition]]
|
|
133
|
+
] = []
|
|
134
|
+
for agent in self.agents:
|
|
135
|
+
agent_registration = get_agent_skill_registrations(
|
|
136
|
+
agent=agent,
|
|
137
|
+
agent_names=self.agent_names,
|
|
138
|
+
all_skills=self.skills,
|
|
139
|
+
skill_names=self.skill_names,
|
|
140
|
+
string_escape=self.string_escape,
|
|
141
|
+
)
|
|
142
|
+
if agent_registration:
|
|
143
|
+
# after all agents since we use the executor
|
|
144
|
+
# (it might not yet be defined)
|
|
145
|
+
position = AgentPosition(None, AgentPositions.AFTER_ALL, 1)
|
|
146
|
+
agent_registrations.append((agent_registration, position))
|
|
147
|
+
return agent_registrations
|
|
148
|
+
|
|
149
|
+
def export(self) -> ExporterReturnType:
|
|
150
|
+
"""Export the skills.
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
ExporterReturnType
|
|
155
|
+
The exported skills content, the imports,
|
|
156
|
+
the before export strings, the after export strings,
|
|
157
|
+
and the environment variables.
|
|
158
|
+
"""
|
|
159
|
+
imports = self.get_imports()
|
|
160
|
+
after_export = self.get_after_export()
|
|
161
|
+
environment_variables = self.get_environment_variables()
|
|
162
|
+
result: ExporterReturnType = {
|
|
163
|
+
"content": self.generate(),
|
|
164
|
+
"imports": imports,
|
|
165
|
+
"before_export": None,
|
|
166
|
+
"after_export": after_export,
|
|
167
|
+
"environment_variables": environment_variables,
|
|
168
|
+
}
|
|
169
|
+
return result
|