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,705 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
"""Export result containers and related classes."""
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from typing import Any, Optional, Union
|
|
8
|
+
|
|
9
|
+
from .constants import (
|
|
10
|
+
DEFAULT_EXPORT_POSITION,
|
|
11
|
+
DEFAULT_IMPORT_POSITION,
|
|
12
|
+
)
|
|
13
|
+
from .content import (
|
|
14
|
+
PositionedContent,
|
|
15
|
+
)
|
|
16
|
+
from .enums import (
|
|
17
|
+
AgentPosition,
|
|
18
|
+
ContentOrder,
|
|
19
|
+
ExportPosition,
|
|
20
|
+
ImportPosition,
|
|
21
|
+
)
|
|
22
|
+
from .types import (
|
|
23
|
+
EnvironmentVariable,
|
|
24
|
+
ImportStatement,
|
|
25
|
+
InstanceArgument,
|
|
26
|
+
)
|
|
27
|
+
from .validation import ValidationResult
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class ExportResult:
|
|
32
|
+
"""Complete export result with all components."""
|
|
33
|
+
|
|
34
|
+
main_content: Optional[str] = None
|
|
35
|
+
imports: set[ImportStatement] = field(
|
|
36
|
+
default_factory=set[ImportStatement],
|
|
37
|
+
)
|
|
38
|
+
positioned_content: list[PositionedContent] = field(
|
|
39
|
+
default_factory=list[PositionedContent],
|
|
40
|
+
)
|
|
41
|
+
instance_arguments: list[InstanceArgument] = field(
|
|
42
|
+
default_factory=list[InstanceArgument],
|
|
43
|
+
)
|
|
44
|
+
environment_variables: list[EnvironmentVariable] = field(
|
|
45
|
+
default_factory=list[EnvironmentVariable]
|
|
46
|
+
)
|
|
47
|
+
validation_result: Optional[ValidationResult] = None
|
|
48
|
+
metadata: dict[str, Any] = field(default_factory=dict[str, Any])
|
|
49
|
+
|
|
50
|
+
def add_import(
|
|
51
|
+
self, statement: str, position: ImportPosition = DEFAULT_IMPORT_POSITION
|
|
52
|
+
) -> None:
|
|
53
|
+
"""Add an import statement.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
statement : str
|
|
58
|
+
The import statement to add.
|
|
59
|
+
position : ImportPosition, optional
|
|
60
|
+
The position of the import, by default THIRD_PARTY
|
|
61
|
+
"""
|
|
62
|
+
if statement and statement.strip():
|
|
63
|
+
self.imports.add(
|
|
64
|
+
ImportStatement(
|
|
65
|
+
statement=statement.strip(),
|
|
66
|
+
position=position,
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def add_imports(
|
|
71
|
+
self,
|
|
72
|
+
statements: Union[
|
|
73
|
+
set[str],
|
|
74
|
+
list[str],
|
|
75
|
+
set[ImportStatement],
|
|
76
|
+
list[ImportStatement],
|
|
77
|
+
],
|
|
78
|
+
position: ImportPosition = DEFAULT_IMPORT_POSITION,
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Add multiple import statements.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
statements : Union[
|
|
85
|
+
set[str],
|
|
86
|
+
list[str]],
|
|
87
|
+
set[ImportStatement],
|
|
88
|
+
list[ImportStatement]
|
|
89
|
+
]
|
|
90
|
+
The import statements to add.
|
|
91
|
+
position : ImportPosition, optional
|
|
92
|
+
The position of the imports, by default THIRD_PARTY
|
|
93
|
+
"""
|
|
94
|
+
for statement in statements:
|
|
95
|
+
if isinstance(statement, ImportStatement):
|
|
96
|
+
# If it's already an ImportStatement, use it directly
|
|
97
|
+
self.add_import(statement.statement, statement.position)
|
|
98
|
+
else:
|
|
99
|
+
# Otherwise, treat it as a string
|
|
100
|
+
self.add_import(statement, position)
|
|
101
|
+
# self.add_import(statement, position)
|
|
102
|
+
|
|
103
|
+
def add_instance_argument(
|
|
104
|
+
self,
|
|
105
|
+
name: str,
|
|
106
|
+
value: Any,
|
|
107
|
+
instance_id: str,
|
|
108
|
+
tabs: int = 0,
|
|
109
|
+
comment: Optional[str] = None,
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Add an instance argument.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
name : str
|
|
116
|
+
The name of the argument.
|
|
117
|
+
value : Any
|
|
118
|
+
The value of the argument.
|
|
119
|
+
instance_id : str
|
|
120
|
+
The ID of the instance this argument belongs to.
|
|
121
|
+
tabs : int, optional
|
|
122
|
+
Number of tabs for indentation, by default 0
|
|
123
|
+
comment : Optional[str], optional
|
|
124
|
+
Optional comment for the argument, by default None
|
|
125
|
+
"""
|
|
126
|
+
if name and value is not None:
|
|
127
|
+
arg = InstanceArgument(
|
|
128
|
+
instance_id=instance_id,
|
|
129
|
+
name=name,
|
|
130
|
+
value=value,
|
|
131
|
+
comment=comment,
|
|
132
|
+
tabs=tabs,
|
|
133
|
+
)
|
|
134
|
+
# Avoid duplicates based on name
|
|
135
|
+
for existing in self.instance_arguments:
|
|
136
|
+
if existing.name == name:
|
|
137
|
+
# Update existing
|
|
138
|
+
existing.value = value
|
|
139
|
+
existing.comment = comment
|
|
140
|
+
return
|
|
141
|
+
self.instance_arguments.append(arg)
|
|
142
|
+
|
|
143
|
+
def add_instance_arguments(
|
|
144
|
+
self,
|
|
145
|
+
arguments: Union[list[InstanceArgument], set[InstanceArgument]],
|
|
146
|
+
) -> None:
|
|
147
|
+
"""Add multiple instance arguments.
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
arguments : Union[list[InstanceArgument], set[InstanceArgument]]
|
|
152
|
+
The instance arguments to add.
|
|
153
|
+
"""
|
|
154
|
+
for arg in arguments:
|
|
155
|
+
self.add_instance_argument(
|
|
156
|
+
instance_id=arg.instance_id,
|
|
157
|
+
name=arg.name,
|
|
158
|
+
value=arg.value,
|
|
159
|
+
comment=arg.comment,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def merge(
|
|
163
|
+
self,
|
|
164
|
+
other: "ExportResult",
|
|
165
|
+
position: ExportPosition = DEFAULT_EXPORT_POSITION,
|
|
166
|
+
) -> None:
|
|
167
|
+
"""Merge another ExportResult into this one.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
other : ExportResult
|
|
172
|
+
The other result to merge.
|
|
173
|
+
position : ExportPosition, optional
|
|
174
|
+
The position for the merged content, by default AGENTS
|
|
175
|
+
"""
|
|
176
|
+
if other.main_content:
|
|
177
|
+
self.main_content = (
|
|
178
|
+
(self.main_content or "") + "\n" + other.main_content
|
|
179
|
+
).strip()
|
|
180
|
+
|
|
181
|
+
self.imports.update(other.imports)
|
|
182
|
+
|
|
183
|
+
self.positioned_content.extend(
|
|
184
|
+
PositionedContent(
|
|
185
|
+
content=c.content,
|
|
186
|
+
position=position,
|
|
187
|
+
order=c.order,
|
|
188
|
+
agent_id=c.agent_id,
|
|
189
|
+
agent_position=c.agent_position,
|
|
190
|
+
**c.metadata,
|
|
191
|
+
)
|
|
192
|
+
for c in other.positioned_content
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
self.environment_variables.extend(other.environment_variables)
|
|
196
|
+
|
|
197
|
+
if other.validation_result:
|
|
198
|
+
if self.validation_result:
|
|
199
|
+
self.validation_result.merge(other.validation_result)
|
|
200
|
+
else:
|
|
201
|
+
self.validation_result = other.validation_result
|
|
202
|
+
|
|
203
|
+
# Merge instance arguments
|
|
204
|
+
for arg in other.instance_arguments:
|
|
205
|
+
self.add_instance_argument(
|
|
206
|
+
name=arg.name,
|
|
207
|
+
value=arg.value,
|
|
208
|
+
instance_id=arg.instance_id,
|
|
209
|
+
comment=arg.comment,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
self.metadata.update(other.metadata)
|
|
213
|
+
|
|
214
|
+
def add_content(
|
|
215
|
+
self,
|
|
216
|
+
content: str,
|
|
217
|
+
position: ExportPosition = DEFAULT_EXPORT_POSITION,
|
|
218
|
+
order: Union[ContentOrder, int] = ContentOrder.MAIN_CONTENT,
|
|
219
|
+
skip_strip: bool = False,
|
|
220
|
+
agent_id: Optional[str] = None,
|
|
221
|
+
agent_position: Optional[AgentPosition] = None,
|
|
222
|
+
metadata: Optional[dict[str, Any]] = None,
|
|
223
|
+
) -> None:
|
|
224
|
+
"""Add positioned content.
|
|
225
|
+
|
|
226
|
+
Parameters
|
|
227
|
+
----------
|
|
228
|
+
content : str
|
|
229
|
+
The content to add.
|
|
230
|
+
position : ExportPosition, optional
|
|
231
|
+
The position of the content, by default AGENTS
|
|
232
|
+
order : int, optional
|
|
233
|
+
The order within the position, by default 0
|
|
234
|
+
skip_strip : bool, optional
|
|
235
|
+
Whether to skip stripping whitespace from content, by default False
|
|
236
|
+
agent_id : Optional[str], optional
|
|
237
|
+
The agent ID if positioned relative to an agent, by default None
|
|
238
|
+
agent_position : Optional[AgentPosition], optional
|
|
239
|
+
The position relative to the agent, by default None
|
|
240
|
+
metadata : Optional[dict[str, Any]], optional
|
|
241
|
+
Additional metadata for the content, by default None
|
|
242
|
+
"""
|
|
243
|
+
order_value = order.value if isinstance(order, ContentOrder) else order
|
|
244
|
+
if content and content.strip():
|
|
245
|
+
positioned = PositionedContent(
|
|
246
|
+
content=content.strip() if not skip_strip else content,
|
|
247
|
+
position=position,
|
|
248
|
+
order=order_value,
|
|
249
|
+
agent_id=agent_id,
|
|
250
|
+
agent_position=agent_position,
|
|
251
|
+
**(metadata or {}),
|
|
252
|
+
)
|
|
253
|
+
if positioned not in self.positioned_content:
|
|
254
|
+
self.positioned_content.append(positioned)
|
|
255
|
+
|
|
256
|
+
def add_env_var(
|
|
257
|
+
self,
|
|
258
|
+
name: str,
|
|
259
|
+
value: str,
|
|
260
|
+
description: Optional[str] = None,
|
|
261
|
+
required: bool = True,
|
|
262
|
+
) -> None:
|
|
263
|
+
"""Add environment variable.
|
|
264
|
+
|
|
265
|
+
Parameters
|
|
266
|
+
----------
|
|
267
|
+
name : str
|
|
268
|
+
The name of the environment variable.
|
|
269
|
+
value : str
|
|
270
|
+
The value of the environment variable.
|
|
271
|
+
description : Optional[str], optional
|
|
272
|
+
Description of the variable, by default None
|
|
273
|
+
required : bool, optional
|
|
274
|
+
Whether the variable is required, by default True
|
|
275
|
+
"""
|
|
276
|
+
if name and value:
|
|
277
|
+
env_var = EnvironmentVariable(
|
|
278
|
+
name=name,
|
|
279
|
+
value=value,
|
|
280
|
+
description=description,
|
|
281
|
+
required=required,
|
|
282
|
+
)
|
|
283
|
+
# Avoid duplicates based on name
|
|
284
|
+
for existing in self.environment_variables:
|
|
285
|
+
if existing.name == name:
|
|
286
|
+
# Update existing
|
|
287
|
+
existing.value = value
|
|
288
|
+
existing.description = description
|
|
289
|
+
existing.required = required
|
|
290
|
+
return
|
|
291
|
+
self.environment_variables.append(env_var)
|
|
292
|
+
|
|
293
|
+
def get_sorted_imports(self) -> list[ImportStatement]:
|
|
294
|
+
"""Get imports sorted by position and statement.
|
|
295
|
+
|
|
296
|
+
Returns
|
|
297
|
+
-------
|
|
298
|
+
list[ImportStatement]
|
|
299
|
+
Sorted list of import statements.
|
|
300
|
+
"""
|
|
301
|
+
return sorted(self.imports)
|
|
302
|
+
|
|
303
|
+
def get_imports_by_position(
|
|
304
|
+
self, position: ImportPosition
|
|
305
|
+
) -> list[ImportStatement]:
|
|
306
|
+
"""Get imports filtered by position.
|
|
307
|
+
|
|
308
|
+
Parameters
|
|
309
|
+
----------
|
|
310
|
+
position : ImportPosition
|
|
311
|
+
The position to filter by.
|
|
312
|
+
|
|
313
|
+
Returns
|
|
314
|
+
-------
|
|
315
|
+
list[ImportStatement]
|
|
316
|
+
list of imports for the specified position.
|
|
317
|
+
"""
|
|
318
|
+
return [
|
|
319
|
+
imp for imp in self.get_sorted_imports() if imp.position == position
|
|
320
|
+
]
|
|
321
|
+
|
|
322
|
+
def get_content_by_position(
|
|
323
|
+
self,
|
|
324
|
+
position: ExportPosition,
|
|
325
|
+
skip_agent_arguments: bool = True,
|
|
326
|
+
) -> list[PositionedContent]:
|
|
327
|
+
"""Get all content for a specific position.
|
|
328
|
+
|
|
329
|
+
Parameters
|
|
330
|
+
----------
|
|
331
|
+
position : ExportPosition
|
|
332
|
+
The position to filter by.
|
|
333
|
+
skip_agent_arguments : bool, optional
|
|
334
|
+
Whether to skip content positioned as agent arguments,
|
|
335
|
+
by default True
|
|
336
|
+
|
|
337
|
+
Returns
|
|
338
|
+
-------
|
|
339
|
+
list[PositionedContent]
|
|
340
|
+
Sorted list of content for the specified position.
|
|
341
|
+
"""
|
|
342
|
+
if not skip_agent_arguments:
|
|
343
|
+
content = [
|
|
344
|
+
c for c in self.positioned_content if c.position == position
|
|
345
|
+
]
|
|
346
|
+
else:
|
|
347
|
+
content = [
|
|
348
|
+
c
|
|
349
|
+
for c in self.positioned_content
|
|
350
|
+
if c.position == position
|
|
351
|
+
and (c.agent_position != AgentPosition.AS_ARGUMENT)
|
|
352
|
+
]
|
|
353
|
+
return sorted(content)
|
|
354
|
+
|
|
355
|
+
def get_agent_content(
|
|
356
|
+
self, agent_id: str, agent_position: Optional[AgentPosition] = None
|
|
357
|
+
) -> list[PositionedContent]:
|
|
358
|
+
"""Get content positioned relative to a specific agent.
|
|
359
|
+
|
|
360
|
+
Parameters
|
|
361
|
+
----------
|
|
362
|
+
agent_id : str
|
|
363
|
+
The ID of the agent.
|
|
364
|
+
agent_position : Optional[AgentPosition], optional
|
|
365
|
+
Filter by specific agent position, by default None (all positions)
|
|
366
|
+
|
|
367
|
+
Returns
|
|
368
|
+
-------
|
|
369
|
+
list[PositionedContent]
|
|
370
|
+
Sorted list of content for the specified agent.
|
|
371
|
+
"""
|
|
372
|
+
content = [
|
|
373
|
+
c
|
|
374
|
+
for c in self.positioned_content
|
|
375
|
+
if c.agent_id == agent_id
|
|
376
|
+
and (agent_position is None or c.agent_position == agent_position)
|
|
377
|
+
]
|
|
378
|
+
return sorted(content)
|
|
379
|
+
|
|
380
|
+
def get_all_content_sorted(self) -> list[PositionedContent]:
|
|
381
|
+
"""Get all positioned content sorted by position and order.
|
|
382
|
+
|
|
383
|
+
Returns
|
|
384
|
+
-------
|
|
385
|
+
list[PositionedContent]
|
|
386
|
+
All positioned content sorted.
|
|
387
|
+
"""
|
|
388
|
+
return sorted(self.positioned_content)
|
|
389
|
+
|
|
390
|
+
def merge_with(self, other: "ExportResult") -> None:
|
|
391
|
+
"""Merge another ExportResult into this one.
|
|
392
|
+
|
|
393
|
+
Parameters
|
|
394
|
+
----------
|
|
395
|
+
other : ExportResult
|
|
396
|
+
The other result to merge.
|
|
397
|
+
"""
|
|
398
|
+
# Merge imports (set automatically handles duplicates)
|
|
399
|
+
self.imports.update(other.imports)
|
|
400
|
+
|
|
401
|
+
# Merge positioned content
|
|
402
|
+
self.positioned_content.extend(other.positioned_content)
|
|
403
|
+
|
|
404
|
+
# Merge environment variables (avoid duplicates by name)
|
|
405
|
+
for env_var in other.environment_variables:
|
|
406
|
+
self.add_env_var(
|
|
407
|
+
env_var.name,
|
|
408
|
+
env_var.value,
|
|
409
|
+
env_var.description,
|
|
410
|
+
env_var.required,
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
# Merge metadata
|
|
414
|
+
self.metadata.update(other.metadata)
|
|
415
|
+
|
|
416
|
+
# Handle validation results
|
|
417
|
+
if other.validation_result:
|
|
418
|
+
if self.validation_result:
|
|
419
|
+
# Merge validation results
|
|
420
|
+
self.validation_result.errors.extend(
|
|
421
|
+
other.validation_result.errors
|
|
422
|
+
)
|
|
423
|
+
self.validation_result.warnings.extend(
|
|
424
|
+
other.validation_result.warnings
|
|
425
|
+
)
|
|
426
|
+
self.validation_result.is_valid = (
|
|
427
|
+
self.validation_result.is_valid
|
|
428
|
+
and other.validation_result.is_valid
|
|
429
|
+
)
|
|
430
|
+
else:
|
|
431
|
+
self.validation_result = other.validation_result
|
|
432
|
+
|
|
433
|
+
def has_content(self) -> bool:
|
|
434
|
+
"""Check if there's any meaningful content.
|
|
435
|
+
|
|
436
|
+
Returns
|
|
437
|
+
-------
|
|
438
|
+
bool
|
|
439
|
+
True if there's any content, imports, or environment variables.
|
|
440
|
+
"""
|
|
441
|
+
return bool(
|
|
442
|
+
self.main_content
|
|
443
|
+
or self.imports
|
|
444
|
+
or self.positioned_content
|
|
445
|
+
or self.environment_variables
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
def has_errors(self) -> bool:
|
|
449
|
+
"""Check if there are validation errors.
|
|
450
|
+
|
|
451
|
+
Returns
|
|
452
|
+
-------
|
|
453
|
+
bool
|
|
454
|
+
True if there are validation errors.
|
|
455
|
+
"""
|
|
456
|
+
return (
|
|
457
|
+
self.validation_result is not None
|
|
458
|
+
and self.validation_result.has_errors()
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
def has_warnings(self) -> bool:
|
|
462
|
+
"""Check if there are validation warnings.
|
|
463
|
+
|
|
464
|
+
Returns
|
|
465
|
+
-------
|
|
466
|
+
bool
|
|
467
|
+
True if there are validation warnings.
|
|
468
|
+
"""
|
|
469
|
+
return (
|
|
470
|
+
self.validation_result is not None
|
|
471
|
+
and self.validation_result.has_warnings()
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
def get_statistics(self) -> dict[str, int]:
|
|
475
|
+
"""Get statistics about the export result.
|
|
476
|
+
|
|
477
|
+
Returns
|
|
478
|
+
-------
|
|
479
|
+
dict[str, int]
|
|
480
|
+
dictionary with statistics about the export.
|
|
481
|
+
"""
|
|
482
|
+
return {
|
|
483
|
+
"total_imports": len(self.imports),
|
|
484
|
+
"builtin_imports": len(
|
|
485
|
+
self.get_imports_by_position(ImportPosition.BUILTINS)
|
|
486
|
+
),
|
|
487
|
+
"third_party_imports": len(
|
|
488
|
+
self.get_imports_by_position(ImportPosition.THIRD_PARTY)
|
|
489
|
+
),
|
|
490
|
+
"local_imports": len(
|
|
491
|
+
self.get_imports_by_position(ImportPosition.LOCAL)
|
|
492
|
+
),
|
|
493
|
+
"positioned_content_items": len(self.positioned_content),
|
|
494
|
+
"environment_variables": len(self.environment_variables),
|
|
495
|
+
"validation_errors": (
|
|
496
|
+
len(self.validation_result.errors)
|
|
497
|
+
if self.validation_result
|
|
498
|
+
else 0
|
|
499
|
+
),
|
|
500
|
+
"validation_warnings": (
|
|
501
|
+
len(self.validation_result.warnings)
|
|
502
|
+
if self.validation_result
|
|
503
|
+
else 0
|
|
504
|
+
),
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
def clear(self) -> None:
|
|
508
|
+
"""Clear all content from the result."""
|
|
509
|
+
self.main_content = None
|
|
510
|
+
self.imports.clear()
|
|
511
|
+
self.positioned_content.clear()
|
|
512
|
+
self.environment_variables.clear()
|
|
513
|
+
self.validation_result = None
|
|
514
|
+
self.metadata.clear()
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
@dataclass
|
|
518
|
+
class ExportResultBuilder:
|
|
519
|
+
"""Builder pattern for constructing ExportResult objects."""
|
|
520
|
+
|
|
521
|
+
_result: ExportResult = field(default_factory=ExportResult)
|
|
522
|
+
|
|
523
|
+
def with_main_content(self, content: str) -> "ExportResultBuilder":
|
|
524
|
+
"""Set the main content.
|
|
525
|
+
|
|
526
|
+
Parameters
|
|
527
|
+
----------
|
|
528
|
+
content : str
|
|
529
|
+
The main content to set.
|
|
530
|
+
|
|
531
|
+
Returns
|
|
532
|
+
-------
|
|
533
|
+
ExportResultBuilder
|
|
534
|
+
Self for method chaining.
|
|
535
|
+
"""
|
|
536
|
+
self._result.main_content = content
|
|
537
|
+
return self
|
|
538
|
+
|
|
539
|
+
def with_import(
|
|
540
|
+
self, statement: str, position: ImportPosition = DEFAULT_IMPORT_POSITION
|
|
541
|
+
) -> "ExportResultBuilder":
|
|
542
|
+
"""Add an import statement.
|
|
543
|
+
|
|
544
|
+
Parameters
|
|
545
|
+
----------
|
|
546
|
+
statement : str
|
|
547
|
+
The import statement.
|
|
548
|
+
position : ImportPosition, optional
|
|
549
|
+
The import position, by default THIRD_PARTY
|
|
550
|
+
|
|
551
|
+
Returns
|
|
552
|
+
-------
|
|
553
|
+
ExportResultBuilder
|
|
554
|
+
Self for method chaining.
|
|
555
|
+
"""
|
|
556
|
+
self._result.add_import(statement, position)
|
|
557
|
+
return self
|
|
558
|
+
|
|
559
|
+
def with_content(
|
|
560
|
+
self,
|
|
561
|
+
content: str,
|
|
562
|
+
position: ExportPosition = DEFAULT_EXPORT_POSITION,
|
|
563
|
+
order: ContentOrder = ContentOrder.MAIN_CONTENT,
|
|
564
|
+
agent_id: Optional[str] = None,
|
|
565
|
+
agent_position: Optional[AgentPosition] = None,
|
|
566
|
+
) -> "ExportResultBuilder":
|
|
567
|
+
"""Add positioned content.
|
|
568
|
+
|
|
569
|
+
Parameters
|
|
570
|
+
----------
|
|
571
|
+
content : str
|
|
572
|
+
The content to add.
|
|
573
|
+
position : ExportPosition, optional
|
|
574
|
+
The content position, by default AGENTS
|
|
575
|
+
order : int, optional
|
|
576
|
+
The order within position, by default 0
|
|
577
|
+
agent_id : Optional[str], optional
|
|
578
|
+
Agent ID for agent-relative positioning, by default None
|
|
579
|
+
agent_position : Optional[AgentPosition], optional
|
|
580
|
+
Position relative to agent, by default None
|
|
581
|
+
|
|
582
|
+
Returns
|
|
583
|
+
-------
|
|
584
|
+
ExportResultBuilder
|
|
585
|
+
Self for method chaining.
|
|
586
|
+
"""
|
|
587
|
+
self._result.add_content(
|
|
588
|
+
content=content,
|
|
589
|
+
position=position,
|
|
590
|
+
order=order,
|
|
591
|
+
agent_id=agent_id,
|
|
592
|
+
agent_position=agent_position,
|
|
593
|
+
)
|
|
594
|
+
return self
|
|
595
|
+
|
|
596
|
+
def with_env_var(
|
|
597
|
+
self, name: str, value: str, description: Optional[str] = None
|
|
598
|
+
) -> "ExportResultBuilder":
|
|
599
|
+
"""Add environment variable.
|
|
600
|
+
|
|
601
|
+
Parameters
|
|
602
|
+
----------
|
|
603
|
+
name : str
|
|
604
|
+
Variable name.
|
|
605
|
+
value : str
|
|
606
|
+
Variable value.
|
|
607
|
+
description : Optional[str], optional
|
|
608
|
+
Variable description, by default None
|
|
609
|
+
|
|
610
|
+
Returns
|
|
611
|
+
-------
|
|
612
|
+
ExportResultBuilder
|
|
613
|
+
Self for method chaining.
|
|
614
|
+
"""
|
|
615
|
+
self._result.add_env_var(name, value, description)
|
|
616
|
+
return self
|
|
617
|
+
|
|
618
|
+
def with_metadata(self, key: str, value: Any) -> "ExportResultBuilder":
|
|
619
|
+
"""Add metadata.
|
|
620
|
+
|
|
621
|
+
Parameters
|
|
622
|
+
----------
|
|
623
|
+
key : str
|
|
624
|
+
Metadata key.
|
|
625
|
+
value : Any
|
|
626
|
+
Metadata value.
|
|
627
|
+
|
|
628
|
+
Returns
|
|
629
|
+
-------
|
|
630
|
+
ExportResultBuilder
|
|
631
|
+
Self for method chaining.
|
|
632
|
+
"""
|
|
633
|
+
self._result.metadata[key] = value
|
|
634
|
+
return self
|
|
635
|
+
|
|
636
|
+
def build(self) -> ExportResult:
|
|
637
|
+
"""Build the final ExportResult.
|
|
638
|
+
|
|
639
|
+
Returns
|
|
640
|
+
-------
|
|
641
|
+
ExportResult
|
|
642
|
+
The constructed ExportResult.
|
|
643
|
+
"""
|
|
644
|
+
return self._result
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
# Utility functions for common operations
|
|
648
|
+
def merge_export_results(*results: ExportResult) -> ExportResult:
|
|
649
|
+
"""Merge multiple ExportResult objects into one.
|
|
650
|
+
|
|
651
|
+
Parameters
|
|
652
|
+
----------
|
|
653
|
+
*results : ExportResult
|
|
654
|
+
Variable number of ExportResult objects to merge.
|
|
655
|
+
|
|
656
|
+
Returns
|
|
657
|
+
-------
|
|
658
|
+
ExportResult
|
|
659
|
+
A new ExportResult containing all merged content.
|
|
660
|
+
"""
|
|
661
|
+
if not results:
|
|
662
|
+
return ExportResult()
|
|
663
|
+
|
|
664
|
+
merged = ExportResult()
|
|
665
|
+
for result in results:
|
|
666
|
+
merged.merge_with(result)
|
|
667
|
+
|
|
668
|
+
return merged
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
def create_empty_result() -> ExportResult:
|
|
672
|
+
"""Create an empty ExportResult.
|
|
673
|
+
|
|
674
|
+
Returns
|
|
675
|
+
-------
|
|
676
|
+
ExportResult
|
|
677
|
+
An empty ExportResult instance.
|
|
678
|
+
"""
|
|
679
|
+
return ExportResult()
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
def create_result_with_content(
|
|
683
|
+
main_content: str,
|
|
684
|
+
imports: Optional[list[str]] = None,
|
|
685
|
+
) -> ExportResult:
|
|
686
|
+
"""Create an ExportResult with basic content.
|
|
687
|
+
|
|
688
|
+
Parameters
|
|
689
|
+
----------
|
|
690
|
+
main_content : str
|
|
691
|
+
The main content.
|
|
692
|
+
imports : Optional[list[str]], optional
|
|
693
|
+
list of import statements, by default None
|
|
694
|
+
|
|
695
|
+
Returns
|
|
696
|
+
-------
|
|
697
|
+
ExportResult
|
|
698
|
+
The created ExportResult.
|
|
699
|
+
"""
|
|
700
|
+
result = ExportResult(main_content=main_content)
|
|
701
|
+
|
|
702
|
+
if imports:
|
|
703
|
+
result.add_imports(imports)
|
|
704
|
+
|
|
705
|
+
return result
|