waldiez 0.1.16__tar.gz → 0.1.18__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.16 → waldiez-0.1.18}/PKG-INFO +21 -86
- {waldiez-0.1.16 → waldiez-0.1.18}/README.md +128 -195
- {waldiez-0.1.16 → waldiez-0.1.18}/pyproject.toml +18 -17
- waldiez-0.1.18/waldiez/__init__.py +74 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/_version.py +1 -1
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/cli.py +1 -1
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/flow/def_main.py +1 -6
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/flow/flow.py +2 -3
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/flow/flow.py +15 -1
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/runner.py +26 -55
- waldiez-0.1.16/waldiez/__init__.py +0 -31
- waldiez-0.1.16/waldiez/io/__init__.py +0 -142
- {waldiez-0.1.16 → waldiez-0.1.18}/.gitignore +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/LICENSE +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/__main__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/conflict_checker.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporter.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/agent.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/agent_skills.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/code_execution.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/group_manager.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/llm_config.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/chroma_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/mongo_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/pgvector_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/qdrant_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/rag_user.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/rag_user/vector_db.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/teachability.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/agents/termination_message.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/chats/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/chats/chats.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/chats/helpers.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/chats/nested.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/flow/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/models/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/skills/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/comments.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/importing.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/logging_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/method_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/naming.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/object_string.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/exporting/utils/path_check.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/agent.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/agent_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/code_execution.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/linked_skill.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/nested_chat.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/teachability.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agent/termination_message.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/agents.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/assistant/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/assistant/assistant.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/assistant/assistant_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/group_manager/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/group_manager/group_manager.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/group_manager/group_manager_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/group_manager/speakers.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/rag_user/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/rag_user/rag_user.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/rag_user/rag_user_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/rag_user/retrieve_config.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/rag_user/vector_db_config.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/user_proxy/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/user_proxy/user_proxy.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/agents/user_proxy/user_proxy_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/chat/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/chat/chat.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/chat/chat_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/chat/chat_message.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/chat/chat_nested.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/chat/chat_summary.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/common/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/common/base.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/common/method_utils.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/flow/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/flow/flow_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/model/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/model/model.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/model/model_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/skill/__init__.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/skill/skill.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/skill/skill_data.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/models/waldiez.py +0 -0
- {waldiez-0.1.16 → waldiez-0.1.18}/waldiez/py.typed +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: waldiez
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.18
|
|
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
|
|
7
7
|
Author-email: Panagiotis Kasnesis <pkasnesis@thingenious.io>, Lazaros Toumanidis <laztoum@protonmail.com>, Stella Ioannidou <stella@humancentered.gr>
|
|
8
|
+
License-File: LICENSE
|
|
8
9
|
Classifier: Development Status :: 3 - Alpha
|
|
9
10
|
Classifier: Intended Audience :: Developers
|
|
10
11
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -17,25 +18,26 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
19
|
Requires-Python: <3.13,>=3.10
|
|
19
20
|
Requires-Dist: jupytext
|
|
20
|
-
Requires-Dist: pyautogen==0.5.
|
|
21
|
+
Requires-Dist: pyautogen==0.5.3
|
|
21
22
|
Requires-Dist: pydantic>=2.0
|
|
22
23
|
Requires-Dist: typer<0.13,>=0.9
|
|
23
24
|
Provides-Extra: ag2-extras
|
|
24
25
|
Requires-Dist: pgvector>=0.3.6; extra == 'ag2-extras'
|
|
25
26
|
Requires-Dist: psycopg[binary]>=3.2.3; extra == 'ag2-extras'
|
|
26
|
-
Requires-Dist: pyautogen[anthropic]==0.5.
|
|
27
|
-
Requires-Dist: pyautogen[bedrock]==0.5.
|
|
28
|
-
Requires-Dist: pyautogen[captainagent]==0.5.
|
|
29
|
-
Requires-Dist: pyautogen[gemini]==0.5.
|
|
30
|
-
Requires-Dist: pyautogen[groq]==0.5.
|
|
31
|
-
Requires-Dist: pyautogen[lmm]==0.5.
|
|
32
|
-
Requires-Dist: pyautogen[mistral]==0.5.
|
|
33
|
-
Requires-Dist: pyautogen[
|
|
34
|
-
Requires-Dist: pyautogen[retrievechat-
|
|
35
|
-
Requires-Dist: pyautogen[retrievechat-
|
|
36
|
-
Requires-Dist: pyautogen[retrievechat]==0.5.
|
|
37
|
-
Requires-Dist: pyautogen[
|
|
38
|
-
Requires-Dist: pyautogen[
|
|
27
|
+
Requires-Dist: pyautogen[anthropic]==0.5.3; extra == 'ag2-extras'
|
|
28
|
+
Requires-Dist: pyautogen[bedrock]==0.5.3; extra == 'ag2-extras'
|
|
29
|
+
Requires-Dist: pyautogen[captainagent]==0.5.3; extra == 'ag2-extras'
|
|
30
|
+
Requires-Dist: pyautogen[gemini]==0.5.3; extra == 'ag2-extras'
|
|
31
|
+
Requires-Dist: pyautogen[groq]==0.5.3; extra == 'ag2-extras'
|
|
32
|
+
Requires-Dist: pyautogen[lmm]==0.5.3; extra == 'ag2-extras'
|
|
33
|
+
Requires-Dist: pyautogen[mistral]==0.5.3; extra == 'ag2-extras'
|
|
34
|
+
Requires-Dist: pyautogen[neo4j]==0.5.3; extra == 'ag2-extras'
|
|
35
|
+
Requires-Dist: pyautogen[retrievechat-mongodb]==0.5.3; extra == 'ag2-extras'
|
|
36
|
+
Requires-Dist: pyautogen[retrievechat-pgvector]==0.5.3; extra == 'ag2-extras'
|
|
37
|
+
Requires-Dist: pyautogen[retrievechat-qdrant]==0.5.3; (python_version < '3.13') and extra == 'ag2-extras'
|
|
38
|
+
Requires-Dist: pyautogen[retrievechat]==0.5.3; extra == 'ag2-extras'
|
|
39
|
+
Requires-Dist: pyautogen[together]==0.5.3; extra == 'ag2-extras'
|
|
40
|
+
Requires-Dist: pyautogen[websurfer]==0.5.3; extra == 'ag2-extras'
|
|
39
41
|
Requires-Dist: pymongo==4.10.1; extra == 'ag2-extras'
|
|
40
42
|
Requires-Dist: qdrant-client[fastembed]; (python_version >= '3.13') and extra == 'ag2-extras'
|
|
41
43
|
Provides-Extra: dev
|
|
@@ -49,7 +51,7 @@ Requires-Dist: pre-commit==4.0.1; extra == 'dev'
|
|
|
49
51
|
Requires-Dist: pydocstyle==6.3.0; extra == 'dev'
|
|
50
52
|
Requires-Dist: pylint==3.3.2; extra == 'dev'
|
|
51
53
|
Requires-Dist: python-dotenv==1.0.1; extra == 'dev'
|
|
52
|
-
Requires-Dist: ruff==0.8.
|
|
54
|
+
Requires-Dist: ruff==0.8.3; extra == 'dev'
|
|
53
55
|
Requires-Dist: toml; (python_version <= '3.10') and extra == 'dev'
|
|
54
56
|
Requires-Dist: types-pyyaml==6.0.12.20240917; extra == 'dev'
|
|
55
57
|
Requires-Dist: types-toml==0.10.8.20240310; extra == 'dev'
|
|
@@ -59,7 +61,7 @@ Requires-Dist: mdx-include==1.4.2; extra == 'docs'
|
|
|
59
61
|
Requires-Dist: mdx-truly-sane-lists==1.3; extra == 'docs'
|
|
60
62
|
Requires-Dist: mkdocs-jupyter==0.25.1; extra == 'docs'
|
|
61
63
|
Requires-Dist: mkdocs-macros-plugin==1.3.7; extra == 'docs'
|
|
62
|
-
Requires-Dist: mkdocs-material==9.5.
|
|
64
|
+
Requires-Dist: mkdocs-material==9.5.49; extra == 'docs'
|
|
63
65
|
Requires-Dist: mkdocs-minify-html-plugin==0.2.3; extra == 'docs'
|
|
64
66
|
Requires-Dist: mkdocs==1.6.1; extra == 'docs'
|
|
65
67
|
Requires-Dist: mkdocstrings-python==1.12.2; extra == 'docs'
|
|
@@ -87,7 +89,7 @@ To a python script or a jupyter notebook with the corresponding [ag2](https://gi
|
|
|
87
89
|
|
|
88
90
|
- Convert .waldiez flows to .py or .ipynb
|
|
89
91
|
- Run a .waldiez flow
|
|
90
|
-
-
|
|
92
|
+
- Store the runtime logs of a flow to csv for further analysis
|
|
91
93
|
|
|
92
94
|
## Installation
|
|
93
95
|
|
|
@@ -177,73 +179,6 @@ runner = WaldiezRunner.load(flow_path)
|
|
|
177
179
|
runner.run(output_path=output_path)
|
|
178
180
|
```
|
|
179
181
|
|
|
180
|
-
#### Run a flow with a custom IOStream
|
|
181
|
-
|
|
182
|
-
```python
|
|
183
|
-
# Run the flow with a custom IOStream
|
|
184
|
-
# In case the standard 'input' and 'print' functions cannot be used
|
|
185
|
-
import time
|
|
186
|
-
import threading
|
|
187
|
-
|
|
188
|
-
from typing import Any
|
|
189
|
-
|
|
190
|
-
from waldiez import WaldiezRunner
|
|
191
|
-
from waldiez.io import WaldiezIOStream
|
|
192
|
-
|
|
193
|
-
flow_path = "/path/to/a/flow.waldiez"
|
|
194
|
-
output_path = "/path/to/an/output.py"
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def custom_print_function(*args: Any, sep: str = " ", **kwargs: Any) -> None:
|
|
198
|
-
"""Custom print function."""
|
|
199
|
-
print(*args, sep=sep, **kwargs)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
# Custom input handler
|
|
203
|
-
class InputProcessorWrapper:
|
|
204
|
-
"""Wrapper input processor.
|
|
205
|
-
|
|
206
|
-
To manage the interaction between the custom input processor and IOStream.
|
|
207
|
-
"""
|
|
208
|
-
|
|
209
|
-
def __init__(self):
|
|
210
|
-
self.stream = None # Placeholder for the WaldiezIOStream instance
|
|
211
|
-
self.lock = threading.Lock() # Ensure thread-safe operations
|
|
212
|
-
|
|
213
|
-
def custom_input_processor(self, prompt: str) -> None:
|
|
214
|
-
"""Simulate external input and send it back to the IOStream."""
|
|
215
|
-
def external_input_simulation():
|
|
216
|
-
with self.lock: # Ensure thread-safe access
|
|
217
|
-
time.sleep(2) # Simulate delay for network input
|
|
218
|
-
if self.stream:
|
|
219
|
-
self.stream.set_input("Simulated external input")
|
|
220
|
-
else:
|
|
221
|
-
raise RuntimeError("Stream reference not set!")
|
|
222
|
-
|
|
223
|
-
threading.Thread(target=external_input_simulation, daemon=True).start()
|
|
224
|
-
|
|
225
|
-
def set_stream(self, stream: "WaldiezIOStream"):
|
|
226
|
-
"""Set the WaldiezIOStream instance."""
|
|
227
|
-
with self.lock: # Ensure thread-safe setting of the stream
|
|
228
|
-
self.stream = stream
|
|
229
|
-
|
|
230
|
-
processor_wrapper = InputProcessorWrapper()
|
|
231
|
-
|
|
232
|
-
stream = WaldiezIOStream(
|
|
233
|
-
input_timeout=30,
|
|
234
|
-
print_function=
|
|
235
|
-
on_prompt_input=processor_wrapper.custom_input_processor,
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
# Link the processor wrapper to the WaldiezIOStream instance
|
|
239
|
-
processor_wrapper.set_stream(custom_stream)
|
|
240
|
-
|
|
241
|
-
with WaldiezIOStream.set_default(io_stream):
|
|
242
|
-
runner = WaldiezRunner.load(flow_path)
|
|
243
|
-
runner.run(stream=io_stream, output_path=output_path)
|
|
244
|
-
|
|
245
|
-
```
|
|
246
|
-
|
|
247
182
|
### Tools
|
|
248
183
|
|
|
249
184
|
- [ag2 (formerly AutoGen)](https://github.com/ag2ai/ag2)
|
|
@@ -1,195 +1,128 @@
|
|
|
1
|
-
# Waldiez
|
|
2
|
-
|
|
3
|
-
 [](https://coveralls.io/github/waldiez/waldiez) [](https://badge.fury.io/py/waldiez)
|
|
4
|
-
|
|
5
|
-
Translate a Waldiez flow:
|
|
6
|
-
|
|
7
|
-

|
|
8
|
-
|
|
9
|
-
To a python script or a jupyter notebook with the corresponding [ag2](https://github.com/ag2ai/ag2/) agents and chats.
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- Convert .waldiez flows to .py or .ipynb
|
|
14
|
-
- Run a .waldiez flow
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
## Installation
|
|
18
|
-
|
|
19
|
-
On PyPI:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
python -m pip install waldiez
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
From the repository:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
python -m pip install git+https://github.com/waldiez/waldiez.git
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Usage
|
|
32
|
-
|
|
33
|
-
### CLI
|
|
34
|
-
|
|
35
|
-
```bash
|
|
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]
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Using docker/podman
|
|
43
|
-
|
|
44
|
-
```shell
|
|
45
|
-
CONTAINER_COMMAND=docker # or podman
|
|
46
|
-
# pull the image
|
|
47
|
-
$CONTAINER_COMMAND pull waldiez/waldiez
|
|
48
|
-
# Convert a Waldiez flow to a python script or a jupyter notebook
|
|
49
|
-
$CONTAINER_COMMAND run \
|
|
50
|
-
--rm \
|
|
51
|
-
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
52
|
-
-v /path/to/an/output:/output \
|
|
53
|
-
waldiez/waldiez convert --file /flow.waldiez --output /output/flow[.py|.ipynb] [--force]
|
|
54
|
-
|
|
55
|
-
# with selinux and/or podman, you might get permission (or file not found) errors, so you can try:
|
|
56
|
-
$CONTAINER_COMMAND run \
|
|
57
|
-
--rm \
|
|
58
|
-
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
59
|
-
-v /path/to/an/output:/output \
|
|
60
|
-
--userns=keep-id \
|
|
61
|
-
--security-opt label=disable \
|
|
62
|
-
waldiez/waldiez convert --file /flow.waldiez --output /output/flow[.py|.ipynb] [--force]
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
```shell
|
|
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]
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### UI
|
|
75
|
-
|
|
76
|
-
For creating-only (no exporting or running) waldiez flows, you can use the playground at <https://waldiez.github.io>.
|
|
77
|
-
The repo for the js library is [here](https://github.com/waldiez/react).
|
|
78
|
-
We are currently working on waldiez-studio to provide a visual interface for creating and running Waldiez flows (you can find more [here](https://github.com/waldiez/studio)).
|
|
79
|
-
Until then, you can use our [Jupyter](https://github.com/waldiez/jupyter) or the [VSCode](https://github.com/waldiez/vscode) extension to create and run Waldiez flows.
|
|
80
|
-
|
|
81
|
-
### As a library
|
|
82
|
-
|
|
83
|
-
#### Export a flow
|
|
84
|
-
|
|
85
|
-
```python
|
|
86
|
-
# Export a Waldiez flow to a python script or a jupyter notebook
|
|
87
|
-
from waldiez import WaldiezExporter
|
|
88
|
-
flow_path = "/path/to/a/flow.waldiez"
|
|
89
|
-
output_path = "/path/to/an/output.py" # or .ipynb
|
|
90
|
-
exporter = WaldiezExporter.load(flow_path)
|
|
91
|
-
exporter.export(output_path)
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
#### Run a flow
|
|
95
|
-
|
|
96
|
-
```python
|
|
97
|
-
# Run a flow
|
|
98
|
-
from waldiez import WaldiezRunner
|
|
99
|
-
flow_path = "/path/to/a/flow.waldiez"
|
|
100
|
-
output_path = "/path/to/an/output.py"
|
|
101
|
-
runner = WaldiezRunner.load(flow_path)
|
|
102
|
-
runner.run(output_path=output_path)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"""Wrapper input processor.
|
|
130
|
-
|
|
131
|
-
To manage the interaction between the custom input processor and IOStream.
|
|
132
|
-
"""
|
|
133
|
-
|
|
134
|
-
def __init__(self):
|
|
135
|
-
self.stream = None # Placeholder for the WaldiezIOStream instance
|
|
136
|
-
self.lock = threading.Lock() # Ensure thread-safe operations
|
|
137
|
-
|
|
138
|
-
def custom_input_processor(self, prompt: str) -> None:
|
|
139
|
-
"""Simulate external input and send it back to the IOStream."""
|
|
140
|
-
def external_input_simulation():
|
|
141
|
-
with self.lock: # Ensure thread-safe access
|
|
142
|
-
time.sleep(2) # Simulate delay for network input
|
|
143
|
-
if self.stream:
|
|
144
|
-
self.stream.set_input("Simulated external input")
|
|
145
|
-
else:
|
|
146
|
-
raise RuntimeError("Stream reference not set!")
|
|
147
|
-
|
|
148
|
-
threading.Thread(target=external_input_simulation, daemon=True).start()
|
|
149
|
-
|
|
150
|
-
def set_stream(self, stream: "WaldiezIOStream"):
|
|
151
|
-
"""Set the WaldiezIOStream instance."""
|
|
152
|
-
with self.lock: # Ensure thread-safe setting of the stream
|
|
153
|
-
self.stream = stream
|
|
154
|
-
|
|
155
|
-
processor_wrapper = InputProcessorWrapper()
|
|
156
|
-
|
|
157
|
-
stream = WaldiezIOStream(
|
|
158
|
-
input_timeout=30,
|
|
159
|
-
print_function=
|
|
160
|
-
on_prompt_input=processor_wrapper.custom_input_processor,
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
# Link the processor wrapper to the WaldiezIOStream instance
|
|
164
|
-
processor_wrapper.set_stream(custom_stream)
|
|
165
|
-
|
|
166
|
-
with WaldiezIOStream.set_default(io_stream):
|
|
167
|
-
runner = WaldiezRunner.load(flow_path)
|
|
168
|
-
runner.run(stream=io_stream, output_path=output_path)
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Tools
|
|
173
|
-
|
|
174
|
-
- [ag2 (formerly AutoGen)](https://github.com/ag2ai/ag2)
|
|
175
|
-
- [juptytext](https://github.com/mwouts/jupytext)
|
|
176
|
-
- [pydantic](https://github.com/pydantic/pydantic)
|
|
177
|
-
- [typer](https://github.com/fastapi/typer)
|
|
178
|
-
|
|
179
|
-
## Known Conflicts
|
|
180
|
-
|
|
181
|
-
- **autogen-agentchat**: This package conflicts with `ag2` / `pyautogen`. Ensure that `autogen-agentchat` is uninstalled before installing `waldiez`. If you have already installed `autogen-agentchat`, you can uninstall it with the following command:
|
|
182
|
-
|
|
183
|
-
```shell
|
|
184
|
-
pip uninstall autogen-agentchat -y
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
If already installed waldiez you might need to reinstall it after uninstalling `autogen-agentchat`:
|
|
188
|
-
|
|
189
|
-
```shell
|
|
190
|
-
pip install --force --no-cache waldiez pyautogen
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## License
|
|
194
|
-
|
|
195
|
-
This project is licensed under the MIT License - see the [LICENSE](https://github.com/waldiez/waldiez/blob/main/LICENSE) file for details.
|
|
1
|
+
# Waldiez
|
|
2
|
+
|
|
3
|
+
 [](https://coveralls.io/github/waldiez/waldiez) [](https://badge.fury.io/py/waldiez)
|
|
4
|
+
|
|
5
|
+
Translate a Waldiez flow:
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
To a python script or a jupyter notebook with the corresponding [ag2](https://github.com/ag2ai/ag2/) agents and chats.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Convert .waldiez flows to .py or .ipynb
|
|
14
|
+
- Run a .waldiez flow
|
|
15
|
+
- Store the runtime logs of a flow to csv for further analysis
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
On PyPI:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install waldiez
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
From the repository:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python -m pip install git+https://github.com/waldiez/waldiez.git
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### CLI
|
|
34
|
+
|
|
35
|
+
```bash
|
|
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]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Using docker/podman
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
CONTAINER_COMMAND=docker # or podman
|
|
46
|
+
# pull the image
|
|
47
|
+
$CONTAINER_COMMAND pull waldiez/waldiez
|
|
48
|
+
# Convert a Waldiez flow to a python script or a jupyter notebook
|
|
49
|
+
$CONTAINER_COMMAND run \
|
|
50
|
+
--rm \
|
|
51
|
+
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
52
|
+
-v /path/to/an/output:/output \
|
|
53
|
+
waldiez/waldiez convert --file /flow.waldiez --output /output/flow[.py|.ipynb] [--force]
|
|
54
|
+
|
|
55
|
+
# with selinux and/or podman, you might get permission (or file not found) errors, so you can try:
|
|
56
|
+
$CONTAINER_COMMAND run \
|
|
57
|
+
--rm \
|
|
58
|
+
-v /path/to/a/flow.waldiez:/flow.waldiez \
|
|
59
|
+
-v /path/to/an/output:/output \
|
|
60
|
+
--userns=keep-id \
|
|
61
|
+
--security-opt label=disable \
|
|
62
|
+
waldiez/waldiez convert --file /flow.waldiez --output /output/flow[.py|.ipynb] [--force]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```shell
|
|
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]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### UI
|
|
75
|
+
|
|
76
|
+
For creating-only (no exporting or running) waldiez flows, you can use the playground at <https://waldiez.github.io>.
|
|
77
|
+
The repo for the js library is [here](https://github.com/waldiez/react).
|
|
78
|
+
We are currently working on waldiez-studio to provide a visual interface for creating and running Waldiez flows (you can find more [here](https://github.com/waldiez/studio)).
|
|
79
|
+
Until then, you can use our [Jupyter](https://github.com/waldiez/jupyter) or the [VSCode](https://github.com/waldiez/vscode) extension to create and run Waldiez flows.
|
|
80
|
+
|
|
81
|
+
### As a library
|
|
82
|
+
|
|
83
|
+
#### Export a flow
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
# Export a Waldiez flow to a python script or a jupyter notebook
|
|
87
|
+
from waldiez import WaldiezExporter
|
|
88
|
+
flow_path = "/path/to/a/flow.waldiez"
|
|
89
|
+
output_path = "/path/to/an/output.py" # or .ipynb
|
|
90
|
+
exporter = WaldiezExporter.load(flow_path)
|
|
91
|
+
exporter.export(output_path)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Run a flow
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
# Run a flow
|
|
98
|
+
from waldiez import WaldiezRunner
|
|
99
|
+
flow_path = "/path/to/a/flow.waldiez"
|
|
100
|
+
output_path = "/path/to/an/output.py"
|
|
101
|
+
runner = WaldiezRunner.load(flow_path)
|
|
102
|
+
runner.run(output_path=output_path)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Tools
|
|
106
|
+
|
|
107
|
+
- [ag2 (formerly AutoGen)](https://github.com/ag2ai/ag2)
|
|
108
|
+
- [juptytext](https://github.com/mwouts/jupytext)
|
|
109
|
+
- [pydantic](https://github.com/pydantic/pydantic)
|
|
110
|
+
- [typer](https://github.com/fastapi/typer)
|
|
111
|
+
|
|
112
|
+
## Known Conflicts
|
|
113
|
+
|
|
114
|
+
- **autogen-agentchat**: This package conflicts with `ag2` / `pyautogen`. Ensure that `autogen-agentchat` is uninstalled before installing `waldiez`. If you have already installed `autogen-agentchat`, you can uninstall it with the following command:
|
|
115
|
+
|
|
116
|
+
```shell
|
|
117
|
+
pip uninstall autogen-agentchat -y
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
If already installed waldiez you might need to reinstall it after uninstalling `autogen-agentchat`:
|
|
121
|
+
|
|
122
|
+
```shell
|
|
123
|
+
pip install --force --no-cache waldiez pyautogen
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/waldiez/waldiez/blob/main/LICENSE) file for details.
|
|
@@ -22,7 +22,7 @@ classifiers = [
|
|
|
22
22
|
"Intended Audience :: Developers",
|
|
23
23
|
]
|
|
24
24
|
dependencies =[
|
|
25
|
-
"pyautogen==0.5.
|
|
25
|
+
"pyautogen==0.5.3",
|
|
26
26
|
"jupytext",
|
|
27
27
|
"pydantic>=2.0",
|
|
28
28
|
# together(ag2 extra) 1.2.0 depends on typer<0.13 and >=0.9
|
|
@@ -53,7 +53,7 @@ dev = [
|
|
|
53
53
|
'pydocstyle==6.3.0',
|
|
54
54
|
'pylint==3.3.2',
|
|
55
55
|
'python-dotenv==1.0.1',
|
|
56
|
-
'ruff==0.8.
|
|
56
|
+
'ruff==0.8.3',
|
|
57
57
|
'types-PyYAML==6.0.12.20240917',
|
|
58
58
|
'yamllint==1.35.1',
|
|
59
59
|
'toml; python_version <= "3.10"',
|
|
@@ -82,21 +82,22 @@ dev = [
|
|
|
82
82
|
ag2_extras =[
|
|
83
83
|
'pgvector>=0.3.6',
|
|
84
84
|
'psycopg[binary]>=3.2.3',
|
|
85
|
-
'pyautogen[
|
|
86
|
-
'pyautogen[
|
|
87
|
-
'pyautogen[
|
|
88
|
-
'pyautogen[
|
|
89
|
-
'pyautogen[
|
|
85
|
+
'pyautogen[anthropic]==0.5.3',
|
|
86
|
+
'pyautogen[bedrock]==0.5.3',
|
|
87
|
+
'pyautogen[captainagent]==0.5.3',
|
|
88
|
+
'pyautogen[gemini]==0.5.3',
|
|
89
|
+
'pyautogen[groq]==0.5.3',
|
|
90
|
+
'pyautogen[lmm]==0.5.3',
|
|
91
|
+
'pyautogen[mistral]==0.5.3',
|
|
92
|
+
'pyautogen[neo4j]==0.5.3',
|
|
93
|
+
'pyautogen[retrievechat-mongodb]==0.5.3',
|
|
94
|
+
'pyautogen[retrievechat-pgvector]==0.5.3',
|
|
95
|
+
'pyautogen[retrievechat-qdrant]==0.5.3; python_version < "3.13"',
|
|
90
96
|
'qdrant-client[fastembed]; python_version >= "3.13"',
|
|
91
|
-
'pyautogen[
|
|
92
|
-
'pyautogen[together]==0.5.
|
|
93
|
-
'pyautogen[
|
|
94
|
-
'pyautogen[
|
|
95
|
-
'pyautogen[mistral]==0.5.0',
|
|
96
|
-
'pyautogen[groq]==0.5.0',
|
|
97
|
-
'pyautogen[bedrock]==0.5.0',
|
|
98
|
-
'pyautogen[websurfer]==0.5.0',
|
|
99
|
-
'pyautogen[together]==0.5.0',
|
|
97
|
+
'pyautogen[retrievechat]==0.5.3',
|
|
98
|
+
'pyautogen[together]==0.5.3',
|
|
99
|
+
'pyautogen[together]==0.5.3',
|
|
100
|
+
'pyautogen[websurfer]==0.5.3',
|
|
100
101
|
'pymongo==4.10.1',
|
|
101
102
|
]
|
|
102
103
|
test = [
|
|
@@ -113,7 +114,7 @@ docs = [
|
|
|
113
114
|
'mkdocs==1.6.1',
|
|
114
115
|
'mkdocs-jupyter==0.25.1',
|
|
115
116
|
'mkdocs-macros-plugin==1.3.7',
|
|
116
|
-
'mkdocs-material==9.5.
|
|
117
|
+
'mkdocs-material==9.5.49',
|
|
117
118
|
'mkdocs-minify-html-plugin==0.2.3',
|
|
118
119
|
'mkdocstrings[crystal,python]==0.27.0',
|
|
119
120
|
'mkdocstrings-python==1.12.2'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Waldiez package."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from ._version import __version__
|
|
6
|
+
from .conflict_checker import check_conflicts
|
|
7
|
+
from .exporter import WaldiezExporter
|
|
8
|
+
from .models import Waldiez
|
|
9
|
+
from .runner import WaldiezRunner
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# pylint: disable=too-few-public-methods
|
|
13
|
+
class FlamlFilter(logging.Filter):
|
|
14
|
+
"""Filter out flaml.automl is not available message."""
|
|
15
|
+
|
|
16
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
|
17
|
+
"""Filter out flaml.automl is not available message.
|
|
18
|
+
|
|
19
|
+
this is just annoying:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
flaml.automl is not available.
|
|
23
|
+
Please install flaml[automl] to enable AutoML functionalities.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
record : logging.LogRecord
|
|
29
|
+
Log record to filter.
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
bool
|
|
34
|
+
Whether to filter out the log record.
|
|
35
|
+
"""
|
|
36
|
+
return "flaml.automl is not available" not in record.getMessage()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# flag to check if ag2 and autogen-agentchat
|
|
40
|
+
# are installed at the same time
|
|
41
|
+
__WALDIEZ_CHECKED_FOR_CONFLICTS = False
|
|
42
|
+
# flag to handle flaml logging
|
|
43
|
+
# suppress the annoying message about flaml.automl
|
|
44
|
+
__WALDIEZ_HANDLED_FLAML_LOGGING = False
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _check_conflicts() -> None:
|
|
48
|
+
"""Check for conflicts once."""
|
|
49
|
+
# pylint: disable=global-statement
|
|
50
|
+
global __WALDIEZ_CHECKED_FOR_CONFLICTS
|
|
51
|
+
if __WALDIEZ_CHECKED_FOR_CONFLICTS is False:
|
|
52
|
+
check_conflicts()
|
|
53
|
+
__WALDIEZ_CHECKED_FOR_CONFLICTS = True
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _handle_flaml_logging() -> None:
|
|
57
|
+
"""Handle flaml logging once."""
|
|
58
|
+
# pylint: disable=global-statement
|
|
59
|
+
global __WALDIEZ_HANDLED_FLAML_LOGGING
|
|
60
|
+
if __WALDIEZ_HANDLED_FLAML_LOGGING is False:
|
|
61
|
+
__WALDIEZ_HANDLED_FLAML_LOGGING = True
|
|
62
|
+
flam_logger = logging.getLogger("flaml")
|
|
63
|
+
flam_logger.addFilter(FlamlFilter())
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
_check_conflicts()
|
|
67
|
+
_handle_flaml_logging()
|
|
68
|
+
|
|
69
|
+
__all__ = [
|
|
70
|
+
"Waldiez",
|
|
71
|
+
"WaldiezExporter",
|
|
72
|
+
"WaldiezRunner",
|
|
73
|
+
"__version__",
|
|
74
|
+
]
|
|
@@ -90,7 +90,7 @@ def run(
|
|
|
90
90
|
raise typer.Exit(code=1) from error
|
|
91
91
|
waldiez = Waldiez.from_dict(data)
|
|
92
92
|
runner = WaldiezRunner(waldiez)
|
|
93
|
-
results = runner.run(
|
|
93
|
+
results = runner.run(output_path=output_path)
|
|
94
94
|
logger = _get_logger()
|
|
95
95
|
if isinstance(results, list):
|
|
96
96
|
logger.info("Results:")
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"""Get the main function (if exporting to python)."""
|
|
2
2
|
|
|
3
|
-
from ..utils import
|
|
4
|
-
get_logging_start_string,
|
|
5
|
-
get_logging_stop_string,
|
|
6
|
-
get_sqlite_to_csv_call_string,
|
|
7
|
-
)
|
|
3
|
+
from ..utils import get_logging_stop_string, get_sqlite_to_csv_call_string
|
|
8
4
|
|
|
9
5
|
|
|
10
6
|
def get_def_main(waldiez_chats: str) -> str:
|
|
@@ -29,7 +25,6 @@ def get_def_main(waldiez_chats: str) -> str:
|
|
|
29
25
|
# type: () -> Union[ChatResult, List[ChatResult]]
|
|
30
26
|
\"\"\"Start chatting.\"\"\"
|
|
31
27
|
"""
|
|
32
|
-
content += get_logging_start_string(1)
|
|
33
28
|
content += f" results = {waldiez_chats}" + "\n"
|
|
34
29
|
content += get_logging_stop_string(1) + "\n"
|
|
35
30
|
content += get_sqlite_to_csv_call_string(1) + "\n"
|
|
@@ -159,8 +159,8 @@ def _combine_strings(
|
|
|
159
159
|
) -> str:
|
|
160
160
|
content = get_pylint_ignore_comment(notebook)
|
|
161
161
|
content += imports_string
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
content += get_comment("logging", notebook) + "\n"
|
|
163
|
+
content += get_logging_start_string(tabs=0) + "\n\n"
|
|
164
164
|
content += models_string
|
|
165
165
|
content += get_comment("agents", notebook) + "\n"
|
|
166
166
|
content += agents_string
|
|
@@ -182,7 +182,6 @@ def _combine_strings(
|
|
|
182
182
|
if not notebook:
|
|
183
183
|
content += get_def_main(chats_content)
|
|
184
184
|
else:
|
|
185
|
-
content += get_logging_start_string(tabs=0)
|
|
186
185
|
content += "\n" + chats_content + "\n"
|
|
187
186
|
content += get_logging_stop_string(tabs=0) + "\n"
|
|
188
187
|
content += get_sqlite_to_csv_call_string(tabs=0) + "\n"
|