waldiez 0.5.6__py3-none-any.whl → 0.5.8__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 (116) hide show
  1. waldiez/_version.py +1 -1
  2. waldiez/cli.py +17 -2
  3. waldiez/exporter.py +1 -1
  4. waldiez/exporting/agent/code_execution.py +8 -1
  5. waldiez/exporting/agent/exporter.py +2 -1
  6. waldiez/exporting/agent/extras/captain_agent_extras.py +1 -0
  7. waldiez/exporting/agent/extras/doc_agent_extras.py +2 -3
  8. waldiez/exporting/agent/extras/group_manager_agent_extas.py +1 -0
  9. waldiez/exporting/agent/extras/handoffs/after_work.py +4 -4
  10. waldiez/exporting/agent/extras/handoffs/target.py +3 -0
  11. waldiez/exporting/agent/extras/rag/chroma_extras.py +0 -4
  12. waldiez/exporting/agent/extras/rag/mongo_extras.py +0 -1
  13. waldiez/exporting/agent/extras/rag/pgvector_extras.py +0 -2
  14. waldiez/exporting/agent/extras/rag/qdrant_extras.py +0 -3
  15. waldiez/exporting/agent/extras/rag/vector_db_extras.py +3 -2
  16. waldiez/exporting/agent/factory.py +11 -11
  17. waldiez/exporting/agent/processor.py +3 -2
  18. waldiez/exporting/chats/exporter.py +2 -2
  19. waldiez/exporting/chats/factory.py +5 -5
  20. waldiez/exporting/chats/processor.py +22 -1
  21. waldiez/exporting/chats/utils/common.py +45 -1
  22. waldiez/exporting/chats/utils/group.py +1 -1
  23. waldiez/exporting/chats/utils/sequential.py +3 -68
  24. waldiez/exporting/chats/utils/single.py +1 -38
  25. waldiez/exporting/core/context.py +39 -38
  26. waldiez/exporting/core/exporter.py +10 -10
  27. waldiez/exporting/core/exporters.py +36 -0
  28. waldiez/exporting/core/extras/base.py +2 -2
  29. waldiez/exporting/core/extras/chat_extras.py +4 -2
  30. waldiez/exporting/core/extras/path_resolver.py +6 -4
  31. waldiez/exporting/core/extras/serializer.py +1 -0
  32. waldiez/exporting/core/protocols.py +6 -0
  33. waldiez/exporting/core/result.py +8 -7
  34. waldiez/exporting/core/types.py +2 -2
  35. waldiez/exporting/core/utils/llm_config.py +2 -0
  36. waldiez/exporting/flow/execution_generator.py +54 -32
  37. waldiez/exporting/flow/factory.py +2 -2
  38. waldiez/exporting/flow/file_generator.py +8 -7
  39. waldiez/exporting/flow/merger.py +8 -7
  40. waldiez/exporting/flow/orchestrator.py +22 -8
  41. waldiez/exporting/flow/utils/__init__.py +2 -0
  42. waldiez/exporting/flow/utils/common.py +20 -11
  43. waldiez/exporting/flow/utils/importing.py +2 -1
  44. waldiez/exporting/flow/utils/logging.py +5 -2
  45. waldiez/exporting/models/exporter.py +2 -1
  46. waldiez/exporting/models/factory.py +6 -7
  47. waldiez/exporting/tools/exporter.py +7 -6
  48. waldiez/exporting/tools/factory.py +4 -5
  49. waldiez/exporting/tools/processor.py +9 -4
  50. waldiez/exporting/tools/registration.py +1 -0
  51. waldiez/io/_ws.py +2 -0
  52. waldiez/io/models/content/audio.py +1 -0
  53. waldiez/io/models/content/file.py +1 -0
  54. waldiez/io/models/content/image.py +1 -0
  55. waldiez/io/models/content/text.py +1 -0
  56. waldiez/io/models/content/video.py +1 -0
  57. waldiez/io/models/user_input.py +1 -0
  58. waldiez/io/models/user_response.py +1 -0
  59. waldiez/io/mqtt.py +6 -3
  60. waldiez/io/redis.py +7 -9
  61. waldiez/io/structured.py +8 -6
  62. waldiez/io/utils.py +11 -4
  63. waldiez/io/ws.py +4 -3
  64. waldiez/logger.py +11 -1
  65. waldiez/models/agents/agent/agent.py +1 -0
  66. waldiez/models/agents/agent/agent_data.py +2 -2
  67. waldiez/models/agents/agent/nested_chat.py +1 -4
  68. waldiez/models/agents/agent/termination_message.py +0 -7
  69. waldiez/models/agents/agent/update_system_message.py +2 -2
  70. waldiez/models/agents/doc_agent/doc_agent_data.py +33 -26
  71. waldiez/models/agents/doc_agent/rag_query_engine.py +1 -1
  72. waldiez/models/agents/extra_requirements.py +5 -5
  73. waldiez/models/agents/group_manager/group_manager.py +3 -7
  74. waldiez/models/agents/group_manager/speakers.py +0 -7
  75. waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +0 -2
  76. waldiez/models/agents/rag_user_proxy/rag_user_proxy_data.py +0 -2
  77. waldiez/models/agents/rag_user_proxy/retrieve_config.py +1 -17
  78. waldiez/models/agents/rag_user_proxy/vector_db_config.py +0 -5
  79. waldiez/models/chat/chat_data.py +0 -2
  80. waldiez/models/chat/chat_summary.py +5 -3
  81. waldiez/models/common/handoff.py +26 -18
  82. waldiez/models/common/naming.py +1 -0
  83. waldiez/models/flow/flow.py +9 -7
  84. waldiez/models/model/_llm.py +4 -2
  85. waldiez/models/model/extra_requirements.py +3 -3
  86. waldiez/models/model/model.py +5 -4
  87. waldiez/models/tool/extra_requirements.py +2 -2
  88. waldiez/models/tool/predefined/_google.py +7 -12
  89. waldiez/models/tool/predefined/_perplexity.py +13 -9
  90. waldiez/models/tool/predefined/_searxng.py +4 -1
  91. waldiez/models/tool/predefined/_tavily.py +0 -6
  92. waldiez/models/tool/predefined/_wikipedia.py +5 -1
  93. waldiez/models/tool/predefined/_youtube.py +0 -4
  94. waldiez/models/tool/tool.py +7 -7
  95. waldiez/models/tool/tool_data.py +39 -2
  96. waldiez/models/waldiez.py +29 -29
  97. waldiez/runner.py +18 -13
  98. waldiez/running/base_runner.py +96 -40
  99. waldiez/running/environment.py +2 -0
  100. waldiez/running/patch_io_stream.py +2 -0
  101. waldiez/running/post_run.py +3 -0
  102. waldiez/running/pre_run.py +1 -0
  103. waldiez/running/protocol.py +50 -48
  104. waldiez/running/run_results.py +2 -10
  105. waldiez/running/standard_runner.py +37 -13
  106. waldiez/running/timeline_processor.py +12 -1
  107. waldiez/running/utils.py +2 -0
  108. waldiez/utils/conflict_checker.py +1 -1
  109. waldiez/utils/version.py +1 -0
  110. {waldiez-0.5.6.dist-info → waldiez-0.5.8.dist-info}/METADATA +68 -65
  111. {waldiez-0.5.6.dist-info → waldiez-0.5.8.dist-info}/RECORD +115 -116
  112. waldiez/exporting/agent/extras/group/target.py +0 -178
  113. {waldiez-0.5.6.dist-info → waldiez-0.5.8.dist-info}/WHEEL +0 -0
  114. {waldiez-0.5.6.dist-info → waldiez-0.5.8.dist-info}/entry_points.txt +0 -0
  115. {waldiez-0.5.6.dist-info → waldiez-0.5.8.dist-info}/licenses/LICENSE +0 -0
  116. {waldiez-0.5.6.dist-info → waldiez-0.5.8.dist-info}/licenses/NOTICE.md +0 -0
