waldiez 0.2.2__py3-none-any.whl → 0.3.0__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 +179 -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 +25 -6
  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.0.dist-info}/METADATA +32 -26
  121. waldiez-0.3.0.dist-info/RECORD +125 -0
  122. waldiez-0.3.0.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.0.dist-info}/WHEEL +0 -0
  138. {waldiez-0.2.2.dist-info → waldiez-0.3.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,118 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Base exporter class to be inherited by all exporters."""
4
+
5
+ import abc
6
+ from typing import Any, List, Optional, Tuple, TypedDict, Union
7
+
8
+ from .agent_position import AgentPosition
9
+ from .export_position import ExportPosition
10
+ from .import_position import ImportPosition
11
+
12
+
13
+ # flake8: noqa E501
14
+ # pylint: disable=line-too-long
15
+ class ExporterReturnType(TypedDict):
16
+ """Exporter Return Type.
17
+
18
+ Attributes
19
+ ----------
20
+ content : Optional[str]
21
+ The exported content.
22
+ imports : Optional[List[Tuple[str, ImportPosition]]]
23
+ The additional imports required for the exported content.
24
+ environment_variables : Optional[List[Tuple[str, str]]]
25
+ The environment variables to set.
26
+ before_export : Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
27
+ The exported content before the main export and its position.
28
+ after_export : Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
29
+ The exported content after the main export and its position.
30
+ """
31
+
32
+ content: Optional[str]
33
+ imports: Optional[List[Tuple[str, ImportPosition]]]
34
+ environment_variables: Optional[List[Tuple[str, str]]]
35
+ before_export: Optional[
36
+ List[Tuple[str, Union[ExportPosition, AgentPosition]]]
37
+ ]
38
+ after_export: Optional[
39
+ List[Tuple[str, Union[ExportPosition, AgentPosition]]]
40
+ ]
41
+
42
+
43
+ class BaseExporter(abc.ABC):
44
+ """Base exporter."""
45
+
46
+ @abc.abstractmethod
47
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
48
+ """Initialize the exporter.
49
+
50
+ Parameters
51
+ ----------
52
+ *args : Any
53
+ The positional arguments.
54
+ **kwargs : Any
55
+ The keyword arguments.
56
+ """
57
+ raise NotImplementedError("Method not implemented.")
58
+
59
+ def get_environment_variables(self) -> Optional[List[Tuple[str, str]]]:
60
+ """Get the environment variables to set.
61
+
62
+ Returns
63
+ -------
64
+ Optional[Set[Tuple[str, str]]]
65
+ The environment variables to set if any.
66
+ """
67
+
68
+ def get_imports(self) -> Optional[List[Tuple[str, ImportPosition]]]:
69
+ """ "Generate the imports string for the exporter.
70
+
71
+ Returns
72
+ -------
73
+ Optional[Tuple[str, ImportPosition]]
74
+ The exported imports and the position of the imports.
75
+ """
76
+
77
+ def get_before_export(
78
+ self,
79
+ ) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
80
+ """Generate the content before the main export.
81
+
82
+ Returns
83
+ -------
84
+ Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
85
+ The exported content before the main export and its position.
86
+ """
87
+
88
+ def generate(
89
+ self,
90
+ ) -> Optional[str]:
91
+ """Generate the main export.
92
+
93
+ Returns
94
+ -------
95
+ str
96
+ The exported content.
97
+ """
98
+
99
+ def get_after_export(
100
+ self,
101
+ ) -> Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]:
102
+ """Generate the content after the main export.
103
+
104
+ Returns
105
+ -------
106
+ Optional[List[Tuple[str, Union[ExportPosition, AgentPosition]]]]
107
+ The exported content after the main export and its position.
108
+ """
109
+
110
+ @abc.abstractmethod
111
+ def export(self) -> ExporterReturnType:
112
+ """Export the content.
113
+
114
+ Returns
115
+ -------
116
+ ExporterReturnType
117
+ The exported content.
118
+ """
@@ -0,0 +1,48 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Export position enum."""
4
+
5
+ from dataclasses import dataclass
6
+ from enum import Enum
7
+
8
+
9
+ class ExportPositions(Enum):
10
+ """Export position.
11
+
12
+ Attributes
13
+ ----------
14
+ TOP : int
15
+ The top of the export (name, comments etc.)
16
+ IMPORTS : int
17
+ The imports section.
18
+ MODELS : int
19
+ The models section (define the llm_configs).
20
+ SKILLS : int
21
+ The skills section (generate the skill files, and import them)
22
+ AGENTS : int
23
+ The agents section.
24
+ CHATS : int
25
+ The chats section (e.g. agent.initiate_chat, or initiate_chats)
26
+ BOTTOM : int
27
+ The bottom part of the export (like the main function and calling it).
28
+ """
29
+
30
+ TOP = 0
31
+ IMPORTS = 1
32
+ SKILLS = 2
33
+ MODELS = 3
34
+ AGENTS = 4
35
+ CHATS = 5
36
+ BOTTOM = 6
37
+
38
+
39
+ @dataclass(order=True, frozen=True, slots=True)
40
+ class ExportPosition:
41
+ """Export position.
42
+
43
+ Optionally, the order can be provided
44
+ to sort the exported content.
45
+ """
46
+
47
+ position: ExportPositions
48
+ order: int = 0
@@ -0,0 +1,23 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Import position enum."""
4
+
5
+ from enum import Enum
6
+
7
+
8
+ class ImportPosition(Enum):
9
+ """Import position.
10
+
11
+ Attributes
12
+ ----------
13
+ BUILTINS : int
14
+ The top of the import (builtins)
15
+ THIRD_PARTY : int
16
+ The third party imports.
17
+ LOCAL : int
18
+ The local imports.
19
+ """
20
+
21
+ BUILTINS = 0
22
+ THIRD_PARTY = 1
23
+ LOCAL = 2
@@ -0,0 +1,134 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """The base exporter mixin."""
4
+
5
+ from typing import Any, Dict, Tuple
6
+
7
+ from .utils import (
8
+ CommentKey,
9
+ comment,
10
+ get_comment,
11
+ get_escaped_string,
12
+ get_item_string,
13
+ get_path_string,
14
+ get_valid_instance_name,
15
+ )
16
+
17
+
18
+ class ExporterMixin:
19
+ """Static methods to be used by the exporters."""
20
+
21
+ @staticmethod
22
+ def serializer(item: Any, tabs: int = 1) -> str:
23
+ """Get the string representation of an item.
24
+
25
+ Parameters
26
+ ----------
27
+ item : Any
28
+ The item.
29
+ tabs : int, optional
30
+ The number of tabs for indentation, by default 1.
31
+ Returns
32
+ -------
33
+ str
34
+ The string representation of the item.
35
+ """
36
+ return get_item_string(item=item, tabs=tabs)
37
+
38
+ @staticmethod
39
+ def path_resolver(path: str) -> str:
40
+ """Get the path string.
41
+
42
+ Parameters
43
+ ----------
44
+ path : str
45
+ The path.
46
+
47
+ Returns
48
+ -------
49
+ str
50
+ The path string.
51
+ """
52
+ return get_path_string(path)
53
+
54
+ @staticmethod
55
+ def string_escape(string: str) -> str:
56
+ """Get a string with escaped quotes and newlines.
57
+
58
+ Parameters
59
+ ----------
60
+ string : str
61
+ The original string.
62
+
63
+ Returns
64
+ -------
65
+ str
66
+ The escaped string.
67
+ """
68
+ return get_escaped_string(string)
69
+
70
+ @staticmethod
71
+ def get_comment(key: CommentKey, for_notebook: bool) -> str:
72
+ """Get the comment string.
73
+
74
+ Parameters
75
+ ----------
76
+ key : CommentKey
77
+ The comment key.
78
+ for_notebook : bool
79
+ Whether the comment is for a notebook or not.
80
+ Returns
81
+ -------
82
+ str
83
+ The comment string.
84
+ """
85
+ return get_comment(key=key, for_notebook=for_notebook)
86
+
87
+ @staticmethod
88
+ def comment(for_notebook: bool, hashtags: int = 1) -> str:
89
+ """Comment the text.
90
+
91
+ Parameters
92
+ ----------
93
+ for_notebook : bool
94
+ Whether the comment is for a notebook or not.
95
+ hashtags : int, optional
96
+ The number of hashtags (for notebooks), by default 1.
97
+
98
+ Returns
99
+ -------
100
+ str
101
+ The commented text.
102
+ """
103
+ return comment(for_notebook=for_notebook, hashtags=hashtags)
104
+
105
+ @staticmethod
106
+ def get_valid_instance_name(
107
+ instance: Tuple[str, str],
108
+ current_names: Dict[str, str],
109
+ prefix: str = "w",
110
+ max_length: int = 64,
111
+ ) -> Dict[str, str]:
112
+ """Get a valid instance name.
113
+
114
+ Parameters
115
+ ----------
116
+ instance : Tuple[str, str]
117
+ The instance id and possible name.
118
+ current_names : Dict[str, str]
119
+ The current names.
120
+ prefix : str, optional
121
+ The prefix for the instance name, by default "w".
122
+ max_length : int, optional
123
+ The maximum length of the variable name, by default 64
124
+ Returns
125
+ -------
126
+ Dict[str, str]
127
+ The updated dictionary of current names.
128
+ """
129
+ return get_valid_instance_name(
130
+ instance=instance,
131
+ current_names=current_names,
132
+ prefix=prefix,
133
+ max_length=max_length,
134
+ )
@@ -0,0 +1,18 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Generic utils to be used for exporting."""
4
+
5
+ from .comments import CommentKey, comment, get_comment
6
+ from .naming import get_escaped_string, get_valid_instance_name
7
+ from .path_check import get_path_string
8
+ from .to_string import get_item_string
9
+
10
+ __all__ = [
11
+ "CommentKey",
12
+ "comment",
13
+ "get_comment",
14
+ "get_escaped_string",
15
+ "get_item_string",
16
+ "get_path_string",
17
+ "get_valid_instance_name",
18
+ ]
@@ -1,38 +1,26 @@
1
- """Comment related string generation functions.
2
- Functions
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Utilities for comments.
3
4
  ---------
4
5
  comment
5
6
  Get a comment string.
6
7
  get_comment
7
8
  Get a comment string for some common keys (notebook headings).
8
- get_pylint_ignore_comment
9
- Get the pylint ignore comment string.
10
9
  """
11
10
 
12
- from typing import List, Optional
13
-
14
11
  from typing_extensions import Literal
15
12
 
16
- PYLINT_RULES = [
17
- "line-too-long",
18
- "unknown-option-value",
19
- "unused-argument",
20
- "unused-import",
21
- "invalid-name",
22
- "import-error",
23
- "inconsistent-quotes",
24
- "missing-function-docstring",
25
- "missing-param-doc",
26
- "missing-return-doc",
13
+ CommentKey = Literal[
14
+ "agents", "imports", "skills", "models", "nested", "run", "logging"
27
15
  ]
28
16
 
29
17
 
30
- def comment(notebook: bool, hashtags: int = 1) -> str:
18
+ def comment(for_notebook: bool, hashtags: int = 1) -> str:
31
19
  """Get the comment string.
32
20
 
33
21
  Parameters
34
22
  ----------
35
- notebook : bool
23
+ for_notebook : bool
36
24
  Whether the comment is for a notebook or not.
37
25
  hashtags : int, optional
38
26
  The number of hashtags (for notebooks), by default 1.
@@ -51,13 +39,13 @@ def comment(notebook: bool, hashtags: int = 1) -> str:
51
39
  ```
52
40
  """
53
41
  content = "# "
54
- if notebook:
42
+ if for_notebook:
55
43
  content += "#" * hashtags + " "
56
44
  return content
57
45
 
58
46
 
59
47
  def get_comment(
60
- key: Literal["agents", "skills", "models", "nested", "run", "logging"],
48
+ key: CommentKey,
61
49
  for_notebook: bool,
62
50
  ) -> str:
63
51
  """Get a comment string for some common keys.
@@ -66,7 +54,7 @@ def get_comment(
66
54
 
67
55
  Parameters
68
56
  ----------
69
- key : Literal["agents", "skills", "models", "nested", "run", "logging"]
57
+ key : "agents"|"imports"|"skills"|"models"|"nested"|"run"|"logging"
70
58
  The key.
71
59
  for_notebook : bool
72
60
  Whether the comment is for a notebook.
@@ -90,6 +78,8 @@ def get_comment(
90
78
  # pylint: disable=too-many-return-statements
91
79
  if key == "agents":
92
80
  return "\n" + comment(for_notebook, 2) + "Agents\n"
81
+ if key == "imports":
82
+ return "\n" + comment(for_notebook, 2) + "Imports\n"
93
83
  if key == "skills":
94
84
  return "\n" + comment(for_notebook, 2) + "Skills\n"
95
85
  if key == "models":
@@ -101,36 +91,3 @@ def get_comment(
101
91
  if key == "logging":
102
92
  return "\n" + comment(for_notebook, 2) + "Start Logging\n"
103
93
  return comment(for_notebook)
104
-
105
-
106
- def get_pylint_ignore_comment(
107
- notebook: bool, rules: Optional[List[str]] = None
108
- ) -> str:
109
- """Get the pylint ignore comment string.
110
-
111
- Parameters
112
- ----------
113
- notebook : bool
114
- Whether the comment is for a notebook.
115
- rules : Optional[List[str]], optional
116
- The pylint rules to ignore, by default None.
117
-
118
- Returns
119
- -------
120
- str
121
- The pylint ignore comment string.
122
-
123
- Example
124
- -------
125
- ```python
126
- >>> get_pylint_ignore_comment(True, ["invalid-name", "line-too-long"])
127
-
128
- # pylint: disable=invalid-name, line-too-long
129
- ```
130
- """
131
- if not rules:
132
- rules = PYLINT_RULES
133
- line = "# pylint: disable=" + ",".join(rules)
134
- if notebook is True:
135
- line = "\n" + line
136
- return line + "\n"
@@ -1,4 +1,6 @@
1
- """Naming related string generation functions.
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Utilities for naming.
2
4
 
3
5
  Functions
4
6
  ---------
@@ -17,6 +19,7 @@ from typing import Dict, Tuple
17
19
  def get_valid_python_variable_name(
18
20
  possible: str,
19
21
  prefix: str = "w",
22
+ max_length: int = 64,
20
23
  ) -> str:
21
24
  """Get a valid Python variable name from a possible name.
22
25
 
@@ -28,6 +31,9 @@ def get_valid_python_variable_name(
28
31
  prefix : str, optional
29
32
  The prefix to use if the name starts with a digit or special character
30
33
 
34
+ max_length : int, optional
35
+ The maximum length of the variable name.
36
+
31
37
  Returns
32
38
  -------
33
39
  str
@@ -56,7 +62,7 @@ def get_valid_python_variable_name(
56
62
  return match.group(0)
57
63
 
58
64
  possible = re.sub(r"->|=>|<-|<=|\W|^(?=\d)", replacement, possible)[
59
- :64
65
+ :max_length
60
66
  ].lower()
61
67
 
62
68
  if not possible:
@@ -72,6 +78,7 @@ def get_valid_instance_name(
72
78
  instance: Tuple[str, str],
73
79
  current_names: Dict[str, str],
74
80
  prefix: str = "w",
81
+ max_length: int = 64,
75
82
  ) -> Dict[str, str]:
76
83
  """Get a valid instance name.
77
84
 
@@ -89,17 +96,20 @@ def get_valid_instance_name(
89
96
  The prefix to use if the name starts with a digit,
90
97
  if the name is already in the current names,
91
98
  or if the name is already in the current names with an index suffix.
99
+ max_length : int, optional
100
+ The maximum length of the variable name.
92
101
 
93
102
  Returns
94
103
  -------
95
104
  Dict[str, str]
96
105
  The updated names.
97
106
  """
98
- instance_id, possible_name = instance
107
+ instance_id, possible_name = instance[0], instance[1][:max_length]
99
108
  if instance_id in current_names:
109
+ # already in the current names (it's id)
100
110
  return current_names
101
111
  new_names = current_names.copy()
102
- name = get_valid_python_variable_name(possible_name, prefix)
112
+ name = get_valid_python_variable_name(possible_name, prefix=prefix)
103
113
  if name in current_names.values():
104
114
  name = f"{prefix}_{name}"
105
115
  if name in current_names.values():
@@ -0,0 +1,68 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=broad-except
4
+ """Path check utility functions."""
5
+
6
+ from pathlib import Path
7
+ from typing import Optional, Union
8
+
9
+
10
+ def _check_local_path(string: str) -> Optional[Path]:
11
+ """Check if a string is a local path.
12
+
13
+ Parameters
14
+ ----------
15
+ string : str
16
+ The string to check.
17
+
18
+ Returns
19
+ -------
20
+ bool
21
+ True if the path is a local path.
22
+ """
23
+ try:
24
+ path = Path(string).resolve()
25
+ except BaseException: # pragma: no cover
26
+ return None
27
+ if path.exists():
28
+ return path
29
+ return None
30
+
31
+
32
+ def _get_raw_path_string(path: Union[str, Path]) -> str:
33
+ """Get the raw path string.
34
+
35
+ Parameters
36
+ ----------
37
+ path : Union[str, Path]
38
+ The string to check.
39
+
40
+ Returns
41
+ -------
42
+ str
43
+ The raw path string.
44
+ """
45
+ if not isinstance(path, str):
46
+ path = str(path)
47
+ while path.startswith('r"') and path.endswith('"'):
48
+ path = path[2:-1]
49
+ return f'r"{path}"'
50
+
51
+
52
+ def get_path_string(path: str) -> str:
53
+ """Get the path string.
54
+
55
+ Parameters
56
+ ----------
57
+ path : str
58
+ The string to check.
59
+
60
+ Returns
61
+ -------
62
+ str
63
+ The local path string.
64
+ """
65
+ resolved = _check_local_path(path)
66
+ if not resolved:
67
+ return _get_raw_path_string(path)
68
+ return _get_raw_path_string(resolved)
@@ -1,4 +1,6 @@
1
- """Function to convert an object to a formatted string with indentation.
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Utilities for converting items to strings.
2
4
 
3
5
  To be used with dicts and/or lists.
4
6
  """
@@ -6,13 +8,13 @@ To be used with dicts and/or lists.
6
8
  from typing import Any
7
9
 
8
10
 
9
- def get_object_string(obj: Any, tabs: int = 1) -> str:
10
- """Convert an object to a formatted string with given indentation.
11
+ def get_item_string(item: Any, tabs: int = 1) -> str:
12
+ """Convert an item to a formatted string with given indentation.
11
13
 
12
14
  Parameters
13
15
  ----------
14
- obj : Any
15
- The object to convert.
16
+ item : Any
17
+ The item to convert.
16
18
  tabs : int, optional
17
19
  The number of tabs, by default 1.
18
20
 
@@ -25,7 +27,7 @@ def get_object_string(obj: Any, tabs: int = 1) -> str:
25
27
  -------
26
28
  ```python
27
29
  >>> obj = {"a": 1, "b": [1, 2, 3]}
28
- >>> get_object_string(obj)
30
+ >>> get_item_string(obj)
29
31
  {
30
32
  "a": 1,
31
33
  "b": [
@@ -35,7 +37,7 @@ def get_object_string(obj: Any, tabs: int = 1) -> str:
35
37
  ]
36
38
  }
37
39
  >>> obj = {"a": 1, "b": [1, 2, 3], "c": {"d": 4}}
38
- >>> get_object_string(obj, 2)
40
+ >>> get_item_string(obj, 2)
39
41
  {
40
42
  "a": 1,
41
43
  "b": [
@@ -53,31 +55,30 @@ def get_object_string(obj: Any, tabs: int = 1) -> str:
53
55
  next_indent = (
54
56
  " " * 4 * (tabs + 1)
55
57
  ) # Number of spaces corresponding to the next tab level
56
- if isinstance(obj, dict):
58
+ if isinstance(item, dict):
57
59
  items = []
58
- for key, value in obj.items():
60
+ for key, value in item.items():
59
61
  items.append(
60
- f'{next_indent}"{key}": {get_object_string(value, tabs + 1)}'
62
+ f'{next_indent}"{key}": {get_item_string(value, tabs + 1)}'
61
63
  )
62
64
  # python3.10? f-string expression part cannot include a backslash
63
65
  items_string = ",\n".join(items)
64
66
  to_return = "\n" + items_string + "\n" + indent
65
67
  return f"{{{to_return}}}"
66
- # return f'{{\n{",\n".join(items)}\n{indent}}}'
67
- if isinstance(obj, list):
68
+ if isinstance(item, list):
68
69
  items = []
69
- for item in obj:
70
- items.append(f"{next_indent}{get_object_string(item, tabs + 1)}")
70
+ for sub_item in item:
71
+ items.append(f"{next_indent}{get_item_string(sub_item, tabs + 1)}")
71
72
  # python3.10? f-string expression part cannot include a backslash
72
73
  items_string = ",\n".join(items)
73
74
  to_return = "\n" + items_string + "\n" + indent
74
75
  return f"[{to_return}]"
75
76
 
76
- if isinstance(obj, str):
77
- if obj.startswith("r'") or obj.startswith('r"'):
78
- return obj
79
- return f'"{obj}"'
77
+ if isinstance(item, str):
78
+ if item.startswith("r'") or item.startswith('r"'):
79
+ return item
80
+ return f'"{item}"'
80
81
 
81
- if obj is None:
82
+ if item is None:
82
83
  return "None"
83
- return str(obj)
84
+ return str(item)
@@ -1,14 +1,7 @@
1
- """Chat related string generation functions.
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ """Export chats in a flow."""
2
4
 
3
- Functions
4
- ---------
5
- export_chats
6
- Get the chats content.
7
- export_nested_chat
8
- Get the 'register_nested_chats' content.
9
- """
5
+ from .chats_exporter import ChatsExporter
10
6
 
11
- from .chats import export_chats
12
- from .nested import export_nested_chat
13
-
14
- __all__ = ["export_chats", "export_nested_chat"]
7
+ __all__ = ["ChatsExporter"]