waldiez 0.4.7__py3-none-any.whl → 0.4.9__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 +97 -102
- 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} +37 -24
- 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 +439 -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 +115 -61
- waldiez/running/__init__.py +13 -7
- waldiez/running/environment.py +49 -68
- waldiez/running/gen_seq_diagram.py +16 -14
- waldiez/running/post_run.py +119 -0
- waldiez/running/pre_run.py +149 -0
- waldiez/running/util.py +134 -0
- waldiez/utils/__init__.py +2 -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/utils/version.py +47 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/METADATA +235 -91
- waldiez-0.4.9.dist-info/RECORD +203 -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/running/running.py +0 -369
- 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.9.dist-info}/WHEEL +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/entry_points.txt +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/licenses/LICENSE +0 -0
- {waldiez-0.4.7.dist-info → waldiez-0.4.9.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
"""Core dataclasses for the exporting system."""
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass, field, fields
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any, Optional, TypeVar
|
|
9
|
+
|
|
10
|
+
from .enums import (
|
|
11
|
+
ImportPosition,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Generic type for extras
|
|
15
|
+
Extras = TypeVar("Extras")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Sentinel for exporters that do not require extras
|
|
19
|
+
# pylint: disable=too-few-public-methods
|
|
20
|
+
class _NoExtrasType:
|
|
21
|
+
"""Sentinel for exporters that do not require extras."""
|
|
22
|
+
|
|
23
|
+
def __repr__(self) -> str:
|
|
24
|
+
"""Get the string representation of NoExtras."""
|
|
25
|
+
return "<NoExtras>"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
NoExtras = _NoExtrasType()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Core Data Structures
|
|
32
|
+
@dataclass
|
|
33
|
+
class ImportStatement:
|
|
34
|
+
"""Represents an import statement with its position."""
|
|
35
|
+
|
|
36
|
+
statement: str
|
|
37
|
+
position: ImportPosition = ImportPosition.THIRD_PARTY
|
|
38
|
+
metadata: Optional[dict[str, Any]] = None
|
|
39
|
+
|
|
40
|
+
def __hash__(self) -> int:
|
|
41
|
+
"""Hash based on the import statement.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
int
|
|
46
|
+
The hash value of the import statement.
|
|
47
|
+
"""
|
|
48
|
+
return hash(self.statement)
|
|
49
|
+
|
|
50
|
+
def __eq__(self, other: object) -> bool:
|
|
51
|
+
"""Check equality based on the import statement.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
other : object
|
|
56
|
+
The object to compare against.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
bool
|
|
61
|
+
True if the other object is an
|
|
62
|
+
ImportStatement with the same statement.
|
|
63
|
+
"""
|
|
64
|
+
if isinstance(other, ImportStatement):
|
|
65
|
+
return self.statement == other.statement
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
def __lt__(self, other: "ImportStatement") -> bool:
|
|
69
|
+
"""Enable sorting by position then statement.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
other : ImportStatement
|
|
74
|
+
The other import statement to compare against.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
bool
|
|
79
|
+
True if this import statement should come before the other.
|
|
80
|
+
"""
|
|
81
|
+
if self.position.value != other.position.value:
|
|
82
|
+
return self.position.value < other.position.value
|
|
83
|
+
return self.statement < other.statement
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass
|
|
87
|
+
class EnvironmentVariable:
|
|
88
|
+
"""Environment variable with metadata."""
|
|
89
|
+
|
|
90
|
+
name: str
|
|
91
|
+
value: str
|
|
92
|
+
description: Optional[str] = None
|
|
93
|
+
required: bool = True
|
|
94
|
+
|
|
95
|
+
def __post_init__(self) -> None:
|
|
96
|
+
"""Validate environment variable."""
|
|
97
|
+
if not self.name or not self.value:
|
|
98
|
+
raise ValueError("Environment variable name and value are required")
|
|
99
|
+
|
|
100
|
+
def __hash__(self) -> int:
|
|
101
|
+
"""Hash based on the environment variable name.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
int
|
|
106
|
+
The hash value of the environment variable name.
|
|
107
|
+
"""
|
|
108
|
+
return hash(self.name)
|
|
109
|
+
|
|
110
|
+
def __eq__(self, other: object) -> bool:
|
|
111
|
+
"""Check equality based on the environment variable name.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
other : object
|
|
116
|
+
The object to compare against.
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
bool
|
|
121
|
+
True if the other object is an
|
|
122
|
+
EnvironmentVariable with the same name.
|
|
123
|
+
"""
|
|
124
|
+
if isinstance(other, EnvironmentVariable):
|
|
125
|
+
return self.name == other.name
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
def as_tuple(self) -> tuple[str, str]:
|
|
129
|
+
"""Get the environment variable as a tuple.
|
|
130
|
+
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
tuple[str, str]
|
|
134
|
+
The environment variable as a tuple.
|
|
135
|
+
"""
|
|
136
|
+
return (self.name, self.value)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# Instance Argument
|
|
140
|
+
@dataclass
|
|
141
|
+
class InstanceArgument:
|
|
142
|
+
"""Represents an instance argument for an agent, model or tool."""
|
|
143
|
+
|
|
144
|
+
instance_id: str
|
|
145
|
+
name: str
|
|
146
|
+
value: Any
|
|
147
|
+
tabs: int = 0
|
|
148
|
+
tabs_length: int = 4 # Assuming 4 spaces per tab
|
|
149
|
+
with_new_line_before: bool = False
|
|
150
|
+
with_new_line_after: bool = False
|
|
151
|
+
with_new_line_if_empty: bool = False
|
|
152
|
+
skip_if_empty_string: bool = True
|
|
153
|
+
comment: Optional[str] = None
|
|
154
|
+
|
|
155
|
+
def has_content(self) -> bool:
|
|
156
|
+
"""Check if the instance argument has content.
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
bool
|
|
161
|
+
True if the instance argument has content, otherwise False.
|
|
162
|
+
"""
|
|
163
|
+
if self.skip_if_empty_string and isinstance(self.value, str):
|
|
164
|
+
return bool(self.value.strip())
|
|
165
|
+
return self.value is not None and self.value != ""
|
|
166
|
+
|
|
167
|
+
def get_content(
|
|
168
|
+
self,
|
|
169
|
+
prepend_new_line: bool = False,
|
|
170
|
+
append_new_line: bool = False,
|
|
171
|
+
) -> str:
|
|
172
|
+
"""Get the content representation of the instance argument.
|
|
173
|
+
|
|
174
|
+
Parameters
|
|
175
|
+
----------
|
|
176
|
+
prepend_new_line : bool, optional
|
|
177
|
+
Whether to prepend a new line before the content,
|
|
178
|
+
by default False.
|
|
179
|
+
append_new_line : bool, optional
|
|
180
|
+
Whether to append a new line at the end of the content,
|
|
181
|
+
by default False.
|
|
182
|
+
|
|
183
|
+
Returns
|
|
184
|
+
-------
|
|
185
|
+
str
|
|
186
|
+
The formatted content string for the instance argument.
|
|
187
|
+
"""
|
|
188
|
+
if (
|
|
189
|
+
self.skip_if_empty_string
|
|
190
|
+
and isinstance(self.value, str)
|
|
191
|
+
and not self.value.strip()
|
|
192
|
+
):
|
|
193
|
+
return "\n" if self.with_new_line_if_empty else ""
|
|
194
|
+
space = " " * (self.tabs * self.tabs_length)
|
|
195
|
+
content = f"{space}{self.name}={self.value}," + (
|
|
196
|
+
f" # {self.comment}" if self.comment else ""
|
|
197
|
+
)
|
|
198
|
+
if self.with_new_line_before or prepend_new_line:
|
|
199
|
+
content = "\n" + content
|
|
200
|
+
if self.with_new_line_after or append_new_line:
|
|
201
|
+
content += "\n"
|
|
202
|
+
return content
|
|
203
|
+
|
|
204
|
+
def __hash__(self) -> int:
|
|
205
|
+
"""Hash based on the instance ID and name.
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
int
|
|
210
|
+
The hash value of the instance argument.
|
|
211
|
+
"""
|
|
212
|
+
return hash((self.instance_id, self.name))
|
|
213
|
+
|
|
214
|
+
def __str__(self) -> str:
|
|
215
|
+
"""Get the string representation of the instance argument.
|
|
216
|
+
|
|
217
|
+
Returns
|
|
218
|
+
-------
|
|
219
|
+
str
|
|
220
|
+
The string representation of the instance argument.
|
|
221
|
+
"""
|
|
222
|
+
return self.get_content()
|
|
223
|
+
|
|
224
|
+
def __repr__(self) -> str:
|
|
225
|
+
"""Get the string representation of the instance argument.
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
-------
|
|
229
|
+
str
|
|
230
|
+
The string representation of the instance argument.
|
|
231
|
+
"""
|
|
232
|
+
return self.get_content()
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
# Export Configuration
|
|
236
|
+
@dataclass
|
|
237
|
+
class ExportConfig:
|
|
238
|
+
"""Configuration for export operations.
|
|
239
|
+
|
|
240
|
+
Attributes
|
|
241
|
+
----------
|
|
242
|
+
output_extension : str
|
|
243
|
+
The file extension for the exported content.
|
|
244
|
+
is_async : bool
|
|
245
|
+
Whether the exported content should be asynchronous.
|
|
246
|
+
"""
|
|
247
|
+
|
|
248
|
+
name: str = "Waldiez Flow"
|
|
249
|
+
description: str = (
|
|
250
|
+
"Make AG2 Agents Collaborate: Drag, Drop, and Orchestrate with Waldiez"
|
|
251
|
+
)
|
|
252
|
+
requirements: list[str] = field(default_factory=list[str])
|
|
253
|
+
tags: list[str] = field(default_factory=list[str])
|
|
254
|
+
output_extension: str = "py"
|
|
255
|
+
is_async: bool = False
|
|
256
|
+
output_directory: Optional[str | Path] = None
|
|
257
|
+
cache_seed: Optional[int] = None
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def for_notebook(self) -> bool:
|
|
261
|
+
"""Check if the export is intended for a notebook environment.
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
bool
|
|
266
|
+
True if the output extension is 'ipynb', otherwise False.
|
|
267
|
+
"""
|
|
268
|
+
return self.output_extension == "ipynb"
|
|
269
|
+
|
|
270
|
+
def __post_init__(self) -> None:
|
|
271
|
+
"""Post-initialization validation."""
|
|
272
|
+
if not self.name:
|
|
273
|
+
raise ValueError("ExportConfig name cannot be empty")
|
|
274
|
+
if not self.description:
|
|
275
|
+
raise ValueError("ExportConfig description cannot be empty")
|
|
276
|
+
if not self.output_extension:
|
|
277
|
+
raise ValueError("ExportConfig output_extension cannot be empty")
|
|
278
|
+
|
|
279
|
+
@classmethod
|
|
280
|
+
def create(cls, **kwargs: Any) -> "ExportConfig":
|
|
281
|
+
"""Create a new ExportConfig instance with the provided values.
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
**kwargs : Any
|
|
286
|
+
Keyword arguments to initialize the ExportConfig.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
ExportConfig
|
|
291
|
+
A new instance of ExportConfig.
|
|
292
|
+
"""
|
|
293
|
+
valid_fields = {f.name for f in fields(cls)}
|
|
294
|
+
output_extension = kwargs.pop("output_extension", "py")
|
|
295
|
+
for_notebook = kwargs.pop("for_notebook", output_extension == "ipynb")
|
|
296
|
+
if for_notebook is True:
|
|
297
|
+
output_extension = "ipynb"
|
|
298
|
+
cache_seed = kwargs.pop("cache_seed", None)
|
|
299
|
+
if cache_seed is not None and not isinstance(cache_seed, int):
|
|
300
|
+
cache_seed = None
|
|
301
|
+
return cls(
|
|
302
|
+
cache_seed=cache_seed,
|
|
303
|
+
output_extension=output_extension,
|
|
304
|
+
**{k: v for k, v in kwargs.items() if k in valid_fields},
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
def update(self, **kwargs: Any) -> None:
|
|
308
|
+
"""Update the export configuration with new values.
|
|
309
|
+
|
|
310
|
+
Parameters
|
|
311
|
+
----------
|
|
312
|
+
**kwargs : Any
|
|
313
|
+
Keyword arguments to update the configuration.
|
|
314
|
+
|
|
315
|
+
Raises
|
|
316
|
+
------
|
|
317
|
+
ValueError
|
|
318
|
+
If an invalid configuration key is provided.
|
|
319
|
+
"""
|
|
320
|
+
valid_fields = {f.name for f in fields(self)}
|
|
321
|
+
for key, value in kwargs.items():
|
|
322
|
+
if key in valid_fields:
|
|
323
|
+
setattr(self, key, value)
|
|
324
|
+
if (
|
|
325
|
+
"for_notebook" in kwargs
|
|
326
|
+
and isinstance(kwargs["for_notebook"], bool)
|
|
327
|
+
and "output_extension" not in kwargs
|
|
328
|
+
): # pragma: no cover
|
|
329
|
+
self.output_extension = "ipynb" if kwargs["for_notebook"] else "py"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Utility functions for Waldiez exporting."""
|
|
4
|
+
|
|
5
|
+
from .comment import get_comment
|
|
6
|
+
from .llm_config import get_agent_llm_config_arg
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"get_comment",
|
|
10
|
+
"get_agent_llm_config_arg",
|
|
11
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Get comment string for scripts or notebooks."""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_comment(
|
|
7
|
+
comment: str,
|
|
8
|
+
for_notebook: bool = False,
|
|
9
|
+
md_headings: int = 3,
|
|
10
|
+
) -> str:
|
|
11
|
+
"""Get a comment for the script or notebook.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
comment : str
|
|
16
|
+
The comment to add.
|
|
17
|
+
for_notebook : bool, optional
|
|
18
|
+
Whether the comment is for a notebook, by default False
|
|
19
|
+
md_headings : int, optional
|
|
20
|
+
The number of markdown headings to use (if for_notebook is True),
|
|
21
|
+
by default 2
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
str
|
|
26
|
+
The formatted comment.
|
|
27
|
+
"""
|
|
28
|
+
if for_notebook:
|
|
29
|
+
# For notebooks, we use markdown headings
|
|
30
|
+
heading = "#" + "#" * md_headings
|
|
31
|
+
return f"# %% [markdown]\n{heading} {comment}\n# %% \n"
|
|
32
|
+
# For scripts, we use a simple comment
|
|
33
|
+
return f"# {comment}\n"
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""LLM config argument utility functions for Waldiez agents."""
|
|
4
|
+
|
|
5
|
+
from waldiez.models import WaldiezAgent, WaldiezModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_agent_llm_config_arg(
|
|
9
|
+
agent: WaldiezAgent,
|
|
10
|
+
all_models: list[WaldiezModel],
|
|
11
|
+
model_names: dict[str, str],
|
|
12
|
+
cache_seed: int | None,
|
|
13
|
+
as_dict: bool = False,
|
|
14
|
+
tabs: int = 1,
|
|
15
|
+
) -> str:
|
|
16
|
+
"""Get the string representation of the agent's llm config argument.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
agent : WaldiezAgent
|
|
21
|
+
The agent.
|
|
22
|
+
all_models : list[WaldiezModel]
|
|
23
|
+
All the models in the flow.
|
|
24
|
+
model_names : dict[str, str]
|
|
25
|
+
A mapping of model ids to model names.
|
|
26
|
+
cache_seed : Optional[int]
|
|
27
|
+
The cache seed.
|
|
28
|
+
as_dict : bool, optional
|
|
29
|
+
Whether to return the argument as a dictionary, by default False.
|
|
30
|
+
tabs : int, optional
|
|
31
|
+
The number of tabs for indentation, by default 1.
|
|
32
|
+
|
|
33
|
+
Returns
|
|
34
|
+
-------
|
|
35
|
+
str
|
|
36
|
+
The agent's llm config argument to use.
|
|
37
|
+
"""
|
|
38
|
+
if as_dict is False:
|
|
39
|
+
return _get_agent_llm_config_arg_as_arg(
|
|
40
|
+
agent,
|
|
41
|
+
all_models,
|
|
42
|
+
model_names,
|
|
43
|
+
cache_seed,
|
|
44
|
+
tabs=tabs,
|
|
45
|
+
)
|
|
46
|
+
return _get_agent_llm_config_arg_as_dict(
|
|
47
|
+
agent,
|
|
48
|
+
all_models,
|
|
49
|
+
model_names,
|
|
50
|
+
cache_seed,
|
|
51
|
+
tabs=tabs + 1,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _get_agent_llm_config_arg_as_arg(
|
|
56
|
+
agent: WaldiezAgent,
|
|
57
|
+
all_models: list[WaldiezModel],
|
|
58
|
+
model_names: dict[str, str],
|
|
59
|
+
cache_seed: int | None,
|
|
60
|
+
tabs: int = 1,
|
|
61
|
+
tab_leng: int = 4,
|
|
62
|
+
) -> str:
|
|
63
|
+
tab = " " * tab_leng * tabs if tabs > 0 else ""
|
|
64
|
+
# tab = " " * tabs if tabs > 0 else ""
|
|
65
|
+
if not agent.data.model_ids:
|
|
66
|
+
return f"{tab}llm_config=False, # pyright: ignore" + "\n"
|
|
67
|
+
content = f"{tab}llm_config=autogen.LLMConfig(" + "\n"
|
|
68
|
+
content += f"{tab} config_list=["
|
|
69
|
+
got_at_least_one_model = False
|
|
70
|
+
temperature: float | None = None
|
|
71
|
+
for model_id in agent.data.model_ids:
|
|
72
|
+
model = next((m for m in all_models if m.id == model_id), None)
|
|
73
|
+
if model is not None:
|
|
74
|
+
temperature = model.data.temperature
|
|
75
|
+
model_name = model_names[model_id]
|
|
76
|
+
content += "\n" + f"{tab} {model_name}_llm_config,"
|
|
77
|
+
got_at_least_one_model = True
|
|
78
|
+
if not got_at_least_one_model: # pragma: no cover
|
|
79
|
+
return f"{tab}llm_config=False, # pyright: ignore" + "\n"
|
|
80
|
+
content += "\n" + f"{tab} ]," + "\n"
|
|
81
|
+
content += f"{tab} cache_seed={cache_seed}," + "\n"
|
|
82
|
+
if temperature is not None:
|
|
83
|
+
content += f"{tab} temperature={temperature}," + "\n"
|
|
84
|
+
content += tab + "),\n"
|
|
85
|
+
return content
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _get_agent_llm_config_arg_as_dict(
|
|
89
|
+
agent: WaldiezAgent,
|
|
90
|
+
all_models: list[WaldiezModel],
|
|
91
|
+
model_names: dict[str, str],
|
|
92
|
+
cache_seed: int | None,
|
|
93
|
+
tabs: int = 1,
|
|
94
|
+
tab_leng: int = 4,
|
|
95
|
+
) -> str:
|
|
96
|
+
tab = " " * tab_leng * tabs if tabs > 0 else ""
|
|
97
|
+
if not agent.data.model_ids:
|
|
98
|
+
return f'{tab}"llm_config": False' + "\n"
|
|
99
|
+
content = f'{tab}"llm_config": autogen.LLMConfig(' + "\n"
|
|
100
|
+
content += f"{tab} config_list=["
|
|
101
|
+
got_at_least_one_model = False
|
|
102
|
+
temperature: float | None = None
|
|
103
|
+
for model_id in agent.data.model_ids:
|
|
104
|
+
model = next((m for m in all_models if m.id == model_id), None)
|
|
105
|
+
if model is not None: # pragma: no branch
|
|
106
|
+
temperature = model.data.temperature
|
|
107
|
+
model_name = model_names[model_id]
|
|
108
|
+
content += "\n" + f"{tab} {model_name}_llm_config,"
|
|
109
|
+
got_at_least_one_model = True
|
|
110
|
+
if not got_at_least_one_model: # pragma: no cover
|
|
111
|
+
return f'{tab}"llm_config": False' + "\n"
|
|
112
|
+
content += "\n" + f"{tab} ]," + "\n"
|
|
113
|
+
content += f"{tab} cache_seed={cache_seed}," + "\n"
|
|
114
|
+
if temperature is not None:
|
|
115
|
+
content += f"{tab} temperature={temperature}," + "\n"
|
|
116
|
+
content += tab + "),\n"
|
|
117
|
+
return content
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Validation types and results for Waldiez exporting core."""
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Validation Types
|
|
10
|
+
@dataclass
|
|
11
|
+
class ValidationError:
|
|
12
|
+
"""Represents a validation error."""
|
|
13
|
+
|
|
14
|
+
message: str
|
|
15
|
+
severity: str = "error" # error, warning, info
|
|
16
|
+
location: Optional[str] = None
|
|
17
|
+
suggestion: Optional[str] = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class ValidationResult:
|
|
22
|
+
"""Result of validation operations."""
|
|
23
|
+
|
|
24
|
+
is_valid: bool
|
|
25
|
+
errors: list[ValidationError] = field(
|
|
26
|
+
default_factory=list[ValidationError],
|
|
27
|
+
)
|
|
28
|
+
warnings: list[ValidationError] = field(
|
|
29
|
+
default_factory=list[ValidationError],
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def add_error(
|
|
33
|
+
self,
|
|
34
|
+
message: str,
|
|
35
|
+
location: Optional[str] = None,
|
|
36
|
+
suggestion: Optional[str] = None,
|
|
37
|
+
) -> None:
|
|
38
|
+
"""Add a validation error.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
message : str
|
|
43
|
+
The error message to add.
|
|
44
|
+
location : Optional[str], optional
|
|
45
|
+
The location in the code where the error occurred, by default None
|
|
46
|
+
suggestion : Optional[str], optional
|
|
47
|
+
A suggestion for fixing the error, by default None
|
|
48
|
+
"""
|
|
49
|
+
self.errors.append(
|
|
50
|
+
ValidationError(message, "error", location, suggestion)
|
|
51
|
+
)
|
|
52
|
+
self.is_valid = False
|
|
53
|
+
|
|
54
|
+
def add_warning(self, message: str, location: Optional[str] = None) -> None:
|
|
55
|
+
"""Add a validation warning.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
message : str
|
|
60
|
+
The warning message to add.
|
|
61
|
+
location : Optional[str], optional
|
|
62
|
+
The location in the code where the warning occurred, by default None
|
|
63
|
+
"""
|
|
64
|
+
self.warnings.append(ValidationError(message, "warning", location))
|
|
65
|
+
|
|
66
|
+
def has_errors(self) -> bool:
|
|
67
|
+
"""Check if there are any errors.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
bool
|
|
72
|
+
True if there are validation errors, otherwise False.
|
|
73
|
+
"""
|
|
74
|
+
return len(self.errors) > 0
|
|
75
|
+
|
|
76
|
+
def has_warnings(self) -> bool:
|
|
77
|
+
"""Check if there are any warnings.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
bool
|
|
82
|
+
True if there are validation warnings, otherwise False.
|
|
83
|
+
"""
|
|
84
|
+
return len(self.warnings) > 0
|
|
85
|
+
|
|
86
|
+
def merge(self, other: "ValidationResult") -> None:
|
|
87
|
+
"""Merge another ValidationResult into this one.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
other : ValidationResult
|
|
92
|
+
The other validation result to merge.
|
|
93
|
+
"""
|
|
94
|
+
self.is_valid = self.is_valid and other.is_valid
|
|
95
|
+
self.errors.extend(other.errors)
|
|
96
|
+
self.warnings.extend(other.warnings)
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
3
|
"""Flow exporter."""
|
|
4
4
|
|
|
5
|
-
from .
|
|
5
|
+
from .exporter import FlowExporter
|
|
6
|
+
from .factory import create_flow_exporter
|
|
6
7
|
|
|
7
|
-
__all__ = [
|
|
8
|
+
__all__ = [
|
|
9
|
+
"FlowExporter",
|
|
10
|
+
"create_flow_exporter",
|
|
11
|
+
]
|