waldiez 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of waldiez might be problematic. Click here for more details.
- waldiez/__init__.py +15 -0
- waldiez/__main__.py +6 -0
- waldiez/_version.py +3 -0
- waldiez/cli.py +162 -0
- waldiez/exporter.py +293 -0
- waldiez/exporting/__init__.py +14 -0
- waldiez/exporting/agents/__init__.py +5 -0
- waldiez/exporting/agents/agent.py +229 -0
- waldiez/exporting/agents/agent_skills.py +67 -0
- waldiez/exporting/agents/code_execution.py +67 -0
- waldiez/exporting/agents/group_manager.py +209 -0
- waldiez/exporting/agents/llm_config.py +53 -0
- waldiez/exporting/agents/rag_user/__init__.py +5 -0
- waldiez/exporting/agents/rag_user/chroma_utils.py +134 -0
- waldiez/exporting/agents/rag_user/mongo_utils.py +83 -0
- waldiez/exporting/agents/rag_user/pgvector_utils.py +93 -0
- waldiez/exporting/agents/rag_user/qdrant_utils.py +112 -0
- waldiez/exporting/agents/rag_user/rag_user.py +165 -0
- waldiez/exporting/agents/rag_user/vector_db.py +119 -0
- waldiez/exporting/agents/teachability.py +37 -0
- waldiez/exporting/agents/termination_message.py +45 -0
- waldiez/exporting/chats/__init__.py +14 -0
- waldiez/exporting/chats/chats.py +46 -0
- waldiez/exporting/chats/helpers.py +395 -0
- waldiez/exporting/chats/nested.py +264 -0
- waldiez/exporting/flow/__init__.py +5 -0
- waldiez/exporting/flow/def_main.py +37 -0
- waldiez/exporting/flow/flow.py +185 -0
- waldiez/exporting/models/__init__.py +193 -0
- waldiez/exporting/skills/__init__.py +128 -0
- waldiez/exporting/utils/__init__.py +34 -0
- waldiez/exporting/utils/comments.py +136 -0
- waldiez/exporting/utils/importing.py +267 -0
- waldiez/exporting/utils/logging_utils.py +203 -0
- waldiez/exporting/utils/method_utils.py +35 -0
- waldiez/exporting/utils/naming.py +127 -0
- waldiez/exporting/utils/object_string.py +81 -0
- waldiez/io_stream.py +181 -0
- waldiez/models/__init__.py +107 -0
- waldiez/models/agents/__init__.py +65 -0
- waldiez/models/agents/agent/__init__.py +21 -0
- waldiez/models/agents/agent/agent.py +190 -0
- waldiez/models/agents/agent/agent_data.py +162 -0
- waldiez/models/agents/agent/code_execution.py +71 -0
- waldiez/models/agents/agent/linked_skill.py +30 -0
- waldiez/models/agents/agent/nested_chat.py +73 -0
- waldiez/models/agents/agent/teachability.py +68 -0
- waldiez/models/agents/agent/termination_message.py +167 -0
- waldiez/models/agents/agents.py +129 -0
- waldiez/models/agents/assistant/__init__.py +6 -0
- waldiez/models/agents/assistant/assistant.py +41 -0
- waldiez/models/agents/assistant/assistant_data.py +29 -0
- waldiez/models/agents/group_manager/__init__.py +19 -0
- waldiez/models/agents/group_manager/group_manager.py +87 -0
- waldiez/models/agents/group_manager/group_manager_data.py +91 -0
- waldiez/models/agents/group_manager/speakers.py +211 -0
- waldiez/models/agents/rag_user/__init__.py +26 -0
- waldiez/models/agents/rag_user/rag_user.py +58 -0
- waldiez/models/agents/rag_user/rag_user_data.py +32 -0
- waldiez/models/agents/rag_user/retrieve_config.py +592 -0
- waldiez/models/agents/rag_user/vector_db_config.py +162 -0
- waldiez/models/agents/user_proxy/__init__.py +6 -0
- waldiez/models/agents/user_proxy/user_proxy.py +41 -0
- waldiez/models/agents/user_proxy/user_proxy_data.py +30 -0
- waldiez/models/chat/__init__.py +22 -0
- waldiez/models/chat/chat.py +129 -0
- waldiez/models/chat/chat_data.py +326 -0
- waldiez/models/chat/chat_message.py +304 -0
- waldiez/models/chat/chat_nested.py +160 -0
- waldiez/models/chat/chat_summary.py +110 -0
- waldiez/models/common/__init__.py +38 -0
- waldiez/models/common/base.py +63 -0
- waldiez/models/common/method_utils.py +165 -0
- waldiez/models/flow/__init__.py +9 -0
- waldiez/models/flow/flow.py +302 -0
- waldiez/models/flow/flow_data.py +87 -0
- waldiez/models/model/__init__.py +11 -0
- waldiez/models/model/model.py +169 -0
- waldiez/models/model/model_data.py +86 -0
- waldiez/models/skill/__init__.py +9 -0
- waldiez/models/skill/skill.py +129 -0
- waldiez/models/skill/skill_data.py +37 -0
- waldiez/models/waldiez.py +301 -0
- waldiez/py.typed +0 -0
- waldiez/runner.py +304 -0
- waldiez/stream/__init__.py +7 -0
- waldiez/stream/consumer.py +139 -0
- waldiez/stream/provider.py +339 -0
- waldiez/stream/server.py +412 -0
- waldiez-0.1.0.dist-info/METADATA +181 -0
- waldiez-0.1.0.dist-info/RECORD +94 -0
- waldiez-0.1.0.dist-info/WHEEL +4 -0
- waldiez-0.1.0.dist-info/entry_points.txt +2 -0
- waldiez-0.1.0.dist-info/licenses/LICENSE +21 -0
waldiez/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Waldiez package."""
|
|
2
|
+
|
|
3
|
+
from ._version import __version__
|
|
4
|
+
from .exporter import WaldiezExporter
|
|
5
|
+
from .io_stream import WaldiezIOStream
|
|
6
|
+
from .models import Waldiez
|
|
7
|
+
from .runner import WaldiezRunner
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"Waldiez",
|
|
11
|
+
"WaldiezExporter",
|
|
12
|
+
"WaldiezIOStream",
|
|
13
|
+
"WaldiezRunner",
|
|
14
|
+
"__version__",
|
|
15
|
+
]
|
waldiez/__main__.py
ADDED
waldiez/_version.py
ADDED
waldiez/cli.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Command line interface to convert or run a waldiez file."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
|
|
11
|
+
from autogen import ChatResult # type: ignore[import-untyped]
|
|
12
|
+
|
|
13
|
+
from . import Waldiez, __version__
|
|
14
|
+
from .exporter import WaldiezExporter
|
|
15
|
+
from .runner import WaldiezRunner
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_parser() -> argparse.ArgumentParser:
|
|
19
|
+
"""Get the argument parser for the Waldiez package.
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
argparse.ArgumentParser
|
|
24
|
+
The argument parser.
|
|
25
|
+
"""
|
|
26
|
+
parser = argparse.ArgumentParser(
|
|
27
|
+
description="Run or export a Waldiez flow.",
|
|
28
|
+
prog="waldiez",
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"waldiez",
|
|
32
|
+
type=str,
|
|
33
|
+
help="Path to the Waldiez flow (*.waldiez) file.",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"-e",
|
|
37
|
+
"--export",
|
|
38
|
+
action="store_true",
|
|
39
|
+
help=(
|
|
40
|
+
"Export the Waldiez flow to a Python script or a jupyter notebook."
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"-o",
|
|
45
|
+
"--output",
|
|
46
|
+
type=str,
|
|
47
|
+
help=(
|
|
48
|
+
"Path to the output file. "
|
|
49
|
+
"If exporting, the file extension determines the output format. "
|
|
50
|
+
"If running, the output's directory will contain "
|
|
51
|
+
"the generated flow (.py) and any additional generated files."
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
parser.add_argument(
|
|
55
|
+
"-f",
|
|
56
|
+
"--force",
|
|
57
|
+
action="store_true",
|
|
58
|
+
help=("Override the output file if it already exists. "),
|
|
59
|
+
)
|
|
60
|
+
parser.add_argument(
|
|
61
|
+
"-v",
|
|
62
|
+
"--version",
|
|
63
|
+
action="version",
|
|
64
|
+
version=f"waldiez version: {__version__}",
|
|
65
|
+
)
|
|
66
|
+
return parser
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _log_result(result: ChatResult) -> None:
|
|
70
|
+
"""Log the result of the Waldiez flow."""
|
|
71
|
+
logger = logging.getLogger("waldiez::cli")
|
|
72
|
+
logger.info("Chat History:\n")
|
|
73
|
+
logger.info(result.chat_history)
|
|
74
|
+
logger.info("Summary:\n")
|
|
75
|
+
logger.info(result.summary)
|
|
76
|
+
logger.info("Cost:\n")
|
|
77
|
+
logger.info(result.cost)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _run(data: Dict[str, Any], output_path: Optional[str]) -> None:
|
|
81
|
+
"""Run the Waldiez flow."""
|
|
82
|
+
waldiez = Waldiez.from_dict(data)
|
|
83
|
+
runner = WaldiezRunner(waldiez)
|
|
84
|
+
results = runner.run(stream=None, output_path=output_path)
|
|
85
|
+
if isinstance(results, list):
|
|
86
|
+
for result in results:
|
|
87
|
+
_log_result(result)
|
|
88
|
+
sep = "-" * 80
|
|
89
|
+
print(f"\n{sep}\n")
|
|
90
|
+
else:
|
|
91
|
+
_log_result(results)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def main() -> None:
|
|
95
|
+
"""Parse the command line arguments and run the Waldiez flow."""
|
|
96
|
+
parser = get_parser()
|
|
97
|
+
args = parser.parse_args()
|
|
98
|
+
logger = _get_logger()
|
|
99
|
+
waldiez_file: str = args.waldiez
|
|
100
|
+
if not os.path.exists(waldiez_file):
|
|
101
|
+
logger.error("File not found: %s", waldiez_file)
|
|
102
|
+
sys.exit(1)
|
|
103
|
+
if not waldiez_file.endswith((".json", ".waldiez")):
|
|
104
|
+
logger.error("Only .json or .waldiez files are supported.")
|
|
105
|
+
sys.exit(1)
|
|
106
|
+
with open(waldiez_file, "r", encoding="utf-8") as file:
|
|
107
|
+
try:
|
|
108
|
+
data = json.load(file)
|
|
109
|
+
except json.decoder.JSONDecodeError:
|
|
110
|
+
logger.error("Invalid .waldiez file: %s. Not a valid json?", file)
|
|
111
|
+
return
|
|
112
|
+
if args.export is True:
|
|
113
|
+
if args.output is None:
|
|
114
|
+
logger.error("Please provide an output file.")
|
|
115
|
+
sys.exit(1)
|
|
116
|
+
if not args.output.endswith((".py", ".ipynb", ".json", ".waldiez")):
|
|
117
|
+
logger.error(
|
|
118
|
+
"Only Python scripts, Jupyter notebooks "
|
|
119
|
+
"and JSON/Waldiez files are supported."
|
|
120
|
+
)
|
|
121
|
+
sys.exit(1)
|
|
122
|
+
output_file = Path(args.output).resolve()
|
|
123
|
+
waldiez = Waldiez.from_dict(data)
|
|
124
|
+
exporter = WaldiezExporter(waldiez)
|
|
125
|
+
exporter.export(output_file, force=args.force)
|
|
126
|
+
generated = str(output_file).replace(os.getcwd(), ".")
|
|
127
|
+
logger.info("Generated: %s", generated)
|
|
128
|
+
else:
|
|
129
|
+
_run(data, args.output)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _get_logger(level: int = logging.INFO) -> logging.Logger:
|
|
133
|
+
"""Get the logger for the Waldiez package.
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
level : int or str, optional
|
|
138
|
+
The logging level. Default is logging.INFO.
|
|
139
|
+
|
|
140
|
+
Returns
|
|
141
|
+
-------
|
|
142
|
+
logging.Logger
|
|
143
|
+
The logger.
|
|
144
|
+
"""
|
|
145
|
+
# check if we already have setup a config
|
|
146
|
+
|
|
147
|
+
if not logging.getLogger().handlers:
|
|
148
|
+
logging.basicConfig(
|
|
149
|
+
level=level,
|
|
150
|
+
format="%(levelname)s %(message)s",
|
|
151
|
+
stream=sys.stderr,
|
|
152
|
+
force=True,
|
|
153
|
+
)
|
|
154
|
+
logger = logging.getLogger("waldiez::cli")
|
|
155
|
+
current_level = logger.getEffectiveLevel()
|
|
156
|
+
if current_level != level:
|
|
157
|
+
logger.setLevel(level)
|
|
158
|
+
return logger
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if __name__ == "__main__":
|
|
162
|
+
main()
|
waldiez/exporter.py
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""Waldiez exporter.
|
|
2
|
+
|
|
3
|
+
The role of the exporter is to export the model's data
|
|
4
|
+
to an autogen's flow with one or more chats.
|
|
5
|
+
|
|
6
|
+
The resulting file(s): a `flow.py` file with one `main()` function
|
|
7
|
+
to trigger the chat(s).
|
|
8
|
+
If additional tools/skills are used,
|
|
9
|
+
they are exported as their `skill_name` in the same directory with
|
|
10
|
+
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}`
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# pylint: disable=inconsistent-quotes
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
import shutil
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Dict, List, Optional, Union
|
|
23
|
+
|
|
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
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class WaldiezExporter:
|
|
35
|
+
"""Waldiez exporter.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
waldiez (Waldiez): The Waldiez instance.
|
|
39
|
+
"""
|
|
40
|
+
|
|
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
|
+
def __init__(self, waldiez: Waldiez) -> None:
|
|
51
|
+
"""Initialize the Waldiez exporter.
|
|
52
|
+
|
|
53
|
+
Parameters:
|
|
54
|
+
waldiez (Waldiez): The Waldiez instance.
|
|
55
|
+
"""
|
|
56
|
+
self.waldiez = waldiez
|
|
57
|
+
self._initialize()
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def load(cls, file_path: Path) -> "WaldiezExporter":
|
|
61
|
+
"""Load the Waldiez instance from a file.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
file_path : Path
|
|
66
|
+
The file path.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
WaldiezExporter
|
|
71
|
+
The Waldiez exporter.
|
|
72
|
+
"""
|
|
73
|
+
waldiez = Waldiez.load(file_path)
|
|
74
|
+
return cls(waldiez)
|
|
75
|
+
|
|
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
|
+
def export(self, path: Union[str, Path], force: bool = False) -> None:
|
|
127
|
+
"""Export the Waldiez instance.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
path : Union[str, Path]
|
|
132
|
+
The path to export to.
|
|
133
|
+
force : bool, optional
|
|
134
|
+
Override the output file if it already exists, by default False.
|
|
135
|
+
|
|
136
|
+
Raises
|
|
137
|
+
------
|
|
138
|
+
FileExistsError
|
|
139
|
+
If the file already exists and force is False.
|
|
140
|
+
IsADirectoryError
|
|
141
|
+
If the output is a directory.
|
|
142
|
+
ValueError
|
|
143
|
+
If the file extension is invalid.
|
|
144
|
+
"""
|
|
145
|
+
if not isinstance(path, Path):
|
|
146
|
+
path = Path(path)
|
|
147
|
+
path = path.resolve()
|
|
148
|
+
if path.is_dir():
|
|
149
|
+
raise IsADirectoryError(f"Output is a directory: {path}")
|
|
150
|
+
if path.exists():
|
|
151
|
+
if force is False:
|
|
152
|
+
raise FileExistsError(f"File already exists: {path}")
|
|
153
|
+
path.unlink(missing_ok=True)
|
|
154
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
155
|
+
extension = path.suffix
|
|
156
|
+
if extension == ".waldiez":
|
|
157
|
+
self.to_waldiez(path)
|
|
158
|
+
elif extension == ".py":
|
|
159
|
+
self.to_py(path)
|
|
160
|
+
elif extension == ".ipynb":
|
|
161
|
+
self.to_ipynb(path)
|
|
162
|
+
else:
|
|
163
|
+
raise ValueError(f"Invalid extension: {extension}")
|
|
164
|
+
|
|
165
|
+
def to_ipynb(self, path: Path) -> None:
|
|
166
|
+
"""Export flow to jupyter notebook.
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
path : Path
|
|
171
|
+
The path to export to.
|
|
172
|
+
|
|
173
|
+
Raises
|
|
174
|
+
------
|
|
175
|
+
RuntimeError
|
|
176
|
+
If the notebook could not be generated.
|
|
177
|
+
"""
|
|
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(
|
|
187
|
+
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
|
+
output_dir=path.parent,
|
|
193
|
+
notebook=True,
|
|
194
|
+
)
|
|
195
|
+
# we first create a .py file with the content
|
|
196
|
+
# and then convert it to a notebook using jupytext
|
|
197
|
+
py_path = path.with_suffix(".tmp.py")
|
|
198
|
+
with open(py_path, "w", encoding="utf-8") as f:
|
|
199
|
+
f.write(content)
|
|
200
|
+
if not shutil.which("jupytext"): # pragma: no cover
|
|
201
|
+
run_command(
|
|
202
|
+
[sys.executable, "-m", "pip", "install", "jupytext"],
|
|
203
|
+
allow_error=False,
|
|
204
|
+
)
|
|
205
|
+
run_command(
|
|
206
|
+
["jupytext", "--to", "notebook", str(py_path)],
|
|
207
|
+
allow_error=False,
|
|
208
|
+
)
|
|
209
|
+
ipynb_path = str(py_path).replace(".tmp.py", ".tmp.ipynb")
|
|
210
|
+
if not os.path.exists(ipynb_path): # pragma: no cover
|
|
211
|
+
raise RuntimeError("Could not generate notebook")
|
|
212
|
+
Path(ipynb_path).rename(ipynb_path.replace(".tmp.ipynb", ".ipynb"))
|
|
213
|
+
py_path.unlink(missing_ok=True)
|
|
214
|
+
|
|
215
|
+
def to_py(self, path: Path) -> None:
|
|
216
|
+
"""Export waldiez flow to python script.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
path : Path
|
|
221
|
+
The path to export to.
|
|
222
|
+
"""
|
|
223
|
+
content = "#!/usr/bin/env python\n"
|
|
224
|
+
content += f'"""{self.waldiez.name}\n\n'
|
|
225
|
+
content += f"{self.waldiez.description}\n\n"
|
|
226
|
+
content += f"Tags: {', '.join(self.waldiez.tags)}\n\n"
|
|
227
|
+
content += f"Requirements: {', '.join(self.waldiez.requirements)}\n\n"
|
|
228
|
+
content += '"""\n\n'
|
|
229
|
+
content += "# cspell: disable\n"
|
|
230
|
+
content += "# flake8: noqa\n\n"
|
|
231
|
+
content += export_flow(
|
|
232
|
+
waldiez=self.waldiez,
|
|
233
|
+
agents=(self._agents, self._agent_names),
|
|
234
|
+
chats=(self._chats, self._chat_names),
|
|
235
|
+
models=(self._models, self._model_names),
|
|
236
|
+
skills=(self._skills, self._skill_names),
|
|
237
|
+
output_dir=path.parent,
|
|
238
|
+
notebook=False,
|
|
239
|
+
)
|
|
240
|
+
content += '\n\nif __name__ == "__main__":\n'
|
|
241
|
+
content += " print(main())\n"
|
|
242
|
+
with open(path, "w", encoding="utf-8") as file:
|
|
243
|
+
file.write(content)
|
|
244
|
+
|
|
245
|
+
def to_waldiez(self, file_path: Path) -> None:
|
|
246
|
+
"""Export the Waldiez instance.
|
|
247
|
+
|
|
248
|
+
Parameters
|
|
249
|
+
----------
|
|
250
|
+
file_path : Path
|
|
251
|
+
The file path.
|
|
252
|
+
"""
|
|
253
|
+
with open(file_path, "w", encoding="utf-8") as file:
|
|
254
|
+
file.write(self.waldiez.model_dump_json())
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def run_command(
|
|
258
|
+
cmd: List[str],
|
|
259
|
+
cwd: Optional[Path] = None,
|
|
260
|
+
allow_error: bool = True,
|
|
261
|
+
) -> None:
|
|
262
|
+
"""Run a command.
|
|
263
|
+
|
|
264
|
+
Parameters
|
|
265
|
+
----------
|
|
266
|
+
cmd : List[str]
|
|
267
|
+
The command to run.
|
|
268
|
+
cwd : Path, optional
|
|
269
|
+
The working directory, by default None (current working directory).
|
|
270
|
+
allow_error : bool, optional
|
|
271
|
+
Whether to allow errors, by default True.
|
|
272
|
+
|
|
273
|
+
Raises
|
|
274
|
+
------
|
|
275
|
+
RuntimeError
|
|
276
|
+
If the command fails and allow_error is False.
|
|
277
|
+
"""
|
|
278
|
+
if not cwd:
|
|
279
|
+
cwd = Path.cwd()
|
|
280
|
+
# pylint: disable=broad-except
|
|
281
|
+
try:
|
|
282
|
+
subprocess.run(
|
|
283
|
+
cmd,
|
|
284
|
+
check=True,
|
|
285
|
+
cwd=cwd,
|
|
286
|
+
env=os.environ,
|
|
287
|
+
stdout=subprocess.PIPE,
|
|
288
|
+
stderr=subprocess.PIPE,
|
|
289
|
+
) # nosemgrep # nosec
|
|
290
|
+
except BaseException as error: # pragma: no cover
|
|
291
|
+
if allow_error:
|
|
292
|
+
return
|
|
293
|
+
raise RuntimeError(f"Error running command: {error}") from error
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Tools for exporting agents, models, skills and chats to strings."""
|
|
2
|
+
|
|
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
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"export_flow",
|
|
10
|
+
"comment",
|
|
11
|
+
"get_valid_instance_name",
|
|
12
|
+
"export_models",
|
|
13
|
+
"export_skills",
|
|
14
|
+
]
|