waldiez 0.1.10__tar.gz → 0.1.12__tar.gz
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-0.1.10 → waldiez-0.1.12}/PKG-INFO +52 -33
- {waldiez-0.1.10 → waldiez-0.1.12}/README.md +28 -10
- {waldiez-0.1.10 → waldiez-0.1.12}/pyproject.toml +26 -24
- waldiez-0.1.12/waldiez/__init__.py +31 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/__main__.py +2 -2
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/_version.py +1 -1
- waldiez-0.1.12/waldiez/cli.py +228 -0
- waldiez-0.1.12/waldiez/conflict_checker.py +23 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/skills/__init__.py +36 -1
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/runner.py +18 -1
- waldiez-0.1.10/waldiez/__init__.py +0 -13
- waldiez-0.1.10/waldiez/cli.py +0 -166
- {waldiez-0.1.10 → waldiez-0.1.12}/.gitignore +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/LICENSE +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporter.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/agent.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/agent_skills.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/code_execution.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/group_manager.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/llm_config.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/chroma_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/mongo_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/pgvector_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/qdrant_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/rag_user.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/rag_user/vector_db.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/teachability.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/agents/termination_message.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/chats/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/chats/chats.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/chats/helpers.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/chats/nested.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/flow/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/flow/def_main.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/flow/flow.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/models/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/comments.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/importing.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/logging_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/method_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/naming.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/object_string.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/exporting/utils/path_check.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/io/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/agent.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/agent_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/code_execution.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/linked_skill.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/nested_chat.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/teachability.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agent/termination_message.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/agents.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/assistant/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/assistant/assistant.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/assistant/assistant_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/group_manager/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/group_manager/group_manager.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/group_manager/group_manager_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/group_manager/speakers.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/rag_user/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/rag_user/rag_user.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/rag_user/rag_user_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/rag_user/retrieve_config.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/rag_user/vector_db_config.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/user_proxy/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/user_proxy/user_proxy.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/agents/user_proxy/user_proxy_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/chat/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/chat/chat.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/chat/chat_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/chat/chat_message.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/chat/chat_nested.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/chat/chat_summary.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/common/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/common/base.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/common/method_utils.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/flow/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/flow/flow.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/flow/flow_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/model/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/model/model.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/model/model_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/skill/__init__.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/skill/skill.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/skill/skill_data.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/models/waldiez.py +0 -0
- {waldiez-0.1.10 → waldiez-0.1.12}/waldiez/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: waldiez
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: waldiez
|
|
5
5
|
Project-URL: homepage, https://waldiez.github.io/waldiez/
|
|
6
6
|
Project-URL: repository, https://github.com/waldiez/waldiez.git
|
|
@@ -16,47 +16,48 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Requires-Python: <3.13,>=3.10
|
|
19
|
-
Requires-Dist: ag2==0.
|
|
19
|
+
Requires-Dist: ag2==0.4.1
|
|
20
20
|
Requires-Dist: jupytext
|
|
21
|
+
Requires-Dist: typer<0.13,>=0.9
|
|
21
22
|
Provides-Extra: ag2-extras
|
|
22
|
-
Requires-Dist: ag2[anthropic]==0.
|
|
23
|
-
Requires-Dist: ag2[bedrock]==0.
|
|
24
|
-
Requires-Dist: ag2[
|
|
25
|
-
Requires-Dist: ag2[
|
|
26
|
-
Requires-Dist: ag2[
|
|
27
|
-
Requires-Dist: ag2[
|
|
28
|
-
Requires-Dist: ag2[
|
|
29
|
-
Requires-Dist: ag2[retrievechat-
|
|
30
|
-
Requires-Dist: ag2[retrievechat-
|
|
31
|
-
Requires-Dist: ag2[retrievechat]==0.
|
|
32
|
-
Requires-Dist: ag2[
|
|
33
|
-
Requires-Dist: ag2[
|
|
34
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: ag2[anthropic]==0.4.1; extra == 'ag2-extras'
|
|
24
|
+
Requires-Dist: ag2[bedrock]==0.4.1; extra == 'ag2-extras'
|
|
25
|
+
Requires-Dist: ag2[captainagent]==0.4.1; extra == 'ag2-extras'
|
|
26
|
+
Requires-Dist: ag2[gemini]==0.4.1; extra == 'ag2-extras'
|
|
27
|
+
Requires-Dist: ag2[groq]==0.4.1; extra == 'ag2-extras'
|
|
28
|
+
Requires-Dist: ag2[lmm]==0.4.1; extra == 'ag2-extras'
|
|
29
|
+
Requires-Dist: ag2[mistral]==0.4.1; extra == 'ag2-extras'
|
|
30
|
+
Requires-Dist: ag2[retrievechat-mongodb]==0.4.1; extra == 'ag2-extras'
|
|
31
|
+
Requires-Dist: ag2[retrievechat-pgvector]==0.4.1; extra == 'ag2-extras'
|
|
32
|
+
Requires-Dist: ag2[retrievechat-qdrant]==0.4.1; extra == 'ag2-extras'
|
|
33
|
+
Requires-Dist: ag2[retrievechat]==0.4.1; extra == 'ag2-extras'
|
|
34
|
+
Requires-Dist: ag2[together]==0.4.1; extra == 'ag2-extras'
|
|
35
|
+
Requires-Dist: ag2[websurfer]==0.4.1; extra == 'ag2-extras'
|
|
35
36
|
Requires-Dist: fastembed==0.4.2; extra == 'ag2-extras'
|
|
36
|
-
Requires-Dist: pgvector>=0.
|
|
37
|
-
Requires-Dist: psycopg[binary]>=3.
|
|
37
|
+
Requires-Dist: pgvector>=0.3.6; extra == 'ag2-extras'
|
|
38
|
+
Requires-Dist: psycopg[binary]>=3.2.3; extra == 'ag2-extras'
|
|
38
39
|
Requires-Dist: pymongo==4.10.1; extra == 'ag2-extras'
|
|
39
40
|
Requires-Dist: qdrant-client==1.12.1; extra == 'ag2-extras'
|
|
40
41
|
Provides-Extra: dev
|
|
41
42
|
Requires-Dist: autoflake==2.3.1; extra == 'dev'
|
|
42
|
-
Requires-Dist: bandit==1.
|
|
43
|
+
Requires-Dist: bandit==1.8.0; extra == 'dev'
|
|
43
44
|
Requires-Dist: black[jupyter]==24.10.0; extra == 'dev'
|
|
44
45
|
Requires-Dist: flake8==7.1.1; extra == 'dev'
|
|
45
46
|
Requires-Dist: isort==5.13.2; extra == 'dev'
|
|
46
47
|
Requires-Dist: mypy==1.13.0; extra == 'dev'
|
|
47
48
|
Requires-Dist: pre-commit==4.0.1; extra == 'dev'
|
|
48
49
|
Requires-Dist: pydocstyle==6.3.0; extra == 'dev'
|
|
49
|
-
Requires-Dist: pylint==3.3.
|
|
50
|
+
Requires-Dist: pylint==3.3.2; extra == 'dev'
|
|
50
51
|
Requires-Dist: python-dotenv==1.0.1; extra == 'dev'
|
|
51
|
-
Requires-Dist: ruff==0.
|
|
52
|
-
Requires-Dist: types-pyyaml==6.0.12; extra == 'dev'
|
|
52
|
+
Requires-Dist: ruff==0.8.1; extra == 'dev'
|
|
53
|
+
Requires-Dist: types-pyyaml==6.0.12.20240917; extra == 'dev'
|
|
53
54
|
Requires-Dist: yamllint==1.35.1; extra == 'dev'
|
|
54
55
|
Provides-Extra: docs
|
|
55
56
|
Requires-Dist: mdx-include==1.4.2; extra == 'docs'
|
|
56
57
|
Requires-Dist: mdx-truly-sane-lists==1.3; extra == 'docs'
|
|
57
58
|
Requires-Dist: mkdocs-jupyter==0.25.1; extra == 'docs'
|
|
58
59
|
Requires-Dist: mkdocs-macros-plugin==1.3.7; extra == 'docs'
|
|
59
|
-
Requires-Dist: mkdocs-material==9.5.
|
|
60
|
+
Requires-Dist: mkdocs-material==9.5.47; extra == 'docs'
|
|
60
61
|
Requires-Dist: mkdocs-minify-html-plugin==0.2.3; extra == 'docs'
|
|
61
62
|
Requires-Dist: mkdocs==1.6.1; extra == 'docs'
|
|
62
63
|
Requires-Dist: mkdocstrings-python==1.12.2; extra == 'docs'
|
|
@@ -67,7 +68,7 @@ Requires-Dist: pytest-html==4.1.1; extra == 'test'
|
|
|
67
68
|
Requires-Dist: pytest-sugar==1.0.0; extra == 'test'
|
|
68
69
|
Requires-Dist: pytest-timeout==2.3.1; extra == 'test'
|
|
69
70
|
Requires-Dist: pytest-xdist==3.6.1; extra == 'test'
|
|
70
|
-
Requires-Dist: pytest==8.3.
|
|
71
|
+
Requires-Dist: pytest==8.3.4; extra == 'test'
|
|
71
72
|
Description-Content-Type: text/markdown
|
|
72
73
|
|
|
73
74
|
# Waldiez
|
|
@@ -82,9 +83,8 @@ To a python script or a jupyter notebook with the corresponding [ag2](https://gi
|
|
|
82
83
|
|
|
83
84
|
## Features
|
|
84
85
|
|
|
85
|
-
-
|
|
86
|
+
- Convert .waldiez flows to .py or .ipynb
|
|
86
87
|
- Run a .waldiez flow
|
|
87
|
-
- Include a `logs` folder with the logs of the flow in csv format
|
|
88
88
|
- Provide a custom [IOSStream](https://ag2ai.github.io/ag2/docs/reference/io/base#iostream) to handle input and output.
|
|
89
89
|
|
|
90
90
|
## Installation
|
|
@@ -106,10 +106,10 @@ python -m pip install git+https://github.com/waldiez/waldiez.git
|
|
|
106
106
|
### CLI
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
#
|
|
110
|
-
waldiez --
|
|
111
|
-
#
|
|
112
|
-
waldiez /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py] [--force]
|
|
109
|
+
# Convert a Waldiez flow to a python script or a jupyter notebook
|
|
110
|
+
waldiez convert --file /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py|.ipynb]
|
|
111
|
+
# Convert and run the script, optionally force generation if the output file already exists
|
|
112
|
+
waldiez run --file /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py] [--force]
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
### Using docker/podman
|
|
@@ -118,7 +118,7 @@ waldiez /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py] [--force]
|
|
|
118
118
|
CONTAINER_COMMAND=docker # or podman
|
|
119
119
|
# pull the image
|
|
120
120
|
$CONTAINER_COMMAND pull waldiez/waldiez
|
|
121
|
-
#
|
|
121
|
+
# Convert a Waldiez flow to a python script or a jupyter notebook
|
|
122
122
|
$CONTAINER_COMMAND run \
|
|
123
123
|
--rm \
|
|
124
124
|
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
@@ -132,12 +132,16 @@ $CONTAINER_COMMAND run \
|
|
|
132
132
|
-v /path/to/an/output:/output \
|
|
133
133
|
--userns=keep-id \
|
|
134
134
|
--security-opt label=disable \
|
|
135
|
-
waldiez/waldiez --
|
|
135
|
+
waldiez/waldiez convert --file /flow.waldiez --output /output/flow[.py|.ipynb]
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
```shell
|
|
139
|
-
#
|
|
140
|
-
$CONTAINER_COMMAND run
|
|
139
|
+
# Convert and run the script
|
|
140
|
+
$CONTAINER_COMMAND run \
|
|
141
|
+
--rm \
|
|
142
|
+
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
143
|
+
-v /path/to/an/output:/output \
|
|
144
|
+
waldiez/waldiez run --file /flow.waldiez --output /output/output[.py]
|
|
141
145
|
```
|
|
142
146
|
|
|
143
147
|
### As a library
|
|
@@ -236,6 +240,21 @@ with WaldiezIOStream.set_default(io_stream):
|
|
|
236
240
|
- [ag2 (formerly AutoGen)](https://github.com/ag2ai/ag2)
|
|
237
241
|
- [juptytext](https://github.com/mwouts/jupytext)
|
|
238
242
|
- [pydantic](https://github.com/pydantic/pydantic)
|
|
243
|
+
- [typer](https://github.com/fastapi/typer)
|
|
244
|
+
|
|
245
|
+
## Known Conflicts
|
|
246
|
+
|
|
247
|
+
- **autogen-agentchat**: This package conflicts with `ag2`. Ensure that `autogen-agentchat` is uninstalled before installing `waldiez`. If you have already installed `autogen-agentchat`, you can uninstall it with the following command:
|
|
248
|
+
|
|
249
|
+
```shell
|
|
250
|
+
pip uninstall autogen-agentchat -y
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
If already installed waldiez you might need to reinstall it after uninstalling `autogen-agentchat`:
|
|
254
|
+
|
|
255
|
+
```shell
|
|
256
|
+
pip install --force --no-cache waldiez
|
|
257
|
+
```
|
|
239
258
|
|
|
240
259
|
## License
|
|
241
260
|
|
|
@@ -10,9 +10,8 @@ To a python script or a jupyter notebook with the corresponding [ag2](https://gi
|
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- Convert .waldiez flows to .py or .ipynb
|
|
14
14
|
- Run a .waldiez flow
|
|
15
|
-
- Include a `logs` folder with the logs of the flow in csv format
|
|
16
15
|
- Provide a custom [IOSStream](https://ag2ai.github.io/ag2/docs/reference/io/base#iostream) to handle input and output.
|
|
17
16
|
|
|
18
17
|
## Installation
|
|
@@ -34,10 +33,10 @@ python -m pip install git+https://github.com/waldiez/waldiez.git
|
|
|
34
33
|
### CLI
|
|
35
34
|
|
|
36
35
|
```bash
|
|
37
|
-
#
|
|
38
|
-
waldiez --
|
|
39
|
-
#
|
|
40
|
-
waldiez /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py] [--force]
|
|
36
|
+
# Convert a Waldiez flow to a python script or a jupyter notebook
|
|
37
|
+
waldiez convert --file /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py|.ipynb]
|
|
38
|
+
# Convert and run the script, optionally force generation if the output file already exists
|
|
39
|
+
waldiez run --file /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py] [--force]
|
|
41
40
|
```
|
|
42
41
|
|
|
43
42
|
### Using docker/podman
|
|
@@ -46,7 +45,7 @@ waldiez /path/to/a/flow.waldiez --output /path/to/an/output/flow[.py] [--force]
|
|
|
46
45
|
CONTAINER_COMMAND=docker # or podman
|
|
47
46
|
# pull the image
|
|
48
47
|
$CONTAINER_COMMAND pull waldiez/waldiez
|
|
49
|
-
#
|
|
48
|
+
# Convert a Waldiez flow to a python script or a jupyter notebook
|
|
50
49
|
$CONTAINER_COMMAND run \
|
|
51
50
|
--rm \
|
|
52
51
|
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
@@ -60,12 +59,16 @@ $CONTAINER_COMMAND run \
|
|
|
60
59
|
-v /path/to/an/output:/output \
|
|
61
60
|
--userns=keep-id \
|
|
62
61
|
--security-opt label=disable \
|
|
63
|
-
waldiez/waldiez --
|
|
62
|
+
waldiez/waldiez convert --file /flow.waldiez --output /output/flow[.py|.ipynb]
|
|
64
63
|
```
|
|
65
64
|
|
|
66
65
|
```shell
|
|
67
|
-
#
|
|
68
|
-
$CONTAINER_COMMAND run
|
|
66
|
+
# Convert and run the script
|
|
67
|
+
$CONTAINER_COMMAND run \
|
|
68
|
+
--rm \
|
|
69
|
+
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
70
|
+
-v /path/to/an/output:/output \
|
|
71
|
+
waldiez/waldiez run --file /flow.waldiez --output /output/output[.py]
|
|
69
72
|
```
|
|
70
73
|
|
|
71
74
|
### As a library
|
|
@@ -164,6 +167,21 @@ with WaldiezIOStream.set_default(io_stream):
|
|
|
164
167
|
- [ag2 (formerly AutoGen)](https://github.com/ag2ai/ag2)
|
|
165
168
|
- [juptytext](https://github.com/mwouts/jupytext)
|
|
166
169
|
- [pydantic](https://github.com/pydantic/pydantic)
|
|
170
|
+
- [typer](https://github.com/fastapi/typer)
|
|
171
|
+
|
|
172
|
+
## Known Conflicts
|
|
173
|
+
|
|
174
|
+
- **autogen-agentchat**: This package conflicts with `ag2`. Ensure that `autogen-agentchat` is uninstalled before installing `waldiez`. If you have already installed `autogen-agentchat`, you can uninstall it with the following command:
|
|
175
|
+
|
|
176
|
+
```shell
|
|
177
|
+
pip uninstall autogen-agentchat -y
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
If already installed waldiez you might need to reinstall it after uninstalling `autogen-agentchat`:
|
|
181
|
+
|
|
182
|
+
```shell
|
|
183
|
+
pip install --force --no-cache waldiez
|
|
184
|
+
```
|
|
167
185
|
|
|
168
186
|
## License
|
|
169
187
|
|
|
@@ -21,9 +21,11 @@ classifiers = [
|
|
|
21
21
|
"Intended Audience :: Science/Research",
|
|
22
22
|
"Intended Audience :: Developers",
|
|
23
23
|
]
|
|
24
|
-
dependencies =
|
|
24
|
+
dependencies =[
|
|
25
|
+
"ag2==0.4.1",
|
|
25
26
|
"jupytext",
|
|
26
|
-
|
|
27
|
+
# together(ag2 extra) 1.2.0 depends on typer<0.13 and >=0.9
|
|
28
|
+
"typer>=0.9,<0.13"
|
|
27
29
|
]
|
|
28
30
|
|
|
29
31
|
[project.urls]
|
|
@@ -41,42 +43,42 @@ exclude = [ "**/example.py" ]
|
|
|
41
43
|
[project.optional-dependencies]
|
|
42
44
|
dev = [
|
|
43
45
|
'autoflake==2.3.1',
|
|
44
|
-
'bandit==1.
|
|
46
|
+
'bandit==1.8.0',
|
|
45
47
|
'black[jupyter]==24.10.0',
|
|
46
48
|
'flake8==7.1.1',
|
|
47
49
|
'isort==5.13.2',
|
|
48
50
|
'mypy==1.13.0',
|
|
49
51
|
'pre-commit==4.0.1',
|
|
50
52
|
'pydocstyle==6.3.0',
|
|
51
|
-
'pylint==3.3.
|
|
53
|
+
'pylint==3.3.2',
|
|
52
54
|
'python-dotenv==1.0.1',
|
|
53
|
-
'ruff==0.
|
|
54
|
-
'types-PyYAML==6.0.12',
|
|
55
|
+
'ruff==0.8.1',
|
|
56
|
+
'types-PyYAML==6.0.12.20240917',
|
|
55
57
|
'yamllint==1.35.1',
|
|
56
58
|
]
|
|
57
59
|
ag2_extras =[
|
|
58
|
-
'chromadb==0.5.3',
|
|
59
60
|
'fastembed==0.4.2',
|
|
60
|
-
'pgvector>=0.
|
|
61
|
-
'psycopg[binary]>=3.
|
|
62
|
-
'ag2[
|
|
63
|
-
'ag2[retrievechat
|
|
64
|
-
'ag2[retrievechat-
|
|
65
|
-
'ag2[retrievechat-
|
|
66
|
-
'ag2[
|
|
67
|
-
'ag2[
|
|
68
|
-
'ag2[
|
|
69
|
-
'ag2[
|
|
70
|
-
'ag2[
|
|
71
|
-
'ag2[
|
|
72
|
-
'ag2[
|
|
73
|
-
'ag2[
|
|
74
|
-
'ag2[
|
|
61
|
+
'pgvector>=0.3.6',
|
|
62
|
+
'psycopg[binary]>=3.2.3',
|
|
63
|
+
'ag2[captainagent]==0.4.1',
|
|
64
|
+
'ag2[retrievechat]==0.4.1',
|
|
65
|
+
'ag2[retrievechat-pgvector]==0.4.1',
|
|
66
|
+
'ag2[retrievechat-mongodb]==0.4.1',
|
|
67
|
+
'ag2[retrievechat-qdrant]==0.4.1',
|
|
68
|
+
'ag2[gemini]==0.4.1',
|
|
69
|
+
'ag2[together]==0.4.1',
|
|
70
|
+
'ag2[anthropic]==0.4.1',
|
|
71
|
+
'ag2[lmm]==0.4.1',
|
|
72
|
+
'ag2[mistral]==0.4.1',
|
|
73
|
+
'ag2[groq]==0.4.1',
|
|
74
|
+
'ag2[bedrock]==0.4.1',
|
|
75
|
+
'ag2[websurfer]==0.4.1',
|
|
76
|
+
'ag2[together]==0.4.1',
|
|
75
77
|
'pymongo==4.10.1',
|
|
76
78
|
'qdrant-client==1.12.1',
|
|
77
79
|
]
|
|
78
80
|
test = [
|
|
79
|
-
'pytest==8.3.
|
|
81
|
+
'pytest==8.3.4',
|
|
80
82
|
'pytest-cov==6.0.0',
|
|
81
83
|
'pytest-html==4.1.1',
|
|
82
84
|
'pytest-sugar==1.0.0',
|
|
@@ -89,7 +91,7 @@ docs = [
|
|
|
89
91
|
'mkdocs==1.6.1',
|
|
90
92
|
'mkdocs-jupyter==0.25.1',
|
|
91
93
|
'mkdocs-macros-plugin==1.3.7',
|
|
92
|
-
'mkdocs-material==9.5.
|
|
94
|
+
'mkdocs-material==9.5.47',
|
|
93
95
|
'mkdocs-minify-html-plugin==0.2.3',
|
|
94
96
|
'mkdocstrings[crystal,python]==0.27.0',
|
|
95
97
|
'mkdocstrings-python==1.12.2'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Waldiez package."""
|
|
2
|
+
|
|
3
|
+
from ._version import __version__
|
|
4
|
+
from .conflict_checker import check_conflicts
|
|
5
|
+
from .exporter import WaldiezExporter
|
|
6
|
+
from .models import Waldiez
|
|
7
|
+
from .runner import WaldiezRunner
|
|
8
|
+
|
|
9
|
+
# flag to check if ag2 and autogen-agentchat
|
|
10
|
+
# are installed at the same time
|
|
11
|
+
__WALDIEZ_CHECKED_FOR_CONFLICTS = False
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _check_conflicts_once() -> None:
|
|
15
|
+
"""Check for conflicts once."""
|
|
16
|
+
# pylint: disable=global-statement
|
|
17
|
+
global __WALDIEZ_CHECKED_FOR_CONFLICTS
|
|
18
|
+
if __WALDIEZ_CHECKED_FOR_CONFLICTS is False:
|
|
19
|
+
check_conflicts()
|
|
20
|
+
__WALDIEZ_CHECKED_FOR_CONFLICTS = True
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_check_conflicts_once()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"Waldiez",
|
|
28
|
+
"WaldiezExporter",
|
|
29
|
+
"WaldiezRunner",
|
|
30
|
+
"__version__",
|
|
31
|
+
]
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""Command line interface to convert or run a waldiez file."""
|
|
2
|
+
|
|
3
|
+
# pylint: disable=missing-function-docstring,missing-param-doc,missing-raises-doc
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import TYPE_CHECKING, Optional
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
from typing_extensions import Annotated
|
|
13
|
+
|
|
14
|
+
from . import Waldiez, __version__
|
|
15
|
+
from .exporter import WaldiezExporter
|
|
16
|
+
from .runner import WaldiezRunner
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from autogen import ChatResult # type: ignore[import-untyped]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
app = typer.Typer(
|
|
23
|
+
name="waldiez",
|
|
24
|
+
help="Handle Waldiez flows.",
|
|
25
|
+
context_settings={
|
|
26
|
+
"help_option_names": ["-h", "--help"],
|
|
27
|
+
"allow_extra_args": True,
|
|
28
|
+
},
|
|
29
|
+
add_completion=False,
|
|
30
|
+
no_args_is_help=True,
|
|
31
|
+
invoke_without_command=True,
|
|
32
|
+
add_help_option=True,
|
|
33
|
+
pretty_exceptions_enable=False,
|
|
34
|
+
epilog=("Use `waldiez [COMMAND] --help` for command-specific help. "),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@app.callback()
|
|
39
|
+
def show_version(
|
|
40
|
+
version: bool = typer.Option(
|
|
41
|
+
False,
|
|
42
|
+
"--version",
|
|
43
|
+
"-v",
|
|
44
|
+
help="Show the version of the Waldiez package.",
|
|
45
|
+
),
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Show the version of the Waldiez package and exit."""
|
|
48
|
+
if version:
|
|
49
|
+
typer.echo(f"waldiez version: {__version__}")
|
|
50
|
+
raise typer.Exit()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@app.command()
|
|
54
|
+
def run(
|
|
55
|
+
file: Annotated[
|
|
56
|
+
Path,
|
|
57
|
+
typer.Option(
|
|
58
|
+
...,
|
|
59
|
+
help="Path to the Waldiez flow (*.waldiez) file.",
|
|
60
|
+
exists=True,
|
|
61
|
+
file_okay=True,
|
|
62
|
+
dir_okay=False,
|
|
63
|
+
readable=True,
|
|
64
|
+
resolve_path=True,
|
|
65
|
+
),
|
|
66
|
+
],
|
|
67
|
+
output: Optional[Path] = typer.Option(
|
|
68
|
+
None,
|
|
69
|
+
help=(
|
|
70
|
+
"Path to the output (.py) file. "
|
|
71
|
+
"The output's directory will contain "
|
|
72
|
+
"the generated flow (.py) and any additional generated files."
|
|
73
|
+
),
|
|
74
|
+
dir_okay=False,
|
|
75
|
+
resolve_path=True,
|
|
76
|
+
),
|
|
77
|
+
force: bool = typer.Option(
|
|
78
|
+
False,
|
|
79
|
+
help="Override the output file if it already exists.",
|
|
80
|
+
),
|
|
81
|
+
) -> None:
|
|
82
|
+
"""Run a Waldiez flow."""
|
|
83
|
+
output_path = _get_output_path(output, force)
|
|
84
|
+
with file.open("r", encoding="utf-8") as _file:
|
|
85
|
+
try:
|
|
86
|
+
data = json.load(_file)
|
|
87
|
+
except json.decoder.JSONDecodeError as error:
|
|
88
|
+
typer.echo("Invalid .waldiez file. Not a valid json?")
|
|
89
|
+
raise typer.Exit(code=1) from error
|
|
90
|
+
waldiez = Waldiez.from_dict(data)
|
|
91
|
+
runner = WaldiezRunner(waldiez)
|
|
92
|
+
results = runner.run(stream=None, output_path=output_path)
|
|
93
|
+
logger = _get_logger()
|
|
94
|
+
if isinstance(results, list):
|
|
95
|
+
logger.info("Results:")
|
|
96
|
+
for result in results:
|
|
97
|
+
_log_result(result, logger)
|
|
98
|
+
sep = "-" * 80
|
|
99
|
+
print(f"\n{sep}\n")
|
|
100
|
+
else:
|
|
101
|
+
_log_result(results, logger)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@app.command()
|
|
105
|
+
def convert(
|
|
106
|
+
file: Annotated[
|
|
107
|
+
Path,
|
|
108
|
+
typer.Option(
|
|
109
|
+
...,
|
|
110
|
+
help="Path to the Waldiez flow (*.waldiez) file.",
|
|
111
|
+
exists=True,
|
|
112
|
+
file_okay=True,
|
|
113
|
+
dir_okay=False,
|
|
114
|
+
readable=True,
|
|
115
|
+
resolve_path=True,
|
|
116
|
+
),
|
|
117
|
+
],
|
|
118
|
+
output: Annotated[
|
|
119
|
+
Path,
|
|
120
|
+
typer.Option(
|
|
121
|
+
...,
|
|
122
|
+
help=(
|
|
123
|
+
"Path to the output file. "
|
|
124
|
+
"The file extension determines the output format: "
|
|
125
|
+
"`.py` for Python script, `.ipynb` for Jupyter notebook."
|
|
126
|
+
),
|
|
127
|
+
file_okay=True,
|
|
128
|
+
dir_okay=False,
|
|
129
|
+
resolve_path=True,
|
|
130
|
+
),
|
|
131
|
+
],
|
|
132
|
+
force: bool = typer.Option(
|
|
133
|
+
False,
|
|
134
|
+
help="Override the output file if it already exists.",
|
|
135
|
+
),
|
|
136
|
+
) -> None:
|
|
137
|
+
"""Convert a Waldiez flow to a Python script or a Jupyter notebook."""
|
|
138
|
+
_get_output_path(output, force)
|
|
139
|
+
with file.open("r", encoding="utf-8") as _file:
|
|
140
|
+
try:
|
|
141
|
+
data = json.load(_file)
|
|
142
|
+
except json.decoder.JSONDecodeError as error:
|
|
143
|
+
typer.echo("Invalid .waldiez file. Not a valid json?")
|
|
144
|
+
raise typer.Exit(code=1) from error
|
|
145
|
+
waldiez = Waldiez.from_dict(data)
|
|
146
|
+
exporter = WaldiezExporter(waldiez)
|
|
147
|
+
exporter.export(output, force=force)
|
|
148
|
+
generated = str(output).replace(os.getcwd(), ".")
|
|
149
|
+
typer.echo(f"Generated: {generated}")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@app.command()
|
|
153
|
+
def check(
|
|
154
|
+
file: Annotated[
|
|
155
|
+
Path,
|
|
156
|
+
typer.Option(
|
|
157
|
+
...,
|
|
158
|
+
help="Path to the Waldiez flow (*.waldiez) file.",
|
|
159
|
+
exists=True,
|
|
160
|
+
file_okay=True,
|
|
161
|
+
dir_okay=False,
|
|
162
|
+
readable=True,
|
|
163
|
+
resolve_path=True,
|
|
164
|
+
),
|
|
165
|
+
],
|
|
166
|
+
) -> None:
|
|
167
|
+
"""Validate a Waldiez flow."""
|
|
168
|
+
with file.open("r", encoding="utf-8") as _file:
|
|
169
|
+
data = json.load(_file)
|
|
170
|
+
Waldiez.from_dict(data)
|
|
171
|
+
typer.echo("Waldiez flow is valid.")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _get_output_path(output: Optional[Path], force: bool) -> Optional[Path]:
|
|
175
|
+
if output is not None:
|
|
176
|
+
output = Path(output).resolve()
|
|
177
|
+
if output is not None and not output.parent.exists():
|
|
178
|
+
output.parent.mkdir(parents=True)
|
|
179
|
+
if output is not None and output.exists():
|
|
180
|
+
if force is False:
|
|
181
|
+
typer.echo("Output file already exists.")
|
|
182
|
+
raise typer.Exit(code=1)
|
|
183
|
+
output.unlink()
|
|
184
|
+
return output
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _get_logger(level: int = logging.INFO) -> logging.Logger:
|
|
188
|
+
"""Get the logger for the Waldiez package.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
level : int or str, optional
|
|
193
|
+
The logging level. Default is logging.INFO.
|
|
194
|
+
|
|
195
|
+
Returns
|
|
196
|
+
-------
|
|
197
|
+
logging.Logger
|
|
198
|
+
The logger.
|
|
199
|
+
"""
|
|
200
|
+
# check if we already have setup a config
|
|
201
|
+
|
|
202
|
+
if not logging.getLogger().handlers:
|
|
203
|
+
logging.basicConfig(
|
|
204
|
+
level=level,
|
|
205
|
+
format="%(levelname)s %(message)s",
|
|
206
|
+
stream=sys.stderr,
|
|
207
|
+
force=True,
|
|
208
|
+
)
|
|
209
|
+
logger = logging.getLogger("waldiez::cli")
|
|
210
|
+
current_level = logger.getEffectiveLevel()
|
|
211
|
+
if current_level != level:
|
|
212
|
+
logger.setLevel(level)
|
|
213
|
+
return logger
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _log_result(result: "ChatResult", logger: logging.Logger) -> None:
|
|
217
|
+
"""Log the result of the Waldiez flow."""
|
|
218
|
+
logger.info("Chat History:\n")
|
|
219
|
+
logger.info(result.chat_history)
|
|
220
|
+
logger.info("Summary:\n")
|
|
221
|
+
logger.info(result.summary)
|
|
222
|
+
logger.info("Cost:\n")
|
|
223
|
+
logger.info(result.cost)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
if __name__ == "__main__":
|
|
227
|
+
_get_logger()
|
|
228
|
+
app()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Check for conflicts with 'autogen-agentchat' package."""
|
|
2
|
+
|
|
3
|
+
# pylint: disable=line-too-long
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# fmt: off
|
|
10
|
+
def check_conflicts() -> None: # pragma: no cover
|
|
11
|
+
"""Check for conflicts with 'autogen-agentchat' package."""
|
|
12
|
+
try:
|
|
13
|
+
version("autogen-agentchat")
|
|
14
|
+
print(
|
|
15
|
+
"Conflict detected: 'autogen-agentchat' is installed, which conflicts with 'ag2'.\n"
|
|
16
|
+
"Please uninstall 'autogen-agentchat': pip uninstall -y autogen-agentchat \n"
|
|
17
|
+
"And install 'ag2' (or 'waldiez') again: pip install --force ag2"
|
|
18
|
+
)
|
|
19
|
+
sys.exit(1)
|
|
20
|
+
except PackageNotFoundError:
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
# fmt: on
|
|
@@ -69,6 +69,32 @@ def get_agent_skill_registration(
|
|
|
69
69
|
return content
|
|
70
70
|
|
|
71
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") 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
|
+
|
|
72
98
|
def export_skills(
|
|
73
99
|
skills: List[WaldiezSkill],
|
|
74
100
|
skill_names: Dict[str, str],
|
|
@@ -116,12 +142,21 @@ def export_skills(
|
|
|
116
142
|
skill_secrets: Set[Tuple[str, str]] = set()
|
|
117
143
|
for skill in skills:
|
|
118
144
|
skill_name = skill_names[skill.id]
|
|
119
|
-
skill_imports.add(f"from {skill_name} import {skill_name}")
|
|
120
145
|
skill_secrets.update(skill.secrets.items())
|
|
121
146
|
if not output_dir:
|
|
147
|
+
skill_imports.add(f"from {skill_name} import {skill_name}")
|
|
122
148
|
continue
|
|
123
149
|
if not isinstance(output_dir, Path):
|
|
124
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)
|
|
125
160
|
skill_file = output_dir / f"{skill_name}.py"
|
|
126
161
|
with skill_file.open("w", encoding="utf-8") as f:
|
|
127
162
|
f.write(skill.content)
|
|
@@ -169,8 +169,12 @@ class WaldiezRunner:
|
|
|
169
169
|
print_function(
|
|
170
170
|
f"Installing requirements: {', '.join(extra_requirements)}"
|
|
171
171
|
)
|
|
172
|
+
pip_install = [sys.executable, "-m", "pip", "install"]
|
|
173
|
+
if not in_virtualenv():
|
|
174
|
+
pip_install.append("--user")
|
|
175
|
+
pip_install.extend(extra_requirements)
|
|
172
176
|
with subprocess.Popen(
|
|
173
|
-
|
|
177
|
+
pip_install,
|
|
174
178
|
stdout=subprocess.PIPE,
|
|
175
179
|
stderr=subprocess.PIPE,
|
|
176
180
|
) as proc:
|
|
@@ -341,3 +345,16 @@ class WaldiezRunner:
|
|
|
341
345
|
self._running = False
|
|
342
346
|
self._stream.reset(token)
|
|
343
347
|
del token
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def in_virtualenv() -> bool:
|
|
351
|
+
"""Check if we are inside a virtualenv.
|
|
352
|
+
|
|
353
|
+
Returns
|
|
354
|
+
-------
|
|
355
|
+
bool
|
|
356
|
+
True if inside a virtualenv, False otherwise.
|
|
357
|
+
"""
|
|
358
|
+
return hasattr(sys, "real_prefix") or (
|
|
359
|
+
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
|
|
360
|
+
)
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""Waldiez package."""
|
|
2
|
-
|
|
3
|
-
from ._version import __version__
|
|
4
|
-
from .exporter import WaldiezExporter
|
|
5
|
-
from .models import Waldiez
|
|
6
|
-
from .runner import WaldiezRunner
|
|
7
|
-
|
|
8
|
-
__all__ = [
|
|
9
|
-
"Waldiez",
|
|
10
|
-
"WaldiezExporter",
|
|
11
|
-
"WaldiezRunner",
|
|
12
|
-
"__version__",
|
|
13
|
-
]
|
waldiez-0.1.10/waldiez/cli.py
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
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 TYPE_CHECKING, Any, Dict, Optional
|
|
10
|
-
|
|
11
|
-
from . import Waldiez, __version__
|
|
12
|
-
from .exporter import WaldiezExporter
|
|
13
|
-
from .runner import WaldiezRunner
|
|
14
|
-
|
|
15
|
-
if TYPE_CHECKING:
|
|
16
|
-
from autogen import ChatResult # type: ignore[import-untyped]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def get_parser() -> argparse.ArgumentParser:
|
|
20
|
-
"""Get the argument parser for the Waldiez package.
|
|
21
|
-
|
|
22
|
-
Returns
|
|
23
|
-
-------
|
|
24
|
-
argparse.ArgumentParser
|
|
25
|
-
The argument parser.
|
|
26
|
-
"""
|
|
27
|
-
parser = argparse.ArgumentParser(
|
|
28
|
-
description="Run or export a Waldiez flow.",
|
|
29
|
-
prog="waldiez",
|
|
30
|
-
)
|
|
31
|
-
parser.add_argument(
|
|
32
|
-
"file",
|
|
33
|
-
type=str,
|
|
34
|
-
help="Path to the Waldiez flow (*.waldiez) file.",
|
|
35
|
-
)
|
|
36
|
-
parser.add_argument(
|
|
37
|
-
"-e",
|
|
38
|
-
"--export",
|
|
39
|
-
action="store_true",
|
|
40
|
-
help=(
|
|
41
|
-
"Export the Waldiez flow to a Python script or a jupyter notebook."
|
|
42
|
-
),
|
|
43
|
-
)
|
|
44
|
-
parser.add_argument(
|
|
45
|
-
"-o",
|
|
46
|
-
"--output",
|
|
47
|
-
type=str,
|
|
48
|
-
help=(
|
|
49
|
-
"Path to the output file. "
|
|
50
|
-
"If exporting, the file extension determines the output format. "
|
|
51
|
-
"If running, the output's directory will contain "
|
|
52
|
-
"the generated flow (.py) and any additional generated files."
|
|
53
|
-
),
|
|
54
|
-
)
|
|
55
|
-
parser.add_argument(
|
|
56
|
-
"-f",
|
|
57
|
-
"--force",
|
|
58
|
-
action="store_true",
|
|
59
|
-
help=("Override the output file if it already exists. "),
|
|
60
|
-
)
|
|
61
|
-
parser.add_argument(
|
|
62
|
-
"-v",
|
|
63
|
-
"--version",
|
|
64
|
-
action="version",
|
|
65
|
-
version=f"waldiez version: {__version__}",
|
|
66
|
-
)
|
|
67
|
-
return parser
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _log_result(result: "ChatResult") -> None:
|
|
71
|
-
"""Log the result of the Waldiez flow."""
|
|
72
|
-
logger = logging.getLogger("waldiez::cli")
|
|
73
|
-
logger.info("Chat History:\n")
|
|
74
|
-
logger.info(result.chat_history)
|
|
75
|
-
logger.info("Summary:\n")
|
|
76
|
-
logger.info(result.summary)
|
|
77
|
-
logger.info("Cost:\n")
|
|
78
|
-
logger.info(result.cost)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def _run(data: Dict[str, Any], output_path: Optional[str]) -> None:
|
|
82
|
-
"""Run the Waldiez flow."""
|
|
83
|
-
waldiez = Waldiez.from_dict(data)
|
|
84
|
-
runner = WaldiezRunner(waldiez)
|
|
85
|
-
results = runner.run(stream=None, output_path=output_path)
|
|
86
|
-
if isinstance(results, list):
|
|
87
|
-
for result in results:
|
|
88
|
-
_log_result(result)
|
|
89
|
-
sep = "-" * 80
|
|
90
|
-
print(f"\n{sep}\n")
|
|
91
|
-
else:
|
|
92
|
-
_log_result(results)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def main() -> None:
|
|
96
|
-
"""Parse the command line arguments and run the Waldiez flow."""
|
|
97
|
-
parser = get_parser()
|
|
98
|
-
if len(sys.argv) == 1:
|
|
99
|
-
parser.print_help()
|
|
100
|
-
sys.exit(0)
|
|
101
|
-
args = parser.parse_args()
|
|
102
|
-
logger = _get_logger()
|
|
103
|
-
waldiez_file: str = args.file
|
|
104
|
-
if not os.path.exists(waldiez_file):
|
|
105
|
-
logger.error("File not found: %s", waldiez_file)
|
|
106
|
-
sys.exit(1)
|
|
107
|
-
if not waldiez_file.endswith((".json", ".waldiez")):
|
|
108
|
-
logger.error("Only .json or .waldiez files are supported.")
|
|
109
|
-
sys.exit(1)
|
|
110
|
-
with open(waldiez_file, "r", encoding="utf-8") as file:
|
|
111
|
-
try:
|
|
112
|
-
data = json.load(file)
|
|
113
|
-
except json.decoder.JSONDecodeError:
|
|
114
|
-
logger.error("Invalid .waldiez file: %s. Not a valid json?", file)
|
|
115
|
-
return
|
|
116
|
-
if args.export is True:
|
|
117
|
-
if args.output is None:
|
|
118
|
-
logger.error("Please provide an output file.")
|
|
119
|
-
sys.exit(1)
|
|
120
|
-
if not args.output.endswith((".py", ".ipynb", ".json", ".waldiez")):
|
|
121
|
-
logger.error(
|
|
122
|
-
"Only Python scripts, Jupyter notebooks "
|
|
123
|
-
"and JSON/Waldiez files are supported."
|
|
124
|
-
)
|
|
125
|
-
sys.exit(1)
|
|
126
|
-
output_file = Path(args.output).resolve()
|
|
127
|
-
waldiez = Waldiez.from_dict(data)
|
|
128
|
-
exporter = WaldiezExporter(waldiez)
|
|
129
|
-
exporter.export(output_file, force=args.force)
|
|
130
|
-
generated = str(output_file).replace(os.getcwd(), ".")
|
|
131
|
-
logger.info("Generated: %s", generated)
|
|
132
|
-
else:
|
|
133
|
-
_run(data, args.output)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def _get_logger(level: int = logging.INFO) -> logging.Logger:
|
|
137
|
-
"""Get the logger for the Waldiez package.
|
|
138
|
-
|
|
139
|
-
Parameters
|
|
140
|
-
----------
|
|
141
|
-
level : int or str, optional
|
|
142
|
-
The logging level. Default is logging.INFO.
|
|
143
|
-
|
|
144
|
-
Returns
|
|
145
|
-
-------
|
|
146
|
-
logging.Logger
|
|
147
|
-
The logger.
|
|
148
|
-
"""
|
|
149
|
-
# check if we already have setup a config
|
|
150
|
-
|
|
151
|
-
if not logging.getLogger().handlers:
|
|
152
|
-
logging.basicConfig(
|
|
153
|
-
level=level,
|
|
154
|
-
format="%(levelname)s %(message)s",
|
|
155
|
-
stream=sys.stderr,
|
|
156
|
-
force=True,
|
|
157
|
-
)
|
|
158
|
-
logger = logging.getLogger("waldiez::cli")
|
|
159
|
-
current_level = logger.getEffectiveLevel()
|
|
160
|
-
if current_level != level:
|
|
161
|
-
logger.setLevel(level)
|
|
162
|
-
return logger
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if __name__ == "__main__":
|
|
166
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|