waldiez 0.4.7__py3-none-any.whl → 0.4.8__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 +5 -5
- waldiez/_version.py +1 -1
- waldiez/cli.py +112 -73
- waldiez/exporter.py +61 -19
- waldiez/exporting/__init__.py +25 -6
- waldiez/exporting/agent/__init__.py +7 -3
- waldiez/exporting/agent/code_execution.py +114 -0
- waldiez/exporting/agent/exporter.py +354 -0
- waldiez/exporting/agent/extras/__init__.py +15 -0
- waldiez/exporting/agent/extras/captain_agent_extras.py +315 -0
- waldiez/exporting/agent/extras/group/target.py +178 -0
- waldiez/exporting/agent/extras/group_manager_agent_extas.py +500 -0
- waldiez/exporting/agent/extras/group_member_extras.py +181 -0
- waldiez/exporting/agent/extras/handoffs/__init__.py +19 -0
- waldiez/exporting/agent/extras/handoffs/after_work.py +78 -0
- waldiez/exporting/agent/extras/handoffs/available.py +74 -0
- waldiez/exporting/agent/extras/handoffs/condition.py +158 -0
- waldiez/exporting/agent/extras/handoffs/handoff.py +171 -0
- waldiez/exporting/agent/extras/handoffs/target.py +189 -0
- waldiez/exporting/agent/extras/rag/__init__.py +10 -0
- waldiez/exporting/agent/{utils/rag_user/chroma_utils.py → extras/rag/chroma_extras.py} +16 -15
- waldiez/exporting/agent/{utils/rag_user/mongo_utils.py → extras/rag/mongo_extras.py} +10 -10
- waldiez/exporting/agent/{utils/rag_user/pgvector_utils.py → extras/rag/pgvector_extras.py} +13 -13
- waldiez/exporting/agent/{utils/rag_user/qdrant_utils.py → extras/rag/qdrant_extras.py} +13 -13
- waldiez/exporting/agent/{utils/rag_user/vector_db.py → extras/rag/vector_db_extras.py} +59 -46
- waldiez/exporting/agent/extras/rag_user_proxy_agent_extras.py +245 -0
- waldiez/exporting/agent/extras/reasoning_agent_extras.py +88 -0
- waldiez/exporting/agent/factory.py +95 -0
- waldiez/exporting/agent/processor.py +150 -0
- waldiez/exporting/agent/system_message.py +36 -0
- waldiez/exporting/agent/termination.py +50 -0
- waldiez/exporting/chats/__init__.py +7 -3
- waldiez/exporting/chats/exporter.py +97 -0
- waldiez/exporting/chats/factory.py +65 -0
- waldiez/exporting/chats/processor.py +226 -0
- waldiez/exporting/chats/utils/__init__.py +6 -5
- waldiez/exporting/chats/utils/common.py +11 -45
- waldiez/exporting/chats/utils/group.py +55 -0
- waldiez/exporting/chats/utils/nested.py +37 -52
- waldiez/exporting/chats/utils/sequential.py +72 -61
- waldiez/exporting/chats/utils/{single_chat.py → single.py} +48 -50
- waldiez/exporting/core/__init__.py +196 -0
- waldiez/exporting/core/constants.py +17 -0
- waldiez/exporting/core/content.py +69 -0
- waldiez/exporting/core/context.py +244 -0
- waldiez/exporting/core/enums.py +89 -0
- waldiez/exporting/core/errors.py +19 -0
- waldiez/exporting/core/exporter.py +390 -0
- waldiez/exporting/core/exporters.py +67 -0
- waldiez/exporting/core/extras/__init__.py +39 -0
- waldiez/exporting/core/extras/agent_extras/__init__.py +27 -0
- waldiez/exporting/core/extras/agent_extras/captain_extras.py +57 -0
- waldiez/exporting/core/extras/agent_extras/group_manager_extras.py +102 -0
- waldiez/exporting/core/extras/agent_extras/rag_user_extras.py +53 -0
- waldiez/exporting/core/extras/agent_extras/reasoning_extras.py +68 -0
- waldiez/exporting/core/extras/agent_extras/standard_extras.py +263 -0
- waldiez/exporting/core/extras/base.py +241 -0
- waldiez/exporting/core/extras/chat_extras.py +118 -0
- waldiez/exporting/core/extras/flow_extras.py +70 -0
- waldiez/exporting/core/extras/model_extras.py +73 -0
- waldiez/exporting/core/extras/path_resolver.py +93 -0
- waldiez/exporting/core/extras/serializer.py +138 -0
- waldiez/exporting/core/extras/tool_extras.py +82 -0
- waldiez/exporting/core/protocols.py +259 -0
- waldiez/exporting/core/result.py +705 -0
- waldiez/exporting/core/types.py +329 -0
- waldiez/exporting/core/utils/__init__.py +11 -0
- waldiez/exporting/core/utils/comment.py +33 -0
- waldiez/exporting/core/utils/llm_config.py +117 -0
- waldiez/exporting/core/validation.py +96 -0
- waldiez/exporting/flow/__init__.py +6 -2
- waldiez/exporting/flow/execution_generator.py +193 -0
- waldiez/exporting/flow/exporter.py +107 -0
- waldiez/exporting/flow/factory.py +94 -0
- waldiez/exporting/flow/file_generator.py +214 -0
- waldiez/exporting/flow/merger.py +387 -0
- waldiez/exporting/flow/orchestrator.py +411 -0
- waldiez/exporting/flow/utils/__init__.py +9 -36
- waldiez/exporting/flow/utils/common.py +206 -0
- waldiez/exporting/flow/utils/importing.py +373 -0
- waldiez/exporting/flow/utils/linting.py +200 -0
- waldiez/exporting/flow/utils/{logging_utils.py → logging.py} +23 -9
- waldiez/exporting/models/__init__.py +3 -1
- waldiez/exporting/models/exporter.py +233 -0
- waldiez/exporting/models/factory.py +66 -0
- waldiez/exporting/models/processor.py +139 -0
- waldiez/exporting/tools/__init__.py +11 -0
- waldiez/exporting/tools/exporter.py +207 -0
- waldiez/exporting/tools/factory.py +57 -0
- waldiez/exporting/tools/processor.py +248 -0
- waldiez/exporting/tools/registration.py +133 -0
- waldiez/io/__init__.py +128 -0
- waldiez/io/_ws.py +199 -0
- waldiez/io/models/__init__.py +60 -0
- waldiez/io/models/base.py +66 -0
- waldiez/io/models/constants.py +78 -0
- waldiez/io/models/content/__init__.py +23 -0
- waldiez/io/models/content/audio.py +43 -0
- waldiez/io/models/content/base.py +45 -0
- waldiez/io/models/content/file.py +43 -0
- waldiez/io/models/content/image.py +96 -0
- waldiez/io/models/content/text.py +37 -0
- waldiez/io/models/content/video.py +43 -0
- waldiez/io/models/user_input.py +269 -0
- waldiez/io/models/user_response.py +215 -0
- waldiez/io/mqtt.py +681 -0
- waldiez/io/redis.py +782 -0
- waldiez/io/structured.py +419 -0
- waldiez/io/utils.py +184 -0
- waldiez/io/ws.py +298 -0
- waldiez/logger.py +481 -0
- waldiez/models/__init__.py +108 -51
- waldiez/models/agents/__init__.py +34 -70
- waldiez/models/agents/agent/__init__.py +10 -4
- waldiez/models/agents/agent/agent.py +466 -65
- waldiez/models/agents/agent/agent_data.py +119 -47
- waldiez/models/agents/agent/agent_type.py +13 -2
- waldiez/models/agents/agent/code_execution.py +12 -12
- waldiez/models/agents/agent/human_input_mode.py +8 -0
- waldiez/models/agents/agent/{linked_skill.py → linked_tool.py} +7 -7
- waldiez/models/agents/agent/nested_chat.py +35 -7
- waldiez/models/agents/agent/termination_message.py +30 -22
- waldiez/models/agents/{swarm_agent → agent}/update_system_message.py +22 -22
- waldiez/models/agents/agents.py +58 -63
- waldiez/models/agents/assistant/assistant.py +4 -4
- waldiez/models/agents/assistant/assistant_data.py +13 -1
- waldiez/models/agents/{captain_agent → captain}/captain_agent.py +5 -5
- waldiez/models/agents/{captain_agent → captain}/captain_agent_data.py +5 -5
- waldiez/models/agents/extra_requirements.py +11 -16
- waldiez/models/agents/group_manager/group_manager.py +103 -13
- waldiez/models/agents/group_manager/group_manager_data.py +36 -14
- waldiez/models/agents/group_manager/speakers.py +77 -24
- waldiez/models/agents/{rag_user → rag_user_proxy}/__init__.py +16 -16
- waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +64 -0
- waldiez/models/agents/{rag_user/rag_user_data.py → rag_user_proxy/rag_user_proxy_data.py} +6 -5
- waldiez/models/agents/{rag_user → rag_user_proxy}/retrieve_config.py +182 -114
- waldiez/models/agents/{rag_user → rag_user_proxy}/vector_db_config.py +13 -13
- waldiez/models/agents/reasoning/reasoning_agent.py +6 -6
- waldiez/models/agents/reasoning/reasoning_agent_data.py +110 -63
- waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +38 -10
- waldiez/models/agents/user_proxy/user_proxy.py +11 -7
- waldiez/models/agents/user_proxy/user_proxy_data.py +2 -2
- waldiez/models/chat/__init__.py +2 -1
- waldiez/models/chat/chat.py +166 -87
- waldiez/models/chat/chat_data.py +99 -136
- waldiez/models/chat/chat_message.py +33 -23
- waldiez/models/chat/chat_nested.py +31 -30
- waldiez/models/chat/chat_summary.py +10 -8
- waldiez/models/common/__init__.py +52 -2
- waldiez/models/common/ag2_version.py +1 -1
- waldiez/models/common/base.py +38 -7
- waldiez/models/common/dict_utils.py +42 -17
- waldiez/models/common/handoff.py +459 -0
- waldiez/models/common/id_generator.py +19 -0
- waldiez/models/common/method_utils.py +130 -68
- waldiez/{exporting/base/utils → models/common}/naming.py +38 -61
- waldiez/models/common/waldiez_version.py +37 -0
- waldiez/models/flow/__init__.py +9 -2
- waldiez/models/flow/connection.py +18 -0
- waldiez/models/flow/flow.py +311 -215
- waldiez/models/flow/flow_data.py +207 -40
- waldiez/models/flow/info.py +85 -0
- waldiez/models/flow/naming.py +131 -0
- waldiez/models/model/__init__.py +7 -1
- waldiez/models/model/extra_requirements.py +3 -12
- waldiez/models/model/model.py +76 -21
- waldiez/models/model/model_data.py +108 -20
- waldiez/models/tool/__init__.py +16 -0
- waldiez/models/tool/extra_requirements.py +36 -0
- waldiez/models/{skill/skill.py → tool/tool.py} +88 -88
- waldiez/models/tool/tool_data.py +51 -0
- waldiez/models/tool/tool_type.py +8 -0
- waldiez/models/waldiez.py +97 -80
- waldiez/runner.py +114 -49
- waldiez/running/__init__.py +1 -1
- waldiez/running/environment.py +49 -68
- waldiez/running/gen_seq_diagram.py +16 -14
- waldiez/running/running.py +53 -34
- waldiez/utils/__init__.py +0 -4
- waldiez/utils/cli_extras/jupyter.py +5 -3
- waldiez/utils/cli_extras/runner.py +6 -4
- waldiez/utils/cli_extras/studio.py +6 -4
- waldiez/utils/conflict_checker.py +15 -9
- waldiez/utils/flaml_warnings.py +5 -5
- {waldiez-0.4.7.dist-info → waldiez-0.4.8.dist-info}/METADATA +235 -91
- waldiez-0.4.8.dist-info/RECORD +200 -0
- waldiez/exporting/agent/agent_exporter.py +0 -297
- waldiez/exporting/agent/utils/__init__.py +0 -23
- waldiez/exporting/agent/utils/captain_agent.py +0 -263
- waldiez/exporting/agent/utils/code_execution.py +0 -65
- waldiez/exporting/agent/utils/group_manager.py +0 -220
- waldiez/exporting/agent/utils/rag_user/__init__.py +0 -7
- waldiez/exporting/agent/utils/rag_user/rag_user.py +0 -209
- waldiez/exporting/agent/utils/reasoning.py +0 -36
- waldiez/exporting/agent/utils/swarm_agent.py +0 -469
- waldiez/exporting/agent/utils/teachability.py +0 -41
- waldiez/exporting/agent/utils/termination_message.py +0 -44
- waldiez/exporting/base/__init__.py +0 -25
- waldiez/exporting/base/agent_position.py +0 -75
- waldiez/exporting/base/base_exporter.py +0 -118
- waldiez/exporting/base/export_position.py +0 -48
- waldiez/exporting/base/import_position.py +0 -23
- waldiez/exporting/base/mixin.py +0 -137
- waldiez/exporting/base/utils/__init__.py +0 -18
- waldiez/exporting/base/utils/comments.py +0 -96
- waldiez/exporting/base/utils/path_check.py +0 -68
- waldiez/exporting/base/utils/to_string.py +0 -84
- waldiez/exporting/chats/chats_exporter.py +0 -240
- waldiez/exporting/chats/utils/swarm.py +0 -210
- waldiez/exporting/flow/flow_exporter.py +0 -528
- waldiez/exporting/flow/utils/agent_utils.py +0 -204
- waldiez/exporting/flow/utils/chat_utils.py +0 -71
- waldiez/exporting/flow/utils/def_main.py +0 -77
- waldiez/exporting/flow/utils/flow_content.py +0 -202
- waldiez/exporting/flow/utils/flow_names.py +0 -116
- waldiez/exporting/flow/utils/importing_utils.py +0 -227
- waldiez/exporting/models/models_exporter.py +0 -199
- waldiez/exporting/models/utils.py +0 -174
- waldiez/exporting/skills/__init__.py +0 -9
- waldiez/exporting/skills/skills_exporter.py +0 -176
- waldiez/exporting/skills/utils.py +0 -369
- waldiez/models/agents/agent/teachability.py +0 -70
- waldiez/models/agents/rag_user/rag_user.py +0 -60
- waldiez/models/agents/swarm_agent/__init__.py +0 -50
- waldiez/models/agents/swarm_agent/after_work.py +0 -179
- waldiez/models/agents/swarm_agent/on_condition.py +0 -105
- waldiez/models/agents/swarm_agent/on_condition_available.py +0 -142
- waldiez/models/agents/swarm_agent/on_condition_target.py +0 -40
- waldiez/models/agents/swarm_agent/swarm_agent.py +0 -107
- waldiez/models/agents/swarm_agent/swarm_agent_data.py +0 -124
- waldiez/models/flow/utils.py +0 -232
- waldiez/models/skill/__init__.py +0 -16
- waldiez/models/skill/extra_requirements.py +0 -36
- waldiez/models/skill/skill_data.py +0 -53
- waldiez/models/skill/skill_type.py +0 -8
- waldiez/utils/pysqlite3_checker.py +0 -308
- waldiez/utils/rdps_checker.py +0 -122
- waldiez-0.4.7.dist-info/RECORD +0 -149
- /waldiez/models/agents/{captain_agent → captain}/__init__.py +0 -0
- /waldiez/models/agents/{captain_agent → captain}/captain_agent_lib_entry.py +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.8.dist-info}/WHEEL +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.8.dist-info}/entry_points.txt +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.8.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.8.dist-info}/licenses/NOTICE.md +0 -0
waldiez/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
from .exporter import WaldiezExporter
|
|
6
6
|
from .models import Waldiez
|
|
7
7
|
from .runner import WaldiezRunner
|
|
8
|
-
from .utils import check_conflicts, check_flaml_warnings
|
|
8
|
+
from .utils import check_conflicts, check_flaml_warnings
|
|
9
9
|
|
|
10
10
|
# flake8: noqa: F401
|
|
11
11
|
# pylint: disable=import-error,line-too-long
|
|
@@ -22,13 +22,13 @@ except ImportError: # pragma: no cover
|
|
|
22
22
|
)
|
|
23
23
|
__version__ = "dev"
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
# pylint: disable=invalid-name
|
|
26
|
+
__waldiez_initialized = False
|
|
26
27
|
|
|
27
|
-
if not
|
|
28
|
-
|
|
28
|
+
if not __waldiez_initialized:
|
|
29
|
+
__waldiez_initialized = True
|
|
29
30
|
check_conflicts()
|
|
30
31
|
check_flaml_warnings()
|
|
31
|
-
check_rpds_py()
|
|
32
32
|
|
|
33
33
|
__all__ = [
|
|
34
34
|
"Waldiez",
|
waldiez/_version.py
CHANGED
waldiez/cli.py
CHANGED
|
@@ -5,22 +5,21 @@
|
|
|
5
5
|
"""Command line interface to convert or run a waldiez file."""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
-
import logging
|
|
9
8
|
import os
|
|
10
|
-
import sys
|
|
11
9
|
from pathlib import Path
|
|
12
|
-
from typing import TYPE_CHECKING, Optional
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
13
11
|
|
|
14
12
|
import anyio
|
|
15
13
|
import typer
|
|
14
|
+
from dotenv import load_dotenv
|
|
16
15
|
from typing_extensions import Annotated
|
|
17
16
|
|
|
18
17
|
# pylint: disable=import-error,line-too-long
|
|
19
18
|
# pyright: reportMissingImports=false
|
|
20
19
|
try: # pragma: no cover
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
# fmt: off
|
|
21
|
+
from ._version import __version__ # type: ignore[unused-ignore, unused-import, import-not-found, import-untyped] # noqa
|
|
22
|
+
# fmt: on
|
|
24
23
|
except ImportError: # pragma: no cover
|
|
25
24
|
import warnings
|
|
26
25
|
|
|
@@ -31,6 +30,8 @@ except ImportError: # pragma: no cover
|
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
from .exporter import WaldiezExporter
|
|
33
|
+
from .io import StructuredIOStream
|
|
34
|
+
from .logger import get_logger
|
|
34
35
|
from .models import Waldiez
|
|
35
36
|
from .runner import WaldiezRunner
|
|
36
37
|
from .utils import add_cli_extras
|
|
@@ -39,6 +40,9 @@ if TYPE_CHECKING:
|
|
|
39
40
|
from autogen import ChatResult # type: ignore[import-untyped]
|
|
40
41
|
|
|
41
42
|
|
|
43
|
+
load_dotenv()
|
|
44
|
+
LOG = get_logger()
|
|
45
|
+
|
|
42
46
|
app = typer.Typer(
|
|
43
47
|
name="waldiez",
|
|
44
48
|
help="Handle Waldiez flows.",
|
|
@@ -52,7 +56,7 @@ app = typer.Typer(
|
|
|
52
56
|
invoke_without_command=True,
|
|
53
57
|
add_help_option=True,
|
|
54
58
|
pretty_exceptions_enable=False,
|
|
55
|
-
epilog=
|
|
59
|
+
epilog="Use `waldiez [COMMAND] --help` for command-specific help.",
|
|
56
60
|
)
|
|
57
61
|
|
|
58
62
|
|
|
@@ -95,6 +99,22 @@ def run(
|
|
|
95
99
|
dir_okay=False,
|
|
96
100
|
resolve_path=True,
|
|
97
101
|
),
|
|
102
|
+
uploads_root: Optional[Path] = typer.Option( # noqa: B008
|
|
103
|
+
None,
|
|
104
|
+
help=(
|
|
105
|
+
"Path to the uploads root directory. "
|
|
106
|
+
"The directory will contain "
|
|
107
|
+
"any uploaded files."
|
|
108
|
+
),
|
|
109
|
+
dir_okay=True,
|
|
110
|
+
resolve_path=True,
|
|
111
|
+
),
|
|
112
|
+
structured: bool = typer.Option( # noqa: B008
|
|
113
|
+
False,
|
|
114
|
+
help=(
|
|
115
|
+
"If set, running the flow will use structured io stream instead of the default 'input/print' "
|
|
116
|
+
),
|
|
117
|
+
),
|
|
98
118
|
force: bool = typer.Option( # noqa: B008
|
|
99
119
|
False,
|
|
100
120
|
help="Override the output file if it already exists.",
|
|
@@ -110,28 +130,27 @@ def run(
|
|
|
110
130
|
except json.decoder.JSONDecodeError as error:
|
|
111
131
|
typer.echo("Invalid .waldiez file. Not a valid json?")
|
|
112
132
|
raise typer.Exit(code=1) from error
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
logger = _get_logger()
|
|
133
|
+
results = _do_run(
|
|
134
|
+
data,
|
|
135
|
+
structured=structured,
|
|
136
|
+
uploads_root=uploads_root,
|
|
137
|
+
output_path=output_path,
|
|
138
|
+
)
|
|
120
139
|
if isinstance(results, list):
|
|
121
|
-
|
|
140
|
+
LOG.info("Results:")
|
|
122
141
|
for result in results:
|
|
123
|
-
_log_result(result
|
|
142
|
+
_log_result(result)
|
|
124
143
|
sep = "-" * 80
|
|
125
144
|
print("\n" + f"{sep}" + "\n")
|
|
126
145
|
elif isinstance(results, dict):
|
|
127
|
-
|
|
146
|
+
LOG.info("Results:")
|
|
128
147
|
for key, result in results.items():
|
|
129
|
-
|
|
130
|
-
_log_result(result
|
|
148
|
+
LOG.info("Order: %s", key)
|
|
149
|
+
_log_result(result)
|
|
131
150
|
sep = "-" * 80
|
|
132
151
|
print("\n" + f"{sep}" + "\n")
|
|
133
152
|
else:
|
|
134
|
-
_log_result(results
|
|
153
|
+
_log_result(results)
|
|
135
154
|
|
|
136
155
|
|
|
137
156
|
@app.command()
|
|
@@ -148,24 +167,31 @@ def convert(
|
|
|
148
167
|
resolve_path=True,
|
|
149
168
|
),
|
|
150
169
|
],
|
|
151
|
-
output:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
),
|
|
160
|
-
file_okay=True,
|
|
161
|
-
dir_okay=False,
|
|
162
|
-
resolve_path=True,
|
|
170
|
+
output: Path | None = typer.Option( # noqa: B008
|
|
171
|
+
default=None,
|
|
172
|
+
help=(
|
|
173
|
+
"Path to the output file. "
|
|
174
|
+
"The file extension determines the output format: "
|
|
175
|
+
"`.py` for Python script, `.ipynb` for Jupyter notebook."
|
|
176
|
+
" If not provided, the output will be saved in the same directory as the input file."
|
|
177
|
+
" If the file already exists, it will not be overwritten unless --force is used."
|
|
163
178
|
),
|
|
164
|
-
|
|
179
|
+
file_okay=True,
|
|
180
|
+
dir_okay=False,
|
|
181
|
+
resolve_path=True,
|
|
182
|
+
),
|
|
165
183
|
force: bool = typer.Option(
|
|
166
184
|
False,
|
|
167
185
|
help="Override the output file if it already exists.",
|
|
168
186
|
),
|
|
187
|
+
debug: bool = typer.Option(
|
|
188
|
+
False,
|
|
189
|
+
"--debug",
|
|
190
|
+
"-d",
|
|
191
|
+
help="Enable debug logging.",
|
|
192
|
+
is_eager=True,
|
|
193
|
+
rich_help_panel="Debug",
|
|
194
|
+
),
|
|
169
195
|
) -> None:
|
|
170
196
|
"""Convert a Waldiez flow to a Python script or a Jupyter notebook."""
|
|
171
197
|
_get_output_path(output, force)
|
|
@@ -177,7 +203,11 @@ def convert(
|
|
|
177
203
|
raise typer.Exit(code=1) from error
|
|
178
204
|
waldiez = Waldiez.from_dict(data)
|
|
179
205
|
exporter = WaldiezExporter(waldiez)
|
|
180
|
-
|
|
206
|
+
if debug:
|
|
207
|
+
LOG.set_level("DEBUG")
|
|
208
|
+
if output is None:
|
|
209
|
+
output = Path(file).with_suffix(".py").resolve()
|
|
210
|
+
exporter.export(output, force=force, debug=debug)
|
|
181
211
|
generated = str(output).replace(os.getcwd(), ".")
|
|
182
212
|
typer.echo(f"Generated: {generated}")
|
|
183
213
|
|
|
@@ -201,7 +231,46 @@ def check(
|
|
|
201
231
|
with file.open("r", encoding="utf-8") as _file:
|
|
202
232
|
data = json.load(_file)
|
|
203
233
|
Waldiez.from_dict(data)
|
|
204
|
-
|
|
234
|
+
LOG.success("Waldiez flow seems valid.")
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _do_run(
|
|
238
|
+
data: dict[str, Any],
|
|
239
|
+
structured: bool,
|
|
240
|
+
uploads_root: Optional[Path],
|
|
241
|
+
output_path: Optional[Path],
|
|
242
|
+
) -> Union["ChatResult", list["ChatResult"], dict[int, "ChatResult"]]:
|
|
243
|
+
"""Run the Waldiez flow and get the results."""
|
|
244
|
+
waldiez = Waldiez.from_dict(data)
|
|
245
|
+
if structured:
|
|
246
|
+
stream = StructuredIOStream(uploads_root=uploads_root)
|
|
247
|
+
with StructuredIOStream.set_default(stream):
|
|
248
|
+
runner = WaldiezRunner(waldiez)
|
|
249
|
+
if waldiez.is_async:
|
|
250
|
+
results = anyio.run(
|
|
251
|
+
runner.a_run,
|
|
252
|
+
output_path,
|
|
253
|
+
uploads_root,
|
|
254
|
+
)
|
|
255
|
+
else:
|
|
256
|
+
results = runner.run(
|
|
257
|
+
output_path=output_path,
|
|
258
|
+
uploads_root=uploads_root,
|
|
259
|
+
)
|
|
260
|
+
else:
|
|
261
|
+
runner = WaldiezRunner(waldiez)
|
|
262
|
+
if waldiez.is_async:
|
|
263
|
+
results = anyio.run(
|
|
264
|
+
runner.a_run,
|
|
265
|
+
output_path,
|
|
266
|
+
uploads_root,
|
|
267
|
+
)
|
|
268
|
+
else:
|
|
269
|
+
results = runner.run(
|
|
270
|
+
output_path=output_path,
|
|
271
|
+
uploads_root=uploads_root,
|
|
272
|
+
)
|
|
273
|
+
return results
|
|
205
274
|
|
|
206
275
|
|
|
207
276
|
def _get_output_path(output: Optional[Path], force: bool) -> Optional[Path]:
|
|
@@ -211,53 +280,23 @@ def _get_output_path(output: Optional[Path], force: bool) -> Optional[Path]:
|
|
|
211
280
|
output.parent.mkdir(parents=True)
|
|
212
281
|
if output is not None and output.exists():
|
|
213
282
|
if force is False:
|
|
214
|
-
|
|
283
|
+
LOG.error("Output file already exists.")
|
|
215
284
|
raise typer.Exit(code=1)
|
|
216
285
|
output.unlink()
|
|
217
286
|
return output
|
|
218
287
|
|
|
219
288
|
|
|
220
|
-
def
|
|
221
|
-
"""Get the logger for the Waldiez package.
|
|
222
|
-
|
|
223
|
-
Parameters
|
|
224
|
-
----------
|
|
225
|
-
level : int or str, optional
|
|
226
|
-
The logging level. Default is logging.INFO.
|
|
227
|
-
|
|
228
|
-
Returns
|
|
229
|
-
-------
|
|
230
|
-
logging.Logger
|
|
231
|
-
The logger.
|
|
232
|
-
"""
|
|
233
|
-
# check if we already have setup a config
|
|
234
|
-
|
|
235
|
-
if not logging.getLogger().handlers:
|
|
236
|
-
logging.basicConfig(
|
|
237
|
-
level=level,
|
|
238
|
-
format="%(levelname)s %(message)s",
|
|
239
|
-
stream=sys.stderr,
|
|
240
|
-
force=True,
|
|
241
|
-
)
|
|
242
|
-
logger = logging.getLogger("waldiez::cli")
|
|
243
|
-
current_level = logger.getEffectiveLevel()
|
|
244
|
-
if current_level != level:
|
|
245
|
-
logger.setLevel(level)
|
|
246
|
-
return logger
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def _log_result(result: "ChatResult", logger: logging.Logger) -> None:
|
|
289
|
+
def _log_result(result: "ChatResult") -> None:
|
|
250
290
|
"""Log the result of the Waldiez flow."""
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
291
|
+
LOG.info("Chat History:\n")
|
|
292
|
+
LOG.info(result.chat_history)
|
|
293
|
+
LOG.info("Summary:\n")
|
|
294
|
+
LOG.info(result.summary)
|
|
295
|
+
LOG.info("Cost:\n")
|
|
296
|
+
LOG.info(result.cost)
|
|
257
297
|
|
|
258
298
|
|
|
259
299
|
add_cli_extras(app)
|
|
260
300
|
|
|
261
301
|
if __name__ == "__main__":
|
|
262
|
-
_get_logger()
|
|
263
302
|
app()
|
waldiez/exporter.py
CHANGED
|
@@ -14,8 +14,11 @@ from pathlib import Path
|
|
|
14
14
|
from typing import Union
|
|
15
15
|
|
|
16
16
|
import jupytext # type: ignore[import-untyped]
|
|
17
|
+
from jupytext.config import ( # type: ignore[import-untyped]
|
|
18
|
+
JupytextConfiguration,
|
|
19
|
+
)
|
|
17
20
|
|
|
18
|
-
from .exporting import
|
|
21
|
+
from .exporting import FlowExtras, create_flow_exporter
|
|
19
22
|
from .models import Waldiez
|
|
20
23
|
|
|
21
24
|
|
|
@@ -27,6 +30,8 @@ class WaldiezExporter:
|
|
|
27
30
|
waldiez (Waldiez): The Waldiez instance.
|
|
28
31
|
"""
|
|
29
32
|
|
|
33
|
+
flow_extras: FlowExtras
|
|
34
|
+
|
|
30
35
|
def __init__(self, waldiez: Waldiez) -> None:
|
|
31
36
|
"""Initialize the Waldiez exporter.
|
|
32
37
|
|
|
@@ -54,20 +59,27 @@ class WaldiezExporter:
|
|
|
54
59
|
waldiez = Waldiez.load(file_path)
|
|
55
60
|
return cls(waldiez)
|
|
56
61
|
|
|
57
|
-
def export(
|
|
62
|
+
def export(
|
|
63
|
+
self,
|
|
64
|
+
path: Union[str, Path],
|
|
65
|
+
force: bool = False,
|
|
66
|
+
debug: bool = False,
|
|
67
|
+
) -> None:
|
|
58
68
|
"""Export the Waldiez instance.
|
|
59
69
|
|
|
60
70
|
Parameters
|
|
61
71
|
----------
|
|
62
72
|
path : Union[str, Path]
|
|
63
73
|
The path to export to.
|
|
64
|
-
force : bool, optional
|
|
74
|
+
force : bool, (optional)
|
|
65
75
|
Override the output file if it already exists, by default False.
|
|
76
|
+
debug : bool, (optional)
|
|
77
|
+
Whether to enable debug mode, by default False.
|
|
66
78
|
|
|
67
79
|
Raises
|
|
68
80
|
------
|
|
69
81
|
FileExistsError
|
|
70
|
-
If the file already exists and force is False.
|
|
82
|
+
If the file already exists, and force is False.
|
|
71
83
|
IsADirectoryError
|
|
72
84
|
If the output is a directory.
|
|
73
85
|
ValueError
|
|
@@ -85,21 +97,27 @@ class WaldiezExporter:
|
|
|
85
97
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
86
98
|
extension = path.suffix
|
|
87
99
|
if extension == ".waldiez":
|
|
88
|
-
self.to_waldiez(path)
|
|
100
|
+
self.to_waldiez(path, debug=debug)
|
|
89
101
|
elif extension == ".py":
|
|
90
|
-
self.to_py(path)
|
|
102
|
+
self.to_py(path, debug=debug)
|
|
91
103
|
elif extension == ".ipynb":
|
|
92
|
-
self.to_ipynb(path)
|
|
104
|
+
self.to_ipynb(path, debug=debug)
|
|
93
105
|
else:
|
|
94
106
|
raise ValueError(f"Invalid extension: {extension}")
|
|
95
107
|
|
|
96
|
-
def to_ipynb(
|
|
108
|
+
def to_ipynb(
|
|
109
|
+
self,
|
|
110
|
+
path: Path,
|
|
111
|
+
debug: bool = False,
|
|
112
|
+
) -> None:
|
|
97
113
|
"""Export flow to jupyter notebook.
|
|
98
114
|
|
|
99
115
|
Parameters
|
|
100
116
|
----------
|
|
101
117
|
path : Path
|
|
102
118
|
The path to export to.
|
|
119
|
+
debug : bool, optional
|
|
120
|
+
Whether to enable debug mode, by default False.
|
|
103
121
|
|
|
104
122
|
Raises
|
|
105
123
|
------
|
|
@@ -108,57 +126,81 @@ class WaldiezExporter:
|
|
|
108
126
|
"""
|
|
109
127
|
# we first create a .py file with the content
|
|
110
128
|
# and then convert it to a notebook using jupytext
|
|
111
|
-
exporter =
|
|
129
|
+
exporter = create_flow_exporter(
|
|
112
130
|
waldiez=self.waldiez,
|
|
113
131
|
output_dir=path.parent,
|
|
114
132
|
for_notebook=True,
|
|
133
|
+
debug=debug,
|
|
115
134
|
)
|
|
135
|
+
self.flow_extras = exporter.extras
|
|
116
136
|
output = exporter.export()
|
|
117
|
-
|
|
118
|
-
if not
|
|
137
|
+
content_str = output.main_content
|
|
138
|
+
if not content_str:
|
|
119
139
|
raise RuntimeError("Could not generate notebook")
|
|
120
140
|
py_path = path.with_suffix(".tmp.py")
|
|
121
141
|
with open(py_path, "w", encoding="utf-8", newline="\n") as f:
|
|
122
|
-
f.write(
|
|
142
|
+
f.write(content_str)
|
|
143
|
+
config = JupytextConfiguration(
|
|
144
|
+
comment_magics=False,
|
|
145
|
+
hide_notebook_metadata=True,
|
|
146
|
+
cell_metadata_filter="-all",
|
|
147
|
+
)
|
|
123
148
|
with open(py_path, "r", encoding="utf-8") as py_out:
|
|
124
|
-
|
|
149
|
+
jp_content = jupytext.read( # pyright: ignore
|
|
150
|
+
py_out,
|
|
151
|
+
fmt="py:percent",
|
|
152
|
+
config=config,
|
|
153
|
+
)
|
|
125
154
|
ipynb_path = str(py_path).replace(".tmp.py", ".tmp.ipynb")
|
|
126
|
-
jupytext.write(
|
|
155
|
+
jupytext.write( # pyright: ignore
|
|
156
|
+
jp_content,
|
|
157
|
+
ipynb_path,
|
|
158
|
+
fmt="ipynb",
|
|
159
|
+
config=config,
|
|
160
|
+
)
|
|
127
161
|
Path(ipynb_path).rename(ipynb_path.replace(".tmp.ipynb", ".ipynb"))
|
|
128
162
|
py_path.unlink(missing_ok=True)
|
|
129
163
|
|
|
130
|
-
def to_py(self, path: Path) -> None:
|
|
131
|
-
"""Export waldiez flow to python script.
|
|
164
|
+
def to_py(self, path: Path, debug: bool = False) -> None:
|
|
165
|
+
"""Export waldiez flow to a python script.
|
|
132
166
|
|
|
133
167
|
Parameters
|
|
134
168
|
----------
|
|
135
169
|
path : Path
|
|
136
170
|
The path to export to.
|
|
171
|
+
debug : bool, optional
|
|
172
|
+
Whether to enable debug mode, by default False.
|
|
137
173
|
|
|
138
174
|
Raises
|
|
139
175
|
------
|
|
140
176
|
RuntimeError
|
|
141
177
|
If the python script could not be generated.
|
|
142
178
|
"""
|
|
143
|
-
exporter =
|
|
179
|
+
exporter = create_flow_exporter(
|
|
144
180
|
waldiez=self.waldiez,
|
|
145
181
|
output_dir=path.parent,
|
|
146
182
|
for_notebook=False,
|
|
183
|
+
debug=debug,
|
|
147
184
|
)
|
|
185
|
+
self.flow_extras = exporter.extras
|
|
148
186
|
output = exporter.export()
|
|
149
|
-
content = output
|
|
187
|
+
content = output.main_content
|
|
150
188
|
if not content:
|
|
151
189
|
raise RuntimeError("Could not generate python script")
|
|
152
190
|
with open(path, "w", encoding="utf-8", newline="\n") as file:
|
|
153
191
|
file.write(content)
|
|
154
192
|
|
|
155
|
-
def to_waldiez(self, file_path: Path) -> None:
|
|
193
|
+
def to_waldiez(self, file_path: Path, debug: bool = False) -> None:
|
|
156
194
|
"""Export the Waldiez instance.
|
|
157
195
|
|
|
158
196
|
Parameters
|
|
159
197
|
----------
|
|
160
198
|
file_path : Path
|
|
161
199
|
The file path.
|
|
200
|
+
debug : bool, optional
|
|
201
|
+
Whether to enable debug mode, by default False.
|
|
162
202
|
"""
|
|
163
203
|
with open(file_path, "w", encoding="utf-8", newline="\n") as file:
|
|
164
204
|
file.write(self.waldiez.model_dump_json())
|
|
205
|
+
if debug:
|
|
206
|
+
print(self.waldiez.model_dump_json(indent=2))
|
waldiez/exporting/__init__.py
CHANGED
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
-
"""Tools for exporting agents, models,
|
|
3
|
+
"""Tools for exporting agents, models, tools and chats to strings."""
|
|
4
4
|
|
|
5
|
-
from .agent import AgentExporter
|
|
6
|
-
from .
|
|
7
|
-
from .
|
|
8
|
-
|
|
5
|
+
from .agent import AgentExporter, create_agent_exporter
|
|
6
|
+
from .chats import ChatsExporter, create_chats_exporter
|
|
7
|
+
from .core.errors import (
|
|
8
|
+
ExporterContentError,
|
|
9
|
+
ExporterError,
|
|
10
|
+
ExporterInitializationError,
|
|
11
|
+
ExporterValidationError,
|
|
12
|
+
)
|
|
13
|
+
from .core.extras.flow_extras import FlowExtras
|
|
14
|
+
from .flow import FlowExporter, create_flow_exporter
|
|
15
|
+
from .models import ModelsExporter, create_models_exporter
|
|
16
|
+
from .tools import ToolsExporter, create_tools_exporter
|
|
9
17
|
|
|
10
18
|
__all__ = [
|
|
11
19
|
"AgentExporter",
|
|
20
|
+
"ChatsExporter",
|
|
21
|
+
"FlowExtras",
|
|
12
22
|
"FlowExporter",
|
|
13
23
|
"ModelsExporter",
|
|
14
|
-
"
|
|
24
|
+
"ToolsExporter",
|
|
25
|
+
"ExporterContentError",
|
|
26
|
+
"ExporterError",
|
|
27
|
+
"ExporterInitializationError",
|
|
28
|
+
"ExporterValidationError",
|
|
29
|
+
"create_agent_exporter",
|
|
30
|
+
"create_chats_exporter",
|
|
31
|
+
"create_flow_exporter",
|
|
32
|
+
"create_models_exporter",
|
|
33
|
+
"create_tools_exporter",
|
|
15
34
|
]
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0.
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
-
"""
|
|
3
|
+
"""Agent exporter."""
|
|
4
4
|
|
|
5
|
-
from .
|
|
5
|
+
from .exporter import AgentExporter
|
|
6
|
+
from .factory import create_agent_exporter
|
|
6
7
|
|
|
7
|
-
__all__ = [
|
|
8
|
+
__all__ = [
|
|
9
|
+
"AgentExporter",
|
|
10
|
+
"create_agent_exporter",
|
|
11
|
+
]
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
# pylint: disable=too-few-public-methods,no-self-use
|
|
4
|
+
"""Code execution processor for Waldiez agents."""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from waldiez.models import WaldiezAgent, WaldiezAgentCodeExecutionConfig
|
|
9
|
+
|
|
10
|
+
from ..core import CodeExecutionConfig, ImportPosition, ImportStatement
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CodeExecutionProcessor:
|
|
14
|
+
"""Processor for code execution configuration."""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
agent: WaldiezAgent,
|
|
19
|
+
agent_name: str,
|
|
20
|
+
tool_names: dict[str, str],
|
|
21
|
+
):
|
|
22
|
+
self.agent = agent
|
|
23
|
+
self.agent_name = agent_name
|
|
24
|
+
self.tool_names = tool_names
|
|
25
|
+
|
|
26
|
+
def process(self) -> CodeExecutionConfig:
|
|
27
|
+
"""Process code execution configuration.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
CodeExecutionConfig
|
|
32
|
+
The processed code execution configuration.
|
|
33
|
+
"""
|
|
34
|
+
if self.agent.data.code_execution_config is False:
|
|
35
|
+
return CodeExecutionConfig(
|
|
36
|
+
executor_content="",
|
|
37
|
+
executor_argument="False",
|
|
38
|
+
executor_import=None,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
config = self.agent.data.code_execution_config
|
|
42
|
+
use_docker = (
|
|
43
|
+
config.use_docker if config.use_docker is not None else False
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
executor_class = self._get_executor_class_name(use_docker)
|
|
47
|
+
executor_content = self._build_executor_content(config, use_docker)
|
|
48
|
+
executor_arg = f'{{"executor": {self.agent_name}_executor}}'
|
|
49
|
+
executor_import = f"from autogen.coding import {executor_class}"
|
|
50
|
+
|
|
51
|
+
return CodeExecutionConfig(
|
|
52
|
+
executor_content=executor_content,
|
|
53
|
+
executor_argument=executor_arg,
|
|
54
|
+
executor_import=ImportStatement(
|
|
55
|
+
statement=executor_import,
|
|
56
|
+
position=ImportPosition.THIRD_PARTY,
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def _get_executor_class_name(self, use_docker: bool) -> str:
|
|
61
|
+
"""Get the appropriate executor class name."""
|
|
62
|
+
return (
|
|
63
|
+
"DockerCommandLineCodeExecutor"
|
|
64
|
+
if use_docker
|
|
65
|
+
else "LocalCommandLineCodeExecutor"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def _build_executor_content(
|
|
69
|
+
self, config: WaldiezAgentCodeExecutionConfig, use_docker: bool
|
|
70
|
+
) -> str:
|
|
71
|
+
"""Build the executor content string."""
|
|
72
|
+
executor_class = self._get_executor_class_name(use_docker)
|
|
73
|
+
lines = [f"{self.agent_name}_executor = {executor_class}("]
|
|
74
|
+
|
|
75
|
+
# Add work directory
|
|
76
|
+
if config.work_dir:
|
|
77
|
+
lines.append(f" work_dir={json.dumps(config.work_dir)},")
|
|
78
|
+
|
|
79
|
+
# Add timeout
|
|
80
|
+
if config.timeout:
|
|
81
|
+
lines.append(f" timeout={int(config.timeout)},")
|
|
82
|
+
|
|
83
|
+
# Add functions (only for local executor)
|
|
84
|
+
if not use_docker and config.functions:
|
|
85
|
+
function_names = self._get_function_names(config.functions)
|
|
86
|
+
if function_names:
|
|
87
|
+
function_names_str = ", ".join(function_names)
|
|
88
|
+
lines.append(f" functions=[{function_names_str}],")
|
|
89
|
+
|
|
90
|
+
lines.append(")")
|
|
91
|
+
lines.append("") # Add empty line
|
|
92
|
+
|
|
93
|
+
return "\n".join(lines)
|
|
94
|
+
|
|
95
|
+
def _get_function_names(self, function_ids: list[str]) -> list[str]:
|
|
96
|
+
"""Get function names from function IDs.
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
function_ids : list[str]
|
|
101
|
+
List of function IDs to resolve names for.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
list[str]
|
|
106
|
+
List of function names corresponding to the provided IDs.
|
|
107
|
+
"""
|
|
108
|
+
function_names: list[str] = []
|
|
109
|
+
for tool_id in function_ids:
|
|
110
|
+
if tool_id in self.tool_names:
|
|
111
|
+
tool_name = self.tool_names[tool_id]
|
|
112
|
+
if tool_name:
|
|
113
|
+
function_names.append(tool_name)
|
|
114
|
+
return function_names
|