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,57 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
"""Factory function for creating a ToolsExporter instance."""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional, Union
|
|
7
|
+
|
|
8
|
+
from waldiez.models import WaldiezAgent, WaldiezTool
|
|
9
|
+
|
|
10
|
+
from ..core import ExporterContext, get_default_exporter_context
|
|
11
|
+
from .exporter import ToolsExporter
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def create_tools_exporter(
|
|
15
|
+
flow_name: str,
|
|
16
|
+
agents: list[WaldiezAgent],
|
|
17
|
+
agent_names: dict[str, str],
|
|
18
|
+
tools: list[WaldiezTool],
|
|
19
|
+
tool_names: dict[str, str],
|
|
20
|
+
output_dir: Optional[Union[str, Path]] = None,
|
|
21
|
+
context: Optional[ExporterContext] = None,
|
|
22
|
+
) -> ToolsExporter:
|
|
23
|
+
"""Create a tools exporter.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
flow_name : str
|
|
28
|
+
The name of the flow.
|
|
29
|
+
agents : list[WaldiezAgent]
|
|
30
|
+
The agents that use tools.
|
|
31
|
+
agent_names : dict[str, str]
|
|
32
|
+
Mapping of agent IDs to names.
|
|
33
|
+
tools : list[WaldiezTool]
|
|
34
|
+
The tools to export.
|
|
35
|
+
tool_names : dict[str, str]
|
|
36
|
+
Mapping of tool IDs to names.
|
|
37
|
+
output_dir : Optional[Union[str, Path]], optional
|
|
38
|
+
Output directory for generated files, by default None
|
|
39
|
+
context : Optional[ExporterContext], optional
|
|
40
|
+
Exporter context with dependencies, by default None
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
ToolsExporter
|
|
45
|
+
The created tools exporter.
|
|
46
|
+
"""
|
|
47
|
+
if context is None:
|
|
48
|
+
context = get_default_exporter_context()
|
|
49
|
+
return ToolsExporter(
|
|
50
|
+
flow_name=flow_name,
|
|
51
|
+
agents=agents,
|
|
52
|
+
agent_names=agent_names,
|
|
53
|
+
tools=tools,
|
|
54
|
+
tool_names=tool_names,
|
|
55
|
+
output_dir=output_dir,
|
|
56
|
+
context=context,
|
|
57
|
+
)
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
# pylint: disable=too-few-public-methods
|
|
4
|
+
"""Tool related utilities and processors."""
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from waldiez.models import WaldiezTool
|
|
11
|
+
|
|
12
|
+
from ..core.constants import FILE_HEADER
|
|
13
|
+
from ..core.errors import ExporterContentError
|
|
14
|
+
from ..core.types import EnvironmentVariable
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ToolProcessingResult:
|
|
19
|
+
"""Result from processing tools."""
|
|
20
|
+
|
|
21
|
+
content: str = ""
|
|
22
|
+
builtin_imports: list[str] = field(default_factory=list[str])
|
|
23
|
+
third_party_imports: list[str] = field(default_factory=list[str])
|
|
24
|
+
environment_variables: list[EnvironmentVariable] = field(
|
|
25
|
+
default_factory=list[EnvironmentVariable]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ToolProcessor:
|
|
30
|
+
"""Processor for tool content generation."""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
flow_name: str,
|
|
35
|
+
tools: list[WaldiezTool],
|
|
36
|
+
tool_names: dict[str, str],
|
|
37
|
+
output_dir: Optional[Path] = None,
|
|
38
|
+
):
|
|
39
|
+
"""Initialize the tool processor.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
flow_name : str
|
|
44
|
+
The name of the flow.
|
|
45
|
+
tools : list[WaldiezTool]
|
|
46
|
+
The tools to process.
|
|
47
|
+
tool_names : dict[str, str]
|
|
48
|
+
Mapping of tool IDs to names.
|
|
49
|
+
output_dir : Optional[Path], optional
|
|
50
|
+
Output directory for generated files, by default None
|
|
51
|
+
"""
|
|
52
|
+
self.flow_name = flow_name
|
|
53
|
+
self.tools = tools
|
|
54
|
+
self.tool_names = tool_names
|
|
55
|
+
self.output_dir = output_dir
|
|
56
|
+
|
|
57
|
+
def process(self) -> ToolProcessingResult:
|
|
58
|
+
"""Process all tools and return consolidated result.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
ToolProcessingResult
|
|
63
|
+
The processed result containing tool content,
|
|
64
|
+
imports, and environment variables.
|
|
65
|
+
"""
|
|
66
|
+
result = ToolProcessingResult()
|
|
67
|
+
|
|
68
|
+
# Separate shared and regular tools
|
|
69
|
+
shared_tools = [tool for tool in self.tools if tool.is_shared]
|
|
70
|
+
regular_tools = [tool for tool in self.tools if not tool.is_shared]
|
|
71
|
+
|
|
72
|
+
# Process shared tools first (they need to be available to other tools)
|
|
73
|
+
for tool in shared_tools:
|
|
74
|
+
self._process_single_tool(tool, result)
|
|
75
|
+
|
|
76
|
+
# Then regular tools
|
|
77
|
+
for tool in regular_tools:
|
|
78
|
+
self._process_single_tool(tool, result)
|
|
79
|
+
|
|
80
|
+
# Clean up and finalize result
|
|
81
|
+
self._finalize_result(result)
|
|
82
|
+
|
|
83
|
+
return result
|
|
84
|
+
|
|
85
|
+
def _process_single_tool(
|
|
86
|
+
self, tool: WaldiezTool, result: ToolProcessingResult
|
|
87
|
+
) -> None:
|
|
88
|
+
"""Process a single tool and add to result.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
tool : WaldiezTool
|
|
93
|
+
The tool to process.
|
|
94
|
+
result : ToolProcessingResult
|
|
95
|
+
The result to add processed content to.
|
|
96
|
+
"""
|
|
97
|
+
# Get tool content
|
|
98
|
+
tool_content = tool.get_content()
|
|
99
|
+
if tool_content: # pragma: no branch
|
|
100
|
+
# Add interop conversion if needed
|
|
101
|
+
if tool.is_interop:
|
|
102
|
+
tool_content += self._get_interop_conversion(tool)
|
|
103
|
+
|
|
104
|
+
result.content += tool_content + "\n\n"
|
|
105
|
+
|
|
106
|
+
# Get imports
|
|
107
|
+
builtin_imports, third_party_imports = tool.get_imports()
|
|
108
|
+
if builtin_imports:
|
|
109
|
+
result.builtin_imports.extend(builtin_imports)
|
|
110
|
+
if third_party_imports:
|
|
111
|
+
result.third_party_imports.extend(third_party_imports)
|
|
112
|
+
|
|
113
|
+
# Handle secrets
|
|
114
|
+
if tool.secrets:
|
|
115
|
+
self._process_tool_secrets(tool, result)
|
|
116
|
+
|
|
117
|
+
def _get_interop_conversion(self, tool: WaldiezTool) -> str:
|
|
118
|
+
"""Get interop conversion code for a tool.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
tool : WaldiezTool
|
|
123
|
+
The tool that needs interop conversion.
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
str
|
|
128
|
+
The interop conversion code.
|
|
129
|
+
"""
|
|
130
|
+
tool_name = self.tool_names[tool.id]
|
|
131
|
+
return f"""
|
|
132
|
+
ag2_{tool_name}_interop = Interoperability()
|
|
133
|
+
ag2_{tool_name} = ag2_{tool_name}_interop.convert_tool(
|
|
134
|
+
tool={tool_name},
|
|
135
|
+
type="{tool.tool_type}"
|
|
136
|
+
)"""
|
|
137
|
+
|
|
138
|
+
def _process_tool_secrets(
|
|
139
|
+
self, tool: WaldiezTool, result: ToolProcessingResult
|
|
140
|
+
) -> None:
|
|
141
|
+
"""Process tool secrets and add to result.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
tool : WaldiezTool
|
|
146
|
+
The tool with secrets.
|
|
147
|
+
result : ToolProcessingResult
|
|
148
|
+
The result to add secrets to.
|
|
149
|
+
"""
|
|
150
|
+
tool_name = self.tool_names[tool.id]
|
|
151
|
+
|
|
152
|
+
# Add to environment variables
|
|
153
|
+
for key, value in tool.secrets.items():
|
|
154
|
+
result.environment_variables.append(
|
|
155
|
+
EnvironmentVariable(
|
|
156
|
+
name=key,
|
|
157
|
+
value=value,
|
|
158
|
+
description=f"Secret for tool '{tool_name}'",
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Write secrets file if output directory provided
|
|
163
|
+
if self.output_dir:
|
|
164
|
+
self._write_secrets_file(tool, tool_name)
|
|
165
|
+
|
|
166
|
+
def _write_secrets_file(self, tool: WaldiezTool, tool_name: str) -> None:
|
|
167
|
+
"""Write tool secrets to a Python file.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
tool : WaldiezTool
|
|
172
|
+
The tool with secrets.
|
|
173
|
+
tool_name : str
|
|
174
|
+
The name of the tool.
|
|
175
|
+
"""
|
|
176
|
+
if not self.output_dir or not tool.secrets: # pragma: no cover
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
180
|
+
secrets_file = (
|
|
181
|
+
self.output_dir / f"{self.flow_name}_{tool_name}_secrets.py"
|
|
182
|
+
)
|
|
183
|
+
# pylint: disable=too-many-try-statements
|
|
184
|
+
try:
|
|
185
|
+
with secrets_file.open("w", encoding="utf-8", newline="\n") as f:
|
|
186
|
+
f.write(
|
|
187
|
+
f'''{FILE_HEADER}
|
|
188
|
+
# flake8: noqa: E501
|
|
189
|
+
# pylint: disable=line-too-long
|
|
190
|
+
"""Secrets for the tool: {tool_name}."""
|
|
191
|
+
|
|
192
|
+
'''
|
|
193
|
+
)
|
|
194
|
+
f.write("import os\n\n")
|
|
195
|
+
for key, value in tool.secrets.items():
|
|
196
|
+
f.write(f'os.environ["{key}"] = "{value}"\n')
|
|
197
|
+
except Exception as exc: # pragma: no cover
|
|
198
|
+
raise ExporterContentError(
|
|
199
|
+
f"Failed to write secrets file for tool '{tool_name}': {exc}"
|
|
200
|
+
) from exc
|
|
201
|
+
|
|
202
|
+
def _finalize_result(self, result: ToolProcessingResult) -> None:
|
|
203
|
+
"""Finalize the processing result.
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
result : ToolProcessingResult
|
|
208
|
+
The result to finalize.
|
|
209
|
+
"""
|
|
210
|
+
# Clean up content - remove excessive newlines
|
|
211
|
+
result.content = result.content.replace("\n\n\n", "\n\n").strip()
|
|
212
|
+
|
|
213
|
+
# Sort and deduplicate imports
|
|
214
|
+
result.builtin_imports = self._sort_imports(result.builtin_imports)
|
|
215
|
+
result.third_party_imports = self._sort_imports(
|
|
216
|
+
result.third_party_imports
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# pylint: disable=no-self-use
|
|
220
|
+
def _sort_imports(self, imports: list[str]) -> list[str]:
|
|
221
|
+
"""Sort imports: 'import' statements first, then 'from' statements.
|
|
222
|
+
|
|
223
|
+
Parameters
|
|
224
|
+
----------
|
|
225
|
+
imports : list[str]
|
|
226
|
+
The import statements to sort.
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
list[str]
|
|
231
|
+
The sorted import statements.
|
|
232
|
+
"""
|
|
233
|
+
if not imports:
|
|
234
|
+
return []
|
|
235
|
+
|
|
236
|
+
# Remove duplicates
|
|
237
|
+
unique_imports = list(set(imports))
|
|
238
|
+
|
|
239
|
+
# Separate import types
|
|
240
|
+
import_statements = [
|
|
241
|
+
imp for imp in unique_imports if imp.startswith("import ")
|
|
242
|
+
]
|
|
243
|
+
from_statements = [
|
|
244
|
+
imp for imp in unique_imports if imp.startswith("from ")
|
|
245
|
+
]
|
|
246
|
+
|
|
247
|
+
# Sort each type
|
|
248
|
+
return sorted(import_statements) + sorted(from_statements)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
# pylint: disable=too-few-public-methods
|
|
4
|
+
"""Tool registration processor."""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from waldiez.models import WaldiezAgent, WaldiezTool
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ToolRegistrationProcessor:
|
|
12
|
+
"""Processor for tool registration code."""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
agents: list[WaldiezAgent],
|
|
17
|
+
agent_names: dict[str, str],
|
|
18
|
+
tools: list[WaldiezTool],
|
|
19
|
+
tool_names: dict[str, str],
|
|
20
|
+
):
|
|
21
|
+
"""Initialize the tool registration processor.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
agents : list[WaldiezAgent]
|
|
26
|
+
The agents that use tools.
|
|
27
|
+
agent_names : dict[str, str]
|
|
28
|
+
Mapping of agent IDs to names.
|
|
29
|
+
tools : list[WaldiezTool]
|
|
30
|
+
The available tools.
|
|
31
|
+
tool_names : dict[str, str]
|
|
32
|
+
Mapping of tool IDs to names.
|
|
33
|
+
"""
|
|
34
|
+
self.agents = agents
|
|
35
|
+
self.agent_names = agent_names
|
|
36
|
+
self.tools = tools
|
|
37
|
+
self.tool_names = tool_names
|
|
38
|
+
|
|
39
|
+
def process(self) -> str:
|
|
40
|
+
"""Process tool registrations for all agents.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
str
|
|
45
|
+
The generated tool registration code for all agents.
|
|
46
|
+
"""
|
|
47
|
+
registrations: list[str] = []
|
|
48
|
+
|
|
49
|
+
for agent in self.agents:
|
|
50
|
+
agent_registration = self._process_agent_registrations(agent)
|
|
51
|
+
if agent_registration:
|
|
52
|
+
registrations.append(agent_registration)
|
|
53
|
+
|
|
54
|
+
return "\n\n".join(registrations) if registrations else ""
|
|
55
|
+
|
|
56
|
+
def _process_agent_registrations(self, agent: WaldiezAgent) -> str:
|
|
57
|
+
"""Process tool registrations for a single agent.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
agent : WaldiezAgent
|
|
62
|
+
The agent to process tool registrations for.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
str
|
|
67
|
+
The tool registration code for this agent.
|
|
68
|
+
"""
|
|
69
|
+
if not agent.data.tools or agent.is_group_member:
|
|
70
|
+
# if group member, it's a handoff
|
|
71
|
+
return ""
|
|
72
|
+
|
|
73
|
+
registrations: list[str] = []
|
|
74
|
+
agent_name = self.agent_names[agent.id]
|
|
75
|
+
|
|
76
|
+
for tool_link in agent.data.tools:
|
|
77
|
+
# Find the actual tool
|
|
78
|
+
tool = next((t for t in self.tools if t.id == tool_link.id), None)
|
|
79
|
+
if not tool: # pragma: no cover
|
|
80
|
+
continue
|
|
81
|
+
|
|
82
|
+
tool_name = self.tool_names[tool_link.id]
|
|
83
|
+
|
|
84
|
+
# Use converted name for interop tools
|
|
85
|
+
if tool.is_interop:
|
|
86
|
+
tool_name = f"ag2_{tool_name}"
|
|
87
|
+
|
|
88
|
+
executor_name = self.agent_names[tool_link.executor_id]
|
|
89
|
+
description = tool.description or f"Description of {tool_name}"
|
|
90
|
+
|
|
91
|
+
registration = self._create_registration(
|
|
92
|
+
caller_name=agent_name,
|
|
93
|
+
executor_name=executor_name,
|
|
94
|
+
tool_name=tool_name,
|
|
95
|
+
description=description,
|
|
96
|
+
)
|
|
97
|
+
registrations.append(registration)
|
|
98
|
+
|
|
99
|
+
return "\n".join(registrations) if registrations else ""
|
|
100
|
+
|
|
101
|
+
# pylint: disable=no-self-use
|
|
102
|
+
def _create_registration(
|
|
103
|
+
self,
|
|
104
|
+
caller_name: str,
|
|
105
|
+
executor_name: str,
|
|
106
|
+
tool_name: str,
|
|
107
|
+
description: str,
|
|
108
|
+
) -> str:
|
|
109
|
+
"""Create a single tool registration statement.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
caller_name : str
|
|
114
|
+
The name of the agent calling the tool.
|
|
115
|
+
executor_name : str
|
|
116
|
+
The name of the agent executing the tool.
|
|
117
|
+
tool_name : str
|
|
118
|
+
The name of the tool.
|
|
119
|
+
description : str
|
|
120
|
+
The description of the tool.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
str
|
|
125
|
+
The tool registration code.
|
|
126
|
+
"""
|
|
127
|
+
return f"""register_function(
|
|
128
|
+
{tool_name},
|
|
129
|
+
caller={caller_name},
|
|
130
|
+
executor={executor_name},
|
|
131
|
+
name="{tool_name}",
|
|
132
|
+
description={json.dumps(description)},
|
|
133
|
+
)"""
|
waldiez/io/__init__.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0.
|
|
2
|
+
# Copyright (c) 2024 - 2025 Waldiez and contributors.
|
|
3
|
+
|
|
4
|
+
# flake8: noqa: F401
|
|
5
|
+
# pylint: disable=unused-import,too-few-public-methods
|
|
6
|
+
|
|
7
|
+
"""IOSTream extensions.
|
|
8
|
+
|
|
9
|
+
Let's keep the redis and websockets imports optional,
|
|
10
|
+
and have them in the optional requirements in the package.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from .models import (
|
|
16
|
+
AudioContent,
|
|
17
|
+
AudioMediaContent,
|
|
18
|
+
FileContent,
|
|
19
|
+
FileMediaContent,
|
|
20
|
+
ImageContent,
|
|
21
|
+
ImageMediaContent,
|
|
22
|
+
ImageUrlMediaContent,
|
|
23
|
+
MediaContent,
|
|
24
|
+
PrintMessage,
|
|
25
|
+
TextMediaContent,
|
|
26
|
+
UserInputData,
|
|
27
|
+
UserInputRequest,
|
|
28
|
+
UserResponse,
|
|
29
|
+
VideoContent,
|
|
30
|
+
VideoMediaContent,
|
|
31
|
+
)
|
|
32
|
+
from .structured import StructuredIOStream
|
|
33
|
+
from .utils import MediaType, MessageType
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
from .redis import RedisIOStream # type: ignore[no-redef,unused-ignore]
|
|
37
|
+
except ImportError: # pragma: no cover
|
|
38
|
+
|
|
39
|
+
class RedisIOStream: # type: ignore[no-redef,unused-ignore]
|
|
40
|
+
"""Dummy class for RedisIOStream."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
43
|
+
"""Initialize the RedisIOStream.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
args : tuple
|
|
48
|
+
Positional arguments.
|
|
49
|
+
kwargs : dict
|
|
50
|
+
Keyword arguments.
|
|
51
|
+
"""
|
|
52
|
+
raise ImportError(
|
|
53
|
+
"RedisIOStream is not available. "
|
|
54
|
+
"Please install the required package."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
from .ws import (
|
|
60
|
+
AsyncWebsocketsIOStream, # type: ignore[no-redef,unused-ignore]
|
|
61
|
+
)
|
|
62
|
+
except ImportError: # pragma: no cover
|
|
63
|
+
|
|
64
|
+
class AsyncWebsocketsIOStream: # type: ignore[no-redef,unused-ignore]
|
|
65
|
+
"""Dummy class for AsyncWebsocketsIOStream just for the linters."""
|
|
66
|
+
|
|
67
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
68
|
+
"""Initialize the AsyncWebsocketsIOStream.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
args : tuple
|
|
73
|
+
Positional arguments.
|
|
74
|
+
kwargs : dict
|
|
75
|
+
Keyword arguments.
|
|
76
|
+
"""
|
|
77
|
+
raise ImportError(
|
|
78
|
+
"AsyncWebsocketsIOStream is not available. "
|
|
79
|
+
"Please install the required package."
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
from .mqtt import MqttIOStream # type: ignore[no-redef,unused-ignore]
|
|
85
|
+
except ImportError: # pragma: no cover
|
|
86
|
+
|
|
87
|
+
class MqttIOStream: # type: ignore[no-redef,unused-ignore]
|
|
88
|
+
"""Dummy class for MqttIOStream."""
|
|
89
|
+
|
|
90
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
91
|
+
"""Initialize the MqttIOStream.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
args : tuple
|
|
96
|
+
Positional arguments.
|
|
97
|
+
kwargs : dict
|
|
98
|
+
Keyword arguments.
|
|
99
|
+
"""
|
|
100
|
+
raise ImportError(
|
|
101
|
+
"MqttIOStream is not available. "
|
|
102
|
+
"Please install the required package."
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
__all__ = [
|
|
107
|
+
"AsyncWebsocketsIOStream",
|
|
108
|
+
"StructuredIOStream",
|
|
109
|
+
"RedisIOStream",
|
|
110
|
+
"MqttIOStream",
|
|
111
|
+
"UserInputData",
|
|
112
|
+
"UserResponse",
|
|
113
|
+
"UserInputRequest",
|
|
114
|
+
"PrintMessage",
|
|
115
|
+
"MessageType",
|
|
116
|
+
"MediaType",
|
|
117
|
+
"MediaContent",
|
|
118
|
+
"TextMediaContent",
|
|
119
|
+
"ImageMediaContent",
|
|
120
|
+
"ImageUrlMediaContent",
|
|
121
|
+
"ImageContent",
|
|
122
|
+
"FileMediaContent",
|
|
123
|
+
"FileContent",
|
|
124
|
+
"AudioMediaContent",
|
|
125
|
+
"AudioContent",
|
|
126
|
+
"VideoMediaContent",
|
|
127
|
+
"VideoContent",
|
|
128
|
+
]
|