waldiez 0.2.2__py3-none-any.whl → 0.3.1__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.

Files changed (138) hide show
  1. waldiez/__init__.py +2 -0
  2. waldiez/__main__.py +2 -0
  3. waldiez/_version.py +3 -1
  4. waldiez/cli.py +13 -3
  5. waldiez/cli_extras.py +4 -3
  6. waldiez/conflict_checker.py +4 -3
  7. waldiez/exporter.py +28 -105
  8. waldiez/exporting/__init__.py +8 -9
  9. waldiez/exporting/agent/__init__.py +7 -0
  10. waldiez/exporting/agent/agent_exporter.py +279 -0
  11. waldiez/exporting/agent/utils/__init__.py +23 -0
  12. waldiez/exporting/agent/utils/agent_class_name.py +34 -0
  13. waldiez/exporting/agent/utils/agent_imports.py +50 -0
  14. waldiez/exporting/{agents → agent/utils}/code_execution.py +9 -11
  15. waldiez/exporting/{agents → agent/utils}/group_manager.py +47 -35
  16. waldiez/exporting/{agents → agent/utils}/rag_user/__init__.py +2 -0
  17. waldiez/exporting/{agents → agent/utils}/rag_user/chroma_utils.py +22 -17
  18. waldiez/exporting/{agents → agent/utils}/rag_user/mongo_utils.py +14 -10
  19. waldiez/exporting/{agents → agent/utils}/rag_user/pgvector_utils.py +12 -8
  20. waldiez/exporting/{agents → agent/utils}/rag_user/qdrant_utils.py +11 -8
  21. waldiez/exporting/{agents → agent/utils}/rag_user/rag_user.py +78 -55
  22. waldiez/exporting/{agents → agent/utils}/rag_user/vector_db.py +10 -8
  23. waldiez/exporting/agent/utils/swarm_agent.py +463 -0
  24. waldiez/exporting/{agents → agent/utils}/teachability.py +10 -6
  25. waldiez/exporting/{agents → agent/utils}/termination_message.py +7 -8
  26. waldiez/exporting/base/__init__.py +25 -0
  27. waldiez/exporting/base/agent_position.py +75 -0
  28. waldiez/exporting/base/base_exporter.py +118 -0
  29. waldiez/exporting/base/export_position.py +48 -0
  30. waldiez/exporting/base/import_position.py +23 -0
  31. waldiez/exporting/base/mixin.py +134 -0
  32. waldiez/exporting/base/utils/__init__.py +18 -0
  33. waldiez/exporting/{utils → base/utils}/comments.py +12 -55
  34. waldiez/exporting/{utils → base/utils}/naming.py +14 -4
  35. waldiez/exporting/base/utils/path_check.py +68 -0
  36. waldiez/exporting/{utils/object_string.py → base/utils/to_string.py} +21 -20
  37. waldiez/exporting/chats/__init__.py +5 -12
  38. waldiez/exporting/chats/chats_exporter.py +240 -0
  39. waldiez/exporting/chats/utils/__init__.py +15 -0
  40. waldiez/exporting/chats/utils/common.py +81 -0
  41. waldiez/exporting/chats/{nested.py → utils/nested.py} +125 -86
  42. waldiez/exporting/chats/utils/sequential.py +244 -0
  43. waldiez/exporting/chats/utils/single_chat.py +313 -0
  44. waldiez/exporting/chats/utils/swarm.py +207 -0
  45. waldiez/exporting/flow/__init__.py +5 -3
  46. waldiez/exporting/flow/flow_exporter.py +503 -0
  47. waldiez/exporting/flow/utils/__init__.py +47 -0
  48. waldiez/exporting/flow/utils/agent_utils.py +204 -0
  49. waldiez/exporting/flow/utils/chat_utils.py +71 -0
  50. waldiez/exporting/flow/utils/def_main.py +62 -0
  51. waldiez/exporting/flow/utils/flow_content.py +112 -0
  52. waldiez/exporting/flow/utils/flow_names.py +115 -0
  53. waldiez/exporting/flow/utils/importing_utils.py +182 -0
  54. waldiez/exporting/{utils → flow/utils}/logging_utils.py +34 -31
  55. waldiez/exporting/models/__init__.py +7 -242
  56. waldiez/exporting/models/models_exporter.py +192 -0
  57. waldiez/exporting/models/utils.py +166 -0
  58. waldiez/exporting/skills/__init__.py +7 -161
  59. waldiez/exporting/skills/skills_exporter.py +169 -0
  60. waldiez/exporting/skills/utils.py +281 -0
  61. waldiez/models/__init__.py +25 -7
  62. waldiez/models/agents/__init__.py +70 -0
  63. waldiez/models/agents/agent/__init__.py +11 -1
  64. waldiez/models/agents/agent/agent.py +9 -4
  65. waldiez/models/agents/agent/agent_data.py +3 -1
  66. waldiez/models/agents/agent/code_execution.py +2 -0
  67. waldiez/models/agents/agent/linked_skill.py +2 -0
  68. waldiez/models/agents/agent/nested_chat.py +2 -0
  69. waldiez/models/agents/agent/teachability.py +2 -0
  70. waldiez/models/agents/agent/termination_message.py +49 -13
  71. waldiez/models/agents/agents.py +15 -3
  72. waldiez/models/agents/assistant/__init__.py +2 -0
  73. waldiez/models/agents/assistant/assistant.py +2 -0
  74. waldiez/models/agents/assistant/assistant_data.py +2 -0
  75. waldiez/models/agents/group_manager/__init__.py +9 -1
  76. waldiez/models/agents/group_manager/group_manager.py +2 -0
  77. waldiez/models/agents/group_manager/group_manager_data.py +2 -0
  78. waldiez/models/agents/group_manager/speakers.py +49 -13
  79. waldiez/models/agents/rag_user/__init__.py +21 -4
  80. waldiez/models/agents/rag_user/rag_user.py +3 -1
  81. waldiez/models/agents/rag_user/rag_user_data.py +2 -0
  82. waldiez/models/agents/rag_user/retrieve_config.py +268 -17
  83. waldiez/models/agents/rag_user/vector_db_config.py +5 -3
  84. waldiez/models/agents/swarm_agent/__init__.py +49 -0
  85. waldiez/models/agents/swarm_agent/after_work.py +178 -0
  86. waldiez/models/agents/swarm_agent/on_condition.py +103 -0
  87. waldiez/models/agents/swarm_agent/on_condition_available.py +140 -0
  88. waldiez/models/agents/swarm_agent/on_condition_target.py +40 -0
  89. waldiez/models/agents/swarm_agent/swarm_agent.py +107 -0
  90. waldiez/models/agents/swarm_agent/swarm_agent_data.py +125 -0
  91. waldiez/models/agents/swarm_agent/update_system_message.py +144 -0
  92. waldiez/models/agents/user_proxy/__init__.py +2 -0
  93. waldiez/models/agents/user_proxy/user_proxy.py +2 -0
  94. waldiez/models/agents/user_proxy/user_proxy_data.py +2 -0
  95. waldiez/models/chat/__init__.py +21 -3
  96. waldiez/models/chat/chat.py +241 -7
  97. waldiez/models/chat/chat_data.py +192 -48
  98. waldiez/models/chat/chat_message.py +153 -144
  99. waldiez/models/chat/chat_nested.py +33 -53
  100. waldiez/models/chat/chat_summary.py +2 -0
  101. waldiez/models/common/__init__.py +6 -6
  102. waldiez/models/common/base.py +4 -1
  103. waldiez/models/common/method_utils.py +163 -83
  104. waldiez/models/flow/__init__.py +2 -0
  105. waldiez/models/flow/flow.py +176 -40
  106. waldiez/models/flow/flow_data.py +63 -2
  107. waldiez/models/flow/utils.py +172 -0
  108. waldiez/models/model/__init__.py +2 -0
  109. waldiez/models/model/model.py +30 -9
  110. waldiez/models/model/model_data.py +3 -1
  111. waldiez/models/skill/__init__.py +4 -1
  112. waldiez/models/skill/skill.py +30 -2
  113. waldiez/models/skill/skill_data.py +2 -0
  114. waldiez/models/waldiez.py +28 -4
  115. waldiez/runner.py +142 -228
  116. waldiez/running/__init__.py +33 -0
  117. waldiez/running/environment.py +83 -0
  118. waldiez/running/gen_seq_diagram.py +185 -0
  119. waldiez/running/running.py +300 -0
  120. {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/METADATA +35 -28
  121. waldiez-0.3.1.dist-info/RECORD +125 -0
  122. waldiez-0.3.1.dist-info/licenses/LICENSE +201 -0
  123. waldiez/exporting/agents/__init__.py +0 -5
  124. waldiez/exporting/agents/agent.py +0 -236
  125. waldiez/exporting/agents/agent_skills.py +0 -67
  126. waldiez/exporting/agents/llm_config.py +0 -53
  127. waldiez/exporting/chats/chats.py +0 -46
  128. waldiez/exporting/chats/helpers.py +0 -420
  129. waldiez/exporting/flow/def_main.py +0 -32
  130. waldiez/exporting/flow/flow.py +0 -189
  131. waldiez/exporting/utils/__init__.py +0 -36
  132. waldiez/exporting/utils/importing.py +0 -265
  133. waldiez/exporting/utils/method_utils.py +0 -35
  134. waldiez/exporting/utils/path_check.py +0 -51
  135. waldiez-0.2.2.dist-info/RECORD +0 -92
  136. waldiez-0.2.2.dist-info/licenses/LICENSE +0 -21
  137. {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/WHEEL +0 -0
  138. {waldiez-0.2.2.dist-info → waldiez-0.3.1.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Waldiez agents model."""
2
4
 
3
5
  from typing import Iterator, List
@@ -10,6 +12,7 @@ from .agent import WaldiezAgent
10
12
  from .assistant import WaldiezAssistant
11
13
  from .group_manager.group_manager import WaldiezGroupManager
12
14
  from .rag_user import WaldiezRagUser
15
+ from .swarm_agent import WaldiezSwarmAgent
13
16
  from .user_proxy import WaldiezUserProxy
14
17
 
15
18
 
@@ -23,7 +26,7 @@ class WaldiezAgents(WaldiezBase):
23
26
  assistants : List[WaldiezAssistant]
24
27
  Assistant agents.
25
28
  managers : List[WaldiezGroupManager]
26
- Group chat mangers.
29
+ Group chat managers.
27
30
  rag_users : List[WaldiezRagUser]
28
31
  RAG user agents.
29
32
  """
@@ -48,7 +51,7 @@ class WaldiezAgents(WaldiezBase):
48
51
  List[WaldiezGroupManager],
49
52
  Field(
50
53
  title="Managers.",
51
- description="Group chat mangers",
54
+ description="Group chat managers",
52
55
  default_factory=list,
53
56
  ),
54
57
  ]
@@ -60,6 +63,14 @@ class WaldiezAgents(WaldiezBase):
60
63
  default_factory=list,
61
64
  ),
62
65
  ]