waldiez/_version.py CHANGED
@@ -5,4 +5,4 @@
5
5
  This file is automatically generated by Hatchling.
6
6
  Do not edit this file directly.
7
7
  """
8
- __version__ = VERSION = "0.5.6"
8
+ __version__ = VERSION = "0.5.8"
waldiez/cli.py CHANGED
@@ -100,6 +100,19 @@ def run(
100
100
  False,
101
101
  help="Override the output file if it already exists.",
102
102
  ),
103
+ env_file: Optional[Path] = typer.Option( # noqa: B008
104
+ None,
105
+ "--env-file",
106
+ "-e",
107
+ help=(
108
+ "Path to a .env file containing additional environment variables. "
109
+ "These variables will be set before running the flow."
110
+ ),
111
+ file_okay=True,
112
+ dir_okay=False,
113
+ readable=True,
114
+ resolve_path=True,
115
+ ),
103
116
  ) -> None:
104
117
  """Run a Waldiez flow."""
105
118
  os.environ["AUTOGEN_USE_DOCKER"] = "0"
@@ -126,6 +139,7 @@ def run(
126
139
  structured, # structured_io
127
140
  False, # skip_mmd
128
141
  False, # skip_timeline
142
+ env_file,
129
143
  )
130
144
  else:
131
145
  runner.run(
@@ -134,6 +148,7 @@ def run(
134
148
  structured_io=structured,
135
149
  skip_mmd=False,
136
150
  skip_timeline=False,
151
+ dot_env=env_file,
137
152
  )
138
153
 
139
154
 
@@ -157,7 +172,7 @@ def convert(
157
172
  "Path to the output file. "
158
173
  "The file extension determines the output format: "
159
174
  "`.py` for Python script, `.ipynb` for Jupyter notebook."
160
- " If not provided, the output will be saved in the same directory as the input file."
175
+ " If not provided, the output (.py) will be saved in the same directory as the input file."
161
176
  " If the file already exists, it will not be overwritten unless --force is used."
162
177
  ),
163
178
  file_okay=True,
@@ -230,7 +245,7 @@ def _get_output_path(output: Optional[Path], force: bool) -> Optional[Path]:
230
245
  if output is not None and not output.parent.exists():
231
246
  output.parent.mkdir(parents=True)
232
247
  if output is not None and output.exists():
233
- if force is False:
248
+ if not force:
234
249
  LOG.error("Output file already exists.")
235
250
  raise typer.Exit(code=1)
236
251
  output.unlink()
waldiez/exporter.py CHANGED
@@ -97,7 +97,7 @@ class WaldiezExporter:
97
97
  if path.is_dir():
98
98
  raise IsADirectoryError(f"Output is a directory: {path}")
99
99
  if path.exists():
100
- if force is False:
100
+ if not force:
101
101
  raise FileExistsError(f"File already exists: {path}")
102
102
  path.unlink(missing_ok=True)
103
103
  path.parent.mkdir(parents=True, exist_ok=True)
@@ -5,6 +5,8 @@
5
5
 
6
6
  import json
7
7
 
8
+ from typing_extensions import Literal
9
+
8
10
  from waldiez.models import WaldiezAgent, WaldiezAgentCodeExecutionConfig
9
11
 
10
12
  from ..core import CodeExecutionConfig, ImportPosition, ImportStatement
@@ -57,6 +59,7 @@ class CodeExecutionProcessor:
57
59
  ),
58
60
  )
59
61
 
62
+ # noinspection PyMethodMayBeStatic
60
63
  def _get_executor_class_name(self, use_docker: bool) -> str:
61
64
  """Get the appropriate executor class name."""
62
65
  return (
@@ -66,9 +69,13 @@ class CodeExecutionProcessor:
66
69
  )
67
70
 
68
71
  def _build_executor_content(
69
- self, config: WaldiezAgentCodeExecutionConfig, use_docker: bool
72
+ self,
73
+ config: WaldiezAgentCodeExecutionConfig | Literal[False],
74
+ use_docker: bool,
70
75
  ) -> str:
71
76
  """Build the executor content string."""
77
+ if config is False:
78
+ return ""
72
79
  executor_class = self._get_executor_class_name(use_docker)
73
80
  lines = [f"{self.agent_name}_executor = {executor_class}("]
74
81
 
@@ -174,7 +174,7 @@ class AgentExporter(Exporter[StandardExtras]):
174
174
  model_names=self.model_names,
175
175
  initial_chats=self.initial_chats,
176
176
  group_chat_members=self.group_chat_members,
177
- serializer=(self.context.get_serializer().serialize),
177
+ serializer=self.context.get_serializer().serialize,
178
178
  )
179
179
 
180
180
  group_manager_extras = group_manager_processor.process(
@@ -376,6 +376,7 @@ class AgentExporter(Exporter[StandardExtras]):
376
376
 
377
377
 
378
378
  # pylint: disable=unused-argument
379
+ # noinspection PyUnusedLocal
379
380
  def fallback_args_resolver(agent: WaldiezAgent) -> list[str]:
380
381
  """Fallback resolver for agent arguments.
381
382
 
@@ -248,6 +248,7 @@ class CaptainAgentProcessor:
248
248
  return model
249
249
  return self._get_default_model(model_id)
250
250
 
251
+ # noinspection PyMethodMayBeStatic
251
252
  def _get_default_model(self, model_id: str) -> WaldiezModel:
252
253
  """Get the default model.
253
254
 
@@ -292,7 +292,6 @@ class DocAgentProcessor:
292
292
  if not isinstance(self.agent, WaldiezDocAgent): # pragma: no cover
293
293
  raise TypeError("Agent must be a WaldiezDocAgent instance.")
294
294
  query_engine = self.agent.get_query_engine()
295
- db_path_str = ""
296
295
  if query_engine.get_db_path():
297
296
  db_path_str = query_engine.get_db_path()
298
297
  else:
@@ -302,7 +301,7 @@ class DocAgentProcessor:
302
301
  db_path_str = str(chroma_dir)
303
302
  else:
304
303
  db_path_str = query_engine.get_db_path()
305
- if self.agent.data.reset_collection is True:
304
+ if self.agent.data.reset_collection:
306
305
  shutil.rmtree(db_path_str, ignore_errors=True)
307
306
  Path(db_path_str).mkdir(parents=True, exist_ok=True)
308
307
  return self.path_resolver.resolve(db_path_str)
@@ -333,7 +332,7 @@ class DocAgentProcessor:
333
332
  parsed_docs_path = str(Path.cwd() / parsed_docs_path)
334
333
  if not Path(parsed_docs_path).is_dir():
335
334
  Path(parsed_docs_path).mkdir(parents=True, exist_ok=True)
336
- if self.agent.data.reset_collection is True:
335
+ if self.agent.data.reset_collection:
337
336
  shutil.rmtree(parsed_docs_path, ignore_errors=True)
338
337
  Path(parsed_docs_path).mkdir(parents=True, exist_ok=True)
339
338
  return self.path_resolver.resolve(str(parsed_docs_path))
@@ -433,6 +433,7 @@ class GroupManagerProcessor:
433
433
 
434
434
  return lines
435
435
 
436
+ # noinspection PyMethodMayBeStatic
436
437
  def _should_check_for_after_work(self, pattern_class: str) -> bool:
437
438
  """Check if pattern should have after work configuration."""
438
439
  return pattern_class not in ["ManualPattern", "AutoPattern"]
@@ -17,10 +17,10 @@ class AfterWorkResult:
17
17
 
18
18
  Attributes
19
19
  ----------
20
- registration : str
21
- Code to register the after-work transition.
22
- after_agent : str
23
- Code to be placed after the agent definition.
20
+ content : str
21
+ The registration string for the after-work transition.
22
+ before_content : str
23
+ Any additional code that should be placed before the main content,
24
24
  extra_imports : set[str]
25
25
  Additional imports required for the after-work transition.
26
26
  """
@@ -87,6 +87,7 @@ class TransitionTargetProcessor:
87
87
  what = target.target_type
88
88
  result.extra_imports.add(f"from {where} import {what}")
89
89
 
90
+ # noinspection DuplicatedCode
90
91
  processors: dict[str, Callable[[WaldiezTransitionTarget], str]] = {
91
92
  "AgentTarget": self._process_agent_target,
92
93
  "RandomAgentTarget": self._process_random_agent_target,
@@ -152,6 +153,7 @@ class TransitionTargetProcessor:
152
153
  target_arg = f'nested_chat_config={{"chat_queue": {chat_name}}}'
153
154
  return f"NestedChatTarget({target_arg})"
154
155
 
156
+ # noinspection DuplicatedCode
155
157
  def _process_nested_chat_target_full(
156
158
  self, _: WaldiezTransitionTarget
157
159
  ) -> TargetResult:
@@ -178,6 +180,7 @@ class TransitionTargetProcessor:
178
180
  return result
179
181
 
180
182
  # pylint: disable=no-self-use
183
+ # noinspection PyMethodMayBeStatic
181
184
  def _process_simple_target(self, target: WaldiezTransitionTarget) -> str:
182
185
  """Process simple targets that don't need parameters.
183
186
 
@@ -15,15 +15,12 @@ def _get_chroma_client_string(agent: WaldiezRagUserProxy) -> tuple[str, str]:
15
15
  ----------
16
16
  agent : WaldiezRagUserProxy
17
17
  The agent.
18
- agent_name : str
19
- The agent's name.
20
18
 
21
19
  Returns
22
20
  -------
23
21
  tuple[str, str]
24
22
  The 'client' and what to import.
25
23
  """
26
- # TODO: also check `connection_url` (chroma in client-server mode)
27
24
  to_import = "import chromadb"
28
25
  client_str = "chromadb."
29
26
  if (
@@ -63,7 +60,6 @@ def _get_chroma_embedding_function_string(
63
60
  The 'embedding_function', the import and the custom embedding function.
64
61
  """
65
62
  to_import = ""
66
- embedding_function_arg = ""
67
63
  embedding_function_content = ""
68
64
  if not agent.retrieve_config.use_custom_embedding:
69
65
  to_import = (
@@ -25,7 +25,6 @@ def _get_mongodb_embedding_function_string(
25
25
  The 'embedding_function', the import and the custom_embedding_function.
26
26
  """
27
27
  to_import = ""
28
- embedding_function_arg = ""
29
28
  embedding_function_content = ""
30
29
  if not agent.retrieve_config.use_custom_embedding:
31
30
  to_import = "from sentence_transformers import SentenceTransformer"
@@ -45,10 +45,8 @@ def _get_pgvector_embedding_function_string(
45
45
  The 'embedding_function', the import and the custom_embedding_function.
46
46
  """
47
47
  to_import = ""
48
- embedding_function_arg = ""
49
48
  embedding_function_content = ""
50
49
  if agent.retrieve_config.use_custom_embedding:
51
- embedding_function_arg = f"custom_embedding_function_{agent_name}"
52
50
  embedding_function_content, embedding_function_arg = (
53
51
  agent.retrieve_config.get_custom_embedding_function(
54
52
  name_suffix=agent_name
@@ -15,8 +15,6 @@ def _get_qdrant_client_string(agent: WaldiezRagUserProxy) -> tuple[str, str]:
15
15
  ----------
16
16
  agent : WaldiezRagUserProxy
17
17
  The agent.
18
- agent_name : str
19
- The agent's name.
20
18
 
21
19
  Returns
22
20
  -------
@@ -62,7 +60,6 @@ def _get_qdrant_embedding_function_string(
62
60
  and the custom_embedding_function if used.
63
61
  """
64
62
  to_import = ""
65
- embedding_function_arg = ""
66
63
  embedding_function_content = ""
67
64
  vector_db_model = agent.retrieve_config.db_config.model
68
65
  if not agent.retrieve_config.use_custom_embedding:
@@ -48,8 +48,9 @@ def get_vector_db_extras(
48
48
 
49
49
  Returns
50
50
  -------
51
- tuple[str, str, Set[str]]
52
- The content before the arg if any, the arg and the related imports.
51
+ VectorDBExtras
52
+ The vector db extras containing the before content, vector db arg,
53
+ and imports.
53
54
  """
54
55
  before = ""
55
56
  imports: set[str] = set()
@@ -5,7 +5,7 @@
5
5
  """Factory for creating agent exporter."""
6
6
 
7
7
  from pathlib import Path
8
- from typing import Any, Callable, Optional, Union
8
+ from typing import Any, Callable
9
9
 
10
10
  from waldiez.models import (
11
11
  WaldiezAgent,
@@ -30,11 +30,11 @@ def create_agent_exporter(
30
30
  initial_chats: list[WaldiezAgentConnection],
31
31
  is_async: bool = False,
32
32
  for_notebook: bool = False,
33
- cache_seed: Optional[int] = None,
34
- group_chat_members: Optional[list[WaldiezAgent]] = None,
35
- arguments_resolver: Optional[Callable[[WaldiezAgent], list[str]]] = None,
36
- output_dir: Optional[Union[str, Path]] = None,
37
- context: Optional[ExporterContext] = None,
33
+ cache_seed: int | None = None,
34
+ group_chat_members: list[WaldiezAgent] | None = None,
35
+ arguments_resolver: Callable[[WaldiezAgent], list[str]] | None = None,
36
+ output_dir: str | Path | None = None,
37
+ context: ExporterContext | None = None,
38
38
  **kwargs: Any,
39
39
  ) -> AgentExporter:
40
40
  """Create an agent exporter.
@@ -57,15 +57,15 @@ def create_agent_exporter(
57
57
  Whether exporting for notebook, by default False
58
58
  cache_seed : Optional[int], optional
59
59
  Cache seed if any, by default None
60
- initial_chats : Optional[list[WaldiezAgentConnection]], optional
60
+ initial_chats : list[WaldiezAgentConnection]
61
61
  Initial chats for group managers, by default None
62
- group_chat_members : Optional[list[WaldiezAgent]], optional
62
+ group_chat_members : list[WaldiezAgent], optional
63
63
  Group chat members if group manager, by default None
64
- arguments_resolver : Optional[Callable], optional
64
+ arguments_resolver : Callable, optional
65
65
  Function to resolve additional arguments, by default None
66
- output_dir : Optional[Union[str, Path]], optional
66
+ output_dir : str | Path | None, optional
67
67
  Output directory for generated files, by default None
68
- context : Optional[ExporterContext], optional
68
+ context : ExporterContext | None, optional
69
69
  Exporter context with dependencies, by default None
70
70
  **kwargs : Any
71
71
  Additional keyword arguments.
@@ -53,8 +53,8 @@ class AgentProcessor:
53
53
 
54
54
  Returns
55
55
  -------
56
- str
57
- The generated agent definition string.
56
+ AgentProcessingResult
57
+ The result containing the agent definition string.
58
58
  """
59
59
  if (
60
60
  isinstance(self.extras, GroupManagerExtras)
@@ -226,6 +226,7 @@ class AgentProcessor:
226
226
  )
227
227
  return f" default_auto_reply={default_auto_reply},\n"
228
228
 
229
+ # noinspection PyMethodMayBeStatic
229
230
  def add_extra_args(self, agent_str: str, extra_args: str) -> str:
230
231
  """Add extra agent args.
231
232
 
@@ -43,9 +43,9 @@ class ChatsExporter(Exporter[ChatExtras]):
43
43
  Mapping of chat IDs to their names.
44
44
  main_chats : list[WaldiezAgentConnection]
45
45
  Main chats that are connections between agents.
46
- root_group_manager : Optional[WaldiezGroupManager]
46
+ root_group_manager : WaldiezGroupManager | None
47
47
  The root group manager for managing chat groups, if any.
48
- context : Optional[ExporterContext], optional
48
+ context : ExporterContext | None, optional
49
49
  Exporter context with dependencies, by default None
50
50
  **kwargs : Any
51
51
  Additional keyword arguments for the exporter.
@@ -2,7 +2,7 @@
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
3
  """Factory function for creating a ChatsExporter instance."""
4
4
 
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
 
7
7
  from waldiez.models import (
8
8
  WaldiezAgent,
@@ -21,8 +21,8 @@ def create_chats_exporter(
21
21
  all_chats: list[WaldiezChat],
22
22
  chat_names: dict[str, str],
23
23
  main_chats: list[WaldiezAgentConnection],
24
- root_group_manager: Optional[WaldiezGroupManager] = None,
25
- context: Optional[ExporterContext] = None,
24
+ root_group_manager: WaldiezGroupManager | None = None,
25
+ context: ExporterContext | None = None,
26
26
  **kwargs: Any,
27
27
  ) -> ChatsExporter:
28
28
  """Create a chats exporter.
@@ -39,9 +39,9 @@ def create_chats_exporter(
39
39
  Mapping of chat IDs to their names.
40
40
  main_chats : list[WaldiezAgentConnection]
41
41
  Main chats that are connections between agents.
42
- root_group_manager : Optional[WaldiezGroupManager], optional
42
+ root_group_manager : WaldiezGroupManager | None, optional
43
43
  The root group manager for managing chat groups, if any.
44
- context : Optional[ExporterContext], optional
44
+ context : ExporterContext | None, optional
45
45
  Exporter context with dependencies, by default None
46
46
  **kwargs : Any
47
47
  Additional keyword arguments for the exporter.
@@ -39,6 +39,7 @@ class ChatParams:
39
39
 
40
40
 
41
41
  # pylint: disable=too-many-arguments,too-many-positional-arguments
42
+ # noinspection PyTypeChecker
42
43
  class ChatsProcessor:
43
44
  """Processor for chats export."""
44
45
 
@@ -49,7 +50,7 @@ class ChatsProcessor:
49
50
  all_chats: list[WaldiezChat],
50
51
  chat_names: dict[str, str],
51
52
  main_chats: list[WaldiezAgentConnection],
52
- root_group_manager: Optional[WaldiezGroupManager],
53
+ root_group_manager: WaldiezGroupManager | None,
53
54
  for_notebook: bool,
54
55
  is_async: bool,
55
56
  cache_seed: Optional[int],
@@ -60,6 +61,26 @@ class ChatsProcessor:
60
61
 
61
62
  Parameters
62
63
  ----------
64
+ all_agents : list[WaldiezAgent]
65
+ All agents involved in the chats.
66
+ agent_names : dict[str, str]
67
+ Mapping of agent IDs to their names.
68
+ all_chats : list[WaldiezChat]
69
+ All chats to be exported.
70
+ chat_names : dict[str, str]
71
+ Mapping of chat IDs to their names.
72
+ main_chats : list[WaldiezAgentConnection]
73
+ Main chats that are connections between agents.
74
+ root_group_manager : WaldiezGroupManager | None
75
+ The root group manager for managing chat groups, if any.
76
+ for_notebook : bool
77
+ Whether the export is for a notebook.
78
+ is_async : bool
79
+ Whether the chat is asynchronous.
80
+ cache_seed : int | None
81
+ The cache seed for the export, if any.
82
+ serializer : Serializer
83
+ The serializer to use for escaping quotes in strings.
63
84
  extras : ChatExtras
64
85
  The structured extras for the chats export.
65
86
  """
@@ -1,5 +1,7 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=line-too-long
4
+ # flake8: noqa: E501
3
5
  """Common utilities for exporting chats."""
4
6
 
5
7
  import json
@@ -99,14 +101,56 @@ def get_event_handler_string(
99
101
  f"{tab} should_continue = False\n"
100
102
  f"{tab} if not should_continue:\n"
101
103
  f"{tab} break\n"
104
+ )
105
+ content += get_result_dicts_string(tab, is_async)
106
+ content += (
102
107
  f"{tab}else:\n"
103
108
  f"{tab} if not isinstance(results, list):\n"
104
109
  f"{tab} results = [results]\n"
105
- f"{tab} for result in results:\n"
110
+ f"{tab} for index, result in enumerate(results):\n"
106
111
  )
107
112
  if is_async:
108
113
  content += f"{tab} await result.process()\n"
109
114
  else:
110
115
  content += f"{tab} result.process()\n"
116
+ content += get_result_dicts_string(tab, is_async)
111
117
 
112
118
  return content
119
+
120
+
121
+ def get_result_dicts_string(tab: str, is_async: bool) -> str:
122
+ """Get the result dicts string.
123
+
124
+ Parameters
125
+ ----------
126
+ tab : str
127
+ The space string to use for indentation.
128
+ is_async : bool
129
+ Whether the function is asynchronous.
130
+
131
+ Returns
132
+ -------
133
+ str
134
+ The result dicts string.
135
+ """
136
+ space = f"{tab} "
137
+ flow_content = f"{space}result_dict = {{\n"
138
+ flow_content += f"{space} 'index': index,\n"
139
+ if is_async:
140
+ flow_content += f"{space} 'messages': await result.messages,\n"
141
+ flow_content += f"{space} 'summary': await result.summary,\n"
142
+ flow_content += f"{space} 'cost': (await result.cost).model_dump(mode='json', fallback=str) if await result.cost else None,\n"
143
+ flow_content += f"{space} 'context_variables': (await result.context_variables).model_dump(mode='json', fallback=str) if await result.context_variables else None,\n"
144
+ flow_content += (
145
+ f"{space} 'last_speaker': await result.last_speaker,\n"
146
+ )
147
+ else:
148
+ flow_content += f"{space} 'messages': result.messages,\n"
149
+ flow_content += f"{space} 'summary': result.summary,\n"
150
+ flow_content += f"{space} 'cost': result.cost.model_dump(mode='json', fallback=str) if result.cost else None,\n"
151
+ flow_content += f"{space} 'context_variables': result.context_variables.model_dump(mode='json', fallback=str) if result.context_variables else None,\n"
152
+ flow_content += f"{space} 'last_speaker': result.last_speaker,\n"
153
+ flow_content += f"{space} 'uuid': str(result.uuid),\n"
154
+ flow_content += f"{space}}}\n"
155
+ flow_content += f"{space}result_dicts.append(result_dict)\n"
156
+ return flow_content
@@ -43,7 +43,7 @@ def export_group_chats(
43
43
  tab = " " * tabs
44
44
  run_group_chat = "run_group_chat"
45
45
  if is_async:
46
- run_group_chat = "a_run_group_chat"
46
+ run_group_chat = "await a_run_group_chat"
47
47
  manager_name = agent_names[manager.id]
48
48
  pattern_name = f"{manager_name}_pattern"
49
49
  content = f"{tab}results = {run_group_chat}(" + "\n"
@@ -22,7 +22,7 @@ def export_sequential_chat(
22
22
  is_async: bool,
23
23
  skip_cache: bool,
24
24
  ) -> tuple[str, str]:
25
- r"""Get the chats content, when there are more than one chats in the flow.
25
+ """Get the chats content, when there are more than one chats in the flow.
26
26
 
27
27
  Parameters
28
28
  ----------
@@ -45,72 +45,6 @@ def export_sequential_chat(
45
45
  -------
46
46
  tuple[str, str]
47
47
  The main chats content and additional methods string if any.
48
-
49
- Example
50
- -------
51
- ```python
52
- >>> from waldiez.models import (
53
- ... WaldiezAgent,
54
- ... WaldiezChat,
55
- ... WaldiezChatData,
56
- ... WaldiezChatMessage,
57
- ... )
58
- >>> chat1 = WaldiezChat(
59
- ... id="wc-1",
60
- ... name="chat1",
61
- ... description="A chat between two agents.",
62
- ... tags=["chat", "chat1"],
63
- ... requirements=[],
64
- ... data=WaldiezChatData(
65
- ... sender="wa-1",
66
- ... recipient="wa-2",
67
- ... position=0,
68
- ... message=WaldiezChatMessage(
69
- ... type="string",
70
- ... content="Hello, how are you?",
71
- ... ),
72
- ... ),
73
- ... )
74
- >>> chat2 = WaldiezChat(
75
- ... id="wc-2",
76
- ... name="chat2",
77
- ... description="A chat between two agents.",
78
- ... tags=["chat", "chat2"],
79
- ... requirements=[],
80
- ... data=WaldiezChatData(
81
- ... sender="wa-2",
82
- ... recipient="wa-1",
83
- ... position=1,
84
- ... message=WaldiezChatMessage(
85
- ... type="string",
86
- ... content="I am good, thank you. How about you?",
87
- ... ),
88
- ... ),
89
- ... )
90
- >>> agent_names = {"wa-1": "agent1", "wa-2": "agent2"}
91
- >>> chat_names = {"wc-1": "chat1", "wc-2": "chat2"}
92
- >>> serializer = lambda x: x.replace('"', "\"").replace("\n", "\\n")
93
- >>> export_sequential_chat(
94
- ... main_chats=[(chat1, agent1, agent2), (chat2, agent2, agent1)],
95
- ... chat_names=chat_names,
96
- ... agent_names=agent_names,
97
- ... serializer=serializer,
98
- ... tabs=0,
99
- ... is_async=False,
100
- ... )
101
- results = initiate_chats([
102
- {
103
- "sender": agent1,
104
- "recipient": agent2,
105
- "message": "Hello, how are you?",
106
- },
107
- {
108
- "sender": agent2,
109
- "recipient": agent1,
110
- "message": "I am good, thank you. How about you?",
111
- },
112
- ])
113
- ```
114
48
  """
115
49
  tab = " " * tabs if tabs > 0 else ""
116
50
  content = "\n"
@@ -138,6 +72,7 @@ def export_sequential_chat(
138
72
  return content, additional_methods_string
139
73
 
140
74
 
75
+ # noinspection PyTypeChecker
141
76
  def _get_chat_dict_string(
142
77
  connection: WaldiezAgentConnection,
143
78
  is_first: bool,
@@ -230,7 +165,7 @@ def _get_chat_string_start(
230
165
  if not is_first:
231
166
  chat_string += "\n" + f'{tab} "sender": {agent_names[sender.id]},'
232
167
  chat_string += "\n" + f'{tab} "recipient": {agent_names[recipient.id]},'
233
- if skip_cache is False:
168
+ if not skip_cache:
234
169
  chat_string += "\n" + f'{tab} "cache": cache,'
235
170
  # additional_methods_string = ""
236
171
  for key, value in chat_args.items():