66
+ swarm_agents: Annotated[
67
+ List[WaldiezSwarmAgent],
68
+ Field(
69
+ title="Swarm Agents.",
70
+ description="Swarm agents",
71
+ default_factory=list,
72
+ ),
73
+ ]
63
74
 
64
75
  @property
65
76
  def members(self) -> Iterator[WaldiezAgent]:
@@ -72,8 +83,9 @@ class WaldiezAgents(WaldiezBase):
72
83
  """
73
84
  yield from self.users
74
85
  yield from self.assistants
75
- yield from self.managers
76
86
  yield from self.rag_users
87
+ yield from self.swarm_agents
88
+ yield from self.managers
77
89
 
78
90
  @model_validator(mode="after")
79
91
  def validate_agents(self) -> Self:
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Assistant agent model."""
2
4
 
3
5
  from .assistant import WaldiezAssistant
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Assistant agent model."""
2
4
 
3
5
  from pydantic import Field
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Assistant agent data model."""
2
4
 
3
5
  from pydantic import Field
@@ -1,8 +1,13 @@
1
- """Group chat manger agent."""
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Group chat manager agent."""
2
4
 
3
5
  from .group_manager import WaldiezGroupManager
4
6
  from .group_manager_data import WaldiezGroupManagerData
5
7
  from .speakers import (
8
+ CUSTOM_SPEAKER_SELECTION,
9
+ CUSTOM_SPEAKER_SELECTION_ARGS,
10
+ CUSTOM_SPEAKER_SELECTION_TYPES,
6
11
  WaldiezGroupManagerSpeakers,
7
12
  WaldiezGroupManagerSpeakersSelectionMethod,
8
13
  WaldiezGroupManagerSpeakersSelectionMode,
@@ -10,6 +15,9 @@ from .speakers import (
10
15
  )
11
16
 
12
17
  __all__ = [
18
+ "CUSTOM_SPEAKER_SELECTION",
19
+ "CUSTOM_SPEAKER_SELECTION_ARGS",
20
+ "CUSTOM_SPEAKER_SELECTION_TYPES",
13
21
  "WaldiezGroupManager",
14
22
  "WaldiezGroupManagerData",
15
23
  "WaldiezGroupManagerSpeakers",
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Group chat manager agent."""
2
4
 
3
5
  from typing import List, Literal
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Group chat manager data."""
2
4
 
3
5
  from typing import Optional
@@ -1,12 +1,13 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Group chat speakers."""
2
4
 
3
- from typing import Dict, List, Optional, Union
5
+ from typing import Dict, List, Optional, Tuple, Union
4
6
 
5
- from pydantic import ConfigDict, Field, model_validator
6
- from pydantic.alias_generators import to_camel
7
+ from pydantic import Field, model_validator
7
8
  from typing_extensions import Annotated, Literal, Self
8
9
 
9
- from ...common import WaldiezBase, WaldiezMethodName, check_function
10
+ from ...common import WaldiezBase, check_function, generate_function
10
11
 
11
12
  WaldiezGroupManagerSpeakersSelectionMethod = Literal[
12
13
  "auto",
@@ -18,6 +19,13 @@ WaldiezGroupManagerSpeakersSelectionMethod = Literal[
18
19
  WaldiezGroupManagerSpeakersSelectionMode = Literal["repeat", "transition"]
19
20
  WaldiezGroupManagerSpeakersTransitionsType = Literal["allowed", "disallowed"]
20
21
 
22
+ CUSTOM_SPEAKER_SELECTION = "custom_speaker_selection"
23
+ CUSTOM_SPEAKER_SELECTION_ARGS = ["last_speaker", "groupchat"]
24
+ CUSTOM_SPEAKER_SELECTION_TYPES = (
25
+ ["ConversableAgent", "GroupChat"],
26
+ "Optional[Union[Agent, str]]",
27
+ )
28
+
21
29
 
22
30
  class WaldiezGroupManagerSpeakers(WaldiezBase):
23
31
  """Group chat speakers.
@@ -72,13 +80,6 @@ class WaldiezGroupManagerSpeakers(WaldiezBase):
72
80
  Validate the speakers config.
73
81
  """
74
82
 
75
- model_config = ConfigDict(
76
- extra="forbid",
77
- alias_generator=to_camel,
78
- populate_by_name=True,
79
- frozen=False,
80
- )
81
-
82
83
  selection_method: Annotated[
83
84
  WaldiezGroupManagerSpeakersSelectionMethod,
84
85
  Field(
@@ -181,6 +182,40 @@ class WaldiezGroupManagerSpeakers(WaldiezBase):
181
182
  """
182
183
  return self._custom_method_string
183
184
 
185
+ def get_custom_method_function(
186
+ self,
187
+ name_prefix: Optional[str] = None,
188
+ name_suffix: Optional[str] = None,
189
+ ) -> Tuple[str, str]:
190
+ """Get the custom method function.
191
+
192
+ Parameters
193
+ ----------
194
+ name_prefix : str
195
+ The function name prefix.
196
+ name_suffix : str
197
+ The function name suffix.
198
+
199
+ Returns
200
+ -------
201
+ Tuple[str, str]
202
+ The custom method function and the function name.
203
+ """
204
+ function_name = CUSTOM_SPEAKER_SELECTION
205
+ if name_prefix:
206
+ function_name = f"{name_prefix}_{function_name}"
207
+ if name_suffix:
208
+ function_name = f"{function_name}_{name_suffix}"
209
+ return (
210
+ generate_function(
211
+ function_name=function_name,
212
+ function_args=CUSTOM_SPEAKER_SELECTION_ARGS,
213
+ function_types=CUSTOM_SPEAKER_SELECTION_TYPES,
214
+ function_body=self.custom_method_string or "",
215
+ ),
216
+ function_name,
217
+ )
218
+
184
219
  @model_validator(mode="after")
185
220
  def validate_group_speakers_config(self) -> Self:
186
221
  """Validate the speakers config.
@@ -198,9 +233,10 @@ class WaldiezGroupManagerSpeakers(WaldiezBase):
198
233
  if self.selection_method == "custom":
199
234
  if not self.selection_custom_method:
200
235
  raise ValueError("No custom method provided.")
201
- function_name: WaldiezMethodName = "custom_speaker_selection"
202
236
  is_valid, error_or_body = check_function(
203
- self.selection_custom_method, function_name=function_name
237
+ code_string=self.selection_custom_method,
238
+ function_name=CUSTOM_SPEAKER_SELECTION,
239
+ function_args=CUSTOM_SPEAKER_SELECTION_ARGS,
204
240
  )
205
241
  if not is_valid or not error_or_body:
206
242
  # pylint: disable=inconsistent-quotes
@@ -1,11 +1,19 @@
1
- """RAG user agent.
2
- # pylint: disable=line-too-long
3
- It extends a user agent and has RAG related parameters.
4
- """
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """It extends a user agent and has RAG related parameters."""
5
4
 
6
5
  from .rag_user import WaldiezRagUser
7
6
  from .rag_user_data import WaldiezRagUserData
8
7
  from .retrieve_config import (
8
+ CUSTOM_EMBEDDING_FUNCTION,
9
+ CUSTOM_EMBEDDING_FUNCTION_ARGS,
10
+ CUSTOM_EMBEDDING_FUNCTION_TYPES,
11
+ CUSTOM_TEXT_SPLIT_FUNCTION,
12
+ CUSTOM_TEXT_SPLIT_FUNCTION_ARGS,
13
+ CUSTOM_TEXT_SPLIT_FUNCTION_TYPES,
14
+ CUSTOM_TOKEN_COUNT_FUNCTION,
15
+ CUSTOM_TOKEN_COUNT_FUNCTION_ARGS,
16
+ CUSTOM_TOKEN_COUNT_FUNCTION_TYPES,
9
17
  WaldiezRagUserChunkMode,
10
18
  WaldiezRagUserModels,
11
19
  WaldiezRagUserRetrieveConfig,
@@ -15,6 +23,15 @@ from .retrieve_config import (
15
23
  from .vector_db_config import WaldiezRagUserVectorDbConfig
16
24
 
17
25
  __all__ = [
26
+ "CUSTOM_EMBEDDING_FUNCTION",
27
+ "CUSTOM_EMBEDDING_FUNCTION_ARGS",
28
+ "CUSTOM_EMBEDDING_FUNCTION_TYPES",
29
+ "CUSTOM_TEXT_SPLIT_FUNCTION",
30
+ "CUSTOM_TEXT_SPLIT_FUNCTION_ARGS",
31
+ "CUSTOM_TEXT_SPLIT_FUNCTION_TYPES",
32
+ "CUSTOM_TOKEN_COUNT_FUNCTION",
33
+ "CUSTOM_TOKEN_COUNT_FUNCTION_ARGS",
34
+ "CUSTOM_TOKEN_COUNT_FUNCTION_TYPES",
18
35
  "WaldiezRagUser",
19
36
  "WaldiezRagUserData",
20
37
  "WaldiezRagUserModels",
@@ -1,5 +1,7 @@
1
- # pylint: disable=line-too-long
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
2
3
  """RAG user agent.
4
+
3
5
  It extends a user agent and has RAG related parameters (`retrieve_config`).
4
6
  """
5
7
 
@@ -1,3 +1,5 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """Waldiez RAG user agent data."""
2
4
 
3
5
  from pydantic import Field
@@ -1,12 +1,15 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
1
3
  """RAG user agent retrieve config."""
2
4
 
3
- from typing import Dict, List, Optional, Union
5
+ import os
6
+ from pathlib import Path
7
+ from typing import Dict, List, Optional, Tuple, Union
4
8
 
5
- from pydantic import ConfigDict, Field, model_validator
6
- from pydantic.alias_generators import to_camel
9
+ from pydantic import Field, model_validator
7
10
  from typing_extensions import Annotated, Literal, Self
8
11
 
9
- from ...common import WaldiezBase, WaldiezMethodName, check_function
12
+ from ...common import WaldiezBase, check_function, generate_function
10
13
  from .vector_db_config import WaldiezRagUserVectorDbConfig
11
14
 
12
15
  WaldiezRagUserTask = Literal["code", "qa", "default"]
@@ -19,6 +22,39 @@ WaldiezRagUserModels: Dict[WaldiezRagUserVectorDb, str] = {
19
22
  "qdrant": "BAAI/bge-small-en-v1.5",
20
23
  }
21
24
 
25
+ CUSTOM_EMBEDDING_FUNCTION = "custom_embedding_function"
26
+ CUSTOM_EMBEDDING_FUNCTION_ARGS: List[str] = []
27
+ CUSTOM_EMBEDDING_FUNCTION_TYPES: Tuple[List[str], str] = (
28
+ [],
29
+ "Callable[..., Any]",
30
+ )
31
+ CUSTOM_TOKEN_COUNT_FUNCTION = "custom_token_count_function" # nosec
32
+ CUSTOM_TOKEN_COUNT_FUNCTION_ARGS = ["text", "model"] # nosec
33
+ CUSTOM_TOKEN_COUNT_FUNCTION_TYPES = (
34
+ ["str", "str"],
35
+ "int",
36
+ )
37
+
38
+ CUSTOM_TEXT_SPLIT_FUNCTION = "custom_text_split_function"
39
+ CUSTOM_TEXT_SPLIT_FUNCTION_ARGS = [
40
+ "text",
41
+ "max_tokens",
42
+ "chunk_mode",
43
+ "must_break_at_empty_line",
44
+ "overlap",
45
+ ]
46
+ CUSTOM_TEXT_SPLIT_FUNCTION_TYPES = (
47
+ ["str", "int", "str", "bool", "int"],
48
+ "List[str]",
49
+ )
50
+ NOT_LOCAL = (
51
+ "http://",
52
+ "https://",
53
+ "ftp://",
54
+ "ftps://",
55
+ "sftp://",
56
+ )
57
+
22
58
 
23
59
  class WaldiezRagUserRetrieveConfig(WaldiezBase):
24
60
  """RAG user agent.
@@ -140,13 +176,6 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
140
176
  Validate the RAG user data.
141
177
  """
142
178
 
143
- model_config = ConfigDict(
144
- extra="forbid",
145
- alias_generator=to_camel,
146
- populate_by_name=True,
147
- frozen=False,
148
- )
149
-
150
179
  task: Annotated[
151
180
  WaldiezRagUserTask,
152
181
  Field(
@@ -502,6 +531,108 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
502
531
  """
503
532
  return self._text_split_function_string
504
533
 
534
+ def get_custom_embedding_function(
535
+ self,
536
+ name_prefix: Optional[str] = None,
537
+ name_suffix: Optional[str] = None,
538
+ ) -> Tuple[str, str]:
539
+ """Generate the custom embedding function.
540
+
541
+ Parameters
542
+ ----------
543
+ name_prefix : str
544
+ The function name prefix.
545
+ name_suffix : str
546
+ The function name suffix.
547
+
548
+ Returns
549
+ -------
550
+ Tuple[str, str]
551
+ The custom embedding function and the function name.
552
+ """
553
+ function_name = CUSTOM_EMBEDDING_FUNCTION
554
+ if name_prefix:
555
+ function_name = f"{name_prefix}_{function_name}"
556
+ if name_suffix:
557
+ function_name = f"{function_name}_{name_suffix}"
558
+ return (
559
+ generate_function(
560
+ function_name=function_name,
561
+ function_args=CUSTOM_EMBEDDING_FUNCTION_ARGS,
562
+ function_types=CUSTOM_EMBEDDING_FUNCTION_TYPES,
563
+ function_body=self.embedding_function_string or "",
564
+ ),
565
+ function_name,
566
+ )
567
+
568
+ def get_custom_token_count_function(
569
+ self,
570
+ name_prefix: Optional[str] = None,
571
+ name_suffix: Optional[str] = None,
572
+ ) -> Tuple[str, str]:
573
+ """Generate the custom token count function.
574
+
575
+ Parameters
576
+ ----------
577
+ name_prefix : str
578
+ The function name prefix.
579
+ name_suffix : str
580
+ The function name suffix.
581
+
582
+ Returns
583
+ -------
584
+ Tuple[str, str]
585
+ The custom token count function and the function name.
586
+ """
587
+ function_name = CUSTOM_TOKEN_COUNT_FUNCTION
588
+ if name_prefix:
589
+ function_name = f"{name_prefix}_{function_name}"
590
+ if name_suffix:
591
+ function_name = f"{function_name}_{name_suffix}"
592
+ return (
593
+ generate_function(
594
+ function_name=function_name,
595
+ function_args=CUSTOM_TOKEN_COUNT_FUNCTION_ARGS,
596
+ function_types=CUSTOM_TOKEN_COUNT_FUNCTION_TYPES,
597
+ function_body=self.token_count_function_string or "",
598
+ ),
599
+ function_name,
600
+ )
601
+
602
+ def get_custom_text_split_function(
603
+ self,
604
+ name_prefix: Optional[str] = None,
605
+ name_suffix: Optional[str] = None,
606
+ ) -> Tuple[str, str]:
607
+ """Generate the custom text split function.
608
+
609
+ Parameters
610
+ ----------
611
+ name_prefix : str
612
+ The function name prefix.
613
+ name_suffix : str
614
+ The function name suffix.
615
+
616
+ Returns
617
+ -------
618
+ Tuple[str, str]
619
+ The custom text split function and the function name.
620
+ """
621
+ function_name = CUSTOM_TEXT_SPLIT_FUNCTION
622
+ if name_prefix:
623
+ function_name = f"{name_prefix}_{function_name}"
624
+ if name_suffix:
625
+ function_name = f"{function_name}_{name_suffix}"
626
+ return (
627
+ generate_function(
628
+ function_name=function_name,
629
+ function_args=CUSTOM_TEXT_SPLIT_FUNCTION_ARGS,
630
+ function_types=CUSTOM_TEXT_SPLIT_FUNCTION_TYPES,
631
+ function_body=self.text_split_function_string or "",
632
+ ),
633
+ function_name,
634
+ )
635
+
505
636
  def validate_custom_embedding_function(self) -> None:
506
637
  """Validate the custom embedding function.
507
638
 
@@ -516,9 +647,10 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
516
647
  "The embedding_function is required "
517
648
  "if use_custom_embedding is True."
518
649
  )
519
- function_name: WaldiezMethodName = "custom_embedding_function"
520
650
  valid, error_or_content = check_function(
521
- self.embedding_function, function_name
651
+ code_string=self.embedding_function,
652
+ function_name=CUSTOM_EMBEDDING_FUNCTION,
653
+ function_args=CUSTOM_EMBEDDING_FUNCTION_ARGS,
522
654
  )
523
655
  if not valid:
524
656
  raise ValueError(error_or_content)
@@ -538,9 +670,10 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
538
670
  "The custom_token_count_function is required "
539
671
  "if use_custom_token_count is True."
540
672
  )
541
- function_name: WaldiezMethodName = "custom_token_count_function"
542
673
  valid, error_or_content = check_function(
543
- self.custom_token_count_function, function_name
674
+ code_string=self.custom_token_count_function,
675
+ function_name=CUSTOM_TOKEN_COUNT_FUNCTION,
676
+ function_args=CUSTOM_TOKEN_COUNT_FUNCTION_ARGS,
544
677
  )
545
678
  if not valid:
546
679
  raise ValueError(error_or_content)
@@ -560,14 +693,49 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
560
693
  "The custom_text_split_function is required "
561
694
  "if use_custom_text_split is True."
562
695
  )
563
- function_name: WaldiezMethodName = "custom_text_split_function"
564
696
  valid, error_or_content = check_function(
565
- self.custom_text_split_function, function_name
697
+ code_string=self.custom_text_split_function,
698
+ function_name=CUSTOM_TEXT_SPLIT_FUNCTION,
699
+ function_args=CUSTOM_TEXT_SPLIT_FUNCTION_ARGS,
566
700
  )
567
701
  if not valid:
568
702
  raise ValueError(error_or_content)
569
703
  self._text_split_function_string = error_or_content
570
704
 
705
+ def validate_docs_path(self) -> None:
706
+ """Validate the docs path.
707
+
708
+ Raises
709
+ ------
710
+ ValueError
711
+ If the validation fails.
712
+ """
713
+ if not self.docs_path:
714
+ return
715
+ # if urls or directories ok, if files they should resolve
716
+ doc_paths = (
717
+ [self.docs_path]
718
+ if isinstance(self.docs_path, str)
719
+ else self.docs_path
720
+ )
721
+ for index, path in enumerate(doc_paths):
722
+ is_remote, is_raw = is_remote_path(path)
723
+ if is_remote:
724
+ if not is_raw:
725
+ doc_paths[index] = f'r"{path}"'
726
+ continue
727
+ if path.startswith("file://"):
728
+ path = path[len("file://") :]
729
+ if path.startswith('r"file://"'):
730
+ path = path[len('r"file://"') :]
731
+ if string_represents_folder(path):
732
+ if not is_raw:
733
+ doc_paths[index] = f'r"{path}"'
734
+ continue
735
+ resolved = resolve_path(path, is_raw)
736
+ doc_paths[index] = resolved
737
+ self.docs_path = doc_paths
738
+
571
739
  @model_validator(mode="after")
572
740
  def validate_rag_user_data(self) -> Self:
573
741
  """Validate the RAG user data.
@@ -585,8 +753,91 @@ class WaldiezRagUserRetrieveConfig(WaldiezBase):
585
753
  self.validate_custom_embedding_function()
586
754
  self.validate_custom_token_count_function()
587
755
  self.validate_custom_text_split_function()
756
+ self.validate_docs_path()
588
757
  if not self.db_config.model:
589
758
  self.db_config.model = WaldiezRagUserModels[self.vector_db]
590
759
  if isinstance(self.n_results, int) and self.n_results < 1:
591
760
  self.n_results = None
592
761
  return self
762
+
763
+
764
+ def string_represents_folder(path: str) -> bool:
765
+ """Check if a string represents a folder.
766
+
767
+ Parameters
768
+ ----------
769
+ path : str
770
+ The string to check (does not need to exist).
771
+
772
+ Returns
773
+ -------
774
+ bool
775
+ True if the path is likely a folder, False if it's likely a file.
776
+ """
777
+ if path.endswith(os.path.sep):
778
+ return True
779
+ if os.path.isdir(path):
780
+ return True
781
+ return not os.path.splitext(path)[1]
782
+
783
+
784
+ def is_remote_path(path: str) -> Tuple[bool, bool]:
785
+ """Check if a path is a remote path.
786
+
787
+ Parameters
788
+ ----------
789
+ path : str
790
+ The path to check.
791
+
792
+ Returns
793
+ -------
794
+ Tuple[bool, bool]
795
+ If the path is a remote path and if it's a raw string.
796
+ """
797
+ is_raw = path.startswith(("r'", 'r"'))
798
+ for not_local in NOT_LOCAL:
799
+ if path.startswith((not_local, f'r"{not_local}"', f"r'{not_local}'")):
800
+ return True, is_raw
801
+ return False, is_raw
802
+
803
+
804
+ def resolve_path(path: str, is_raw: bool) -> str:
805
+ """Try to resolve a path.
806
+
807
+ Parameters
808
+ ----------
809
+ path : str
810
+ The path to resolve.
811
+ is_raw : bool
812
+ If the path is a raw string.
813
+ Returns
814
+ -------
815
+ Path
816
+ The resolved path.
817
+
818
+ Raises
819
+ ------
820
+ ValueError
821
+ If the path is not a valid local path.
822
+ """
823
+ # pylint: disable=broad-except
824
+ path_string = path
825
+ if is_raw:
826
+ path_string = path[2:-1]
827
+ if path_string.startswith(NOT_LOCAL):
828
+ return path
829
+ try:
830
+ resolved = Path(path_string).resolve()
831
+ except BaseException as error: # pragma: no cover
832
+ # check if 'r'... is needed
833
+ raw_string = f'r"{path}"'
834
+ try:
835
+ Path(raw_string).resolve()
836
+ except BaseException:
837
+ raise ValueError(
838
+ f"Path {path} is not a valid local path."
839
+ ) from error
840
+ return raw_string
841
+ if not resolved.exists():
842
+ raise ValueError(f"Path {path} does not exist.")
843
+ return f'r"{resolved}"'
@@ -1,7 +1,9 @@
1
- """The vector db config for the RAG user agent."""
2
-
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
3
  # flake8: noqa E501
4
4
 
5
+ """The vector db config for the RAG user agent."""
6
+
5
7
  from pathlib import Path
6
8
  from typing import Any, Dict, Optional
7
9
 
@@ -45,7 +47,7 @@ class WaldiezRagUserVectorDbConfig(WaldiezBase):
45
47
  """
46
48
 
47
49
  model_config = ConfigDict(
48
- extra="forbid",
50
+ extra="ignore",
49
51
  alias_generator=to_camel,
50
52
  populate_by_name=True,
51
53
  frozen=False,
@@ -0,0 +1,49 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Swarm Agent."""
4
+
5
+ from .after_work import (
6
+ CUSTOM_AFTER_WORK,
7
+ CUSTOM_AFTER_WORK_ARGS,
8
+ CUSTOM_AFTER_WORK_TYPES,
9
+ WaldiezSwarmAfterWork,
10
+ WaldiezSwarmAfterWorkOption,
11
+ WaldiezSwarmAfterWorkRecipientType,
12
+ )
13
+ from .on_condition import WaldiezSwarmOnCondition
14
+ from .on_condition_available import (
15
+ CUSTOM_ON_CONDITION_AVAILABLE,
16
+ CUSTOM_ON_CONDITION_AVAILABLE_ARGS,
17
+ CUSTOM_ON_CONDITION_AVAILABLE_TYPES,
18
+ WaldiezSwarmOnConditionAvailable,
19
+ )
20
+ from .on_condition_target import WaldiezSwarmOnConditionTarget
21
+ from .swarm_agent import WaldiezSwarmAgent
22
+ from .swarm_agent_data import WaldiezSwarmAgentData
23
+ from .update_system_message import (
24
+ CUSTOM_UPDATE_SYSTEM_MESSAGE,
25
+ CUSTOM_UPDATE_SYSTEM_MESSAGE_ARGS,
26
+ CUSTOM_UPDATE_SYSTEM_MESSAGE_TYPES,
27
+ WaldiezSwarmUpdateSystemMessage,
28
+ )
29
+
30
+ __all__ = [
31
+ "CUSTOM_AFTER_WORK",
32
+ "CUSTOM_AFTER_WORK_ARGS",
33
+ "CUSTOM_AFTER_WORK_TYPES",
34
+ "CUSTOM_ON_CONDITION_AVAILABLE",
35
+ "CUSTOM_ON_CONDITION_AVAILABLE_ARGS",
36
+ "CUSTOM_ON_CONDITION_AVAILABLE_TYPES",
37
+ "CUSTOM_UPDATE_SYSTEM_MESSAGE",
38
+ "CUSTOM_UPDATE_SYSTEM_MESSAGE_ARGS",
39
+ "CUSTOM_UPDATE_SYSTEM_MESSAGE_TYPES",
40
+ "WaldiezSwarmAfterWork",
41
+ "WaldiezSwarmAfterWorkOption",
42
+ "WaldiezSwarmAgent",
43
+ "WaldiezSwarmAgentData",
44
+ "WaldiezSwarmAfterWorkRecipientType",
45
+ "WaldiezSwarmOnCondition",
46
+ "WaldiezSwarmOnConditionTarget",
47
+ "WaldiezSwarmOnConditionAvailable",
48
+ "WaldiezSwarmUpdateSystemMessage",
49
+ ]