waldiez 0.5.2__py3-none-any.whl → 0.5.4__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 (79) hide show
  1. waldiez/_version.py +1 -1
  2. waldiez/cli.py +5 -27
  3. waldiez/exporter.py +0 -13
  4. waldiez/exporting/agent/exporter.py +38 -0
  5. waldiez/exporting/agent/extras/__init__.py +2 -0
  6. waldiez/exporting/agent/extras/doc_agent_extras.py +366 -0
  7. waldiez/exporting/agent/extras/group_member_extras.py +3 -2
  8. waldiez/exporting/agent/processor.py +113 -15
  9. waldiez/exporting/chats/processor.py +2 -21
  10. waldiez/exporting/chats/utils/common.py +66 -1
  11. waldiez/exporting/chats/utils/group.py +6 -3
  12. waldiez/exporting/chats/utils/nested.py +1 -1
  13. waldiez/exporting/chats/utils/sequential.py +25 -9
  14. waldiez/exporting/chats/utils/single.py +8 -6
  15. waldiez/exporting/core/context.py +0 -12
  16. waldiez/exporting/core/extras/agent_extras/standard_extras.py +3 -1
  17. waldiez/exporting/core/extras/base.py +20 -17
  18. waldiez/exporting/core/extras/path_resolver.py +39 -41
  19. waldiez/exporting/core/extras/serializer.py +16 -1
  20. waldiez/exporting/core/protocols.py +17 -0
  21. waldiez/exporting/core/types.py +6 -9
  22. waldiez/exporting/flow/execution_generator.py +56 -21
  23. waldiez/exporting/flow/exporter.py +1 -4
  24. waldiez/exporting/flow/factory.py +0 -9
  25. waldiez/exporting/flow/file_generator.py +6 -0
  26. waldiez/exporting/flow/orchestrator.py +27 -21
  27. waldiez/exporting/flow/utils/__init__.py +0 -2
  28. waldiez/exporting/flow/utils/common.py +15 -96
  29. waldiez/exporting/flow/utils/importing.py +4 -0
  30. waldiez/io/mqtt.py +33 -14
  31. waldiez/io/redis.py +18 -13
  32. waldiez/io/structured.py +9 -4
  33. waldiez/io/utils.py +32 -0
  34. waldiez/io/ws.py +8 -2
  35. waldiez/models/__init__.py +6 -0
  36. waldiez/models/agents/__init__.py +8 -0
  37. waldiez/models/agents/agent/agent.py +136 -38
  38. waldiez/models/agents/agent/agent_type.py +3 -2
  39. waldiez/models/agents/agents.py +10 -0
  40. waldiez/models/agents/doc_agent/__init__.py +13 -0
  41. waldiez/models/agents/doc_agent/doc_agent.py +126 -0
  42. waldiez/models/agents/doc_agent/doc_agent_data.py +149 -0
  43. waldiez/models/agents/doc_agent/rag_query_engine.py +127 -0
  44. waldiez/models/chat/chat_message.py +1 -1
  45. waldiez/models/flow/flow.py +13 -2
  46. waldiez/models/model/__init__.py +2 -2
  47. waldiez/models/model/_aws.py +75 -0
  48. waldiez/models/model/_llm.py +516 -0
  49. waldiez/models/model/_price.py +30 -0
  50. waldiez/models/model/model.py +45 -2
  51. waldiez/models/model/model_data.py +2 -83
  52. waldiez/models/tool/predefined/_duckduckgo.py +123 -0
  53. waldiez/models/tool/predefined/_google.py +31 -9
  54. waldiez/models/tool/predefined/_perplexity.py +161 -0
  55. waldiez/models/tool/predefined/_searxng.py +152 -0
  56. waldiez/models/tool/predefined/_tavily.py +46 -9
  57. waldiez/models/tool/predefined/_wikipedia.py +26 -6
  58. waldiez/models/tool/predefined/_youtube.py +36 -8
  59. waldiez/models/tool/predefined/registry.py +6 -0
  60. waldiez/models/waldiez.py +12 -0
  61. waldiez/runner.py +184 -382
  62. waldiez/running/__init__.py +2 -4
  63. waldiez/running/base_runner.py +136 -118
  64. waldiez/running/environment.py +61 -17
  65. waldiez/running/post_run.py +70 -14
  66. waldiez/running/pre_run.py +42 -0
  67. waldiez/running/protocol.py +42 -48
  68. waldiez/running/run_results.py +5 -5
  69. waldiez/running/standard_runner.py +429 -0
  70. waldiez/running/timeline_processor.py +1166 -0
  71. waldiez/utils/version.py +12 -1
  72. {waldiez-0.5.2.dist-info → waldiez-0.5.4.dist-info}/METADATA +61 -63
  73. {waldiez-0.5.2.dist-info → waldiez-0.5.4.dist-info}/RECORD +77 -66
  74. waldiez/running/import_runner.py +0 -424
  75. waldiez/running/subprocess_runner.py +0 -100
  76. {waldiez-0.5.2.dist-info → waldiez-0.5.4.dist-info}/WHEEL +0 -0
  77. {waldiez-0.5.2.dist-info → waldiez-0.5.4.dist-info}/entry_points.txt +0 -0
  78. {waldiez-0.5.2.dist-info → waldiez-0.5.4.dist-info}/licenses/LICENSE +0 -0
  79. {waldiez-0.5.2.dist-info → waldiez-0.5.4.dist-info}/licenses/NOTICE.md +0 -0
@@ -1,8 +1,11 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
- # pylint: disable=import-outside-toplevel,reimported
3
+ # pylint: disable=import-outside-toplevel,reimported,line-too-long
4
+ # flake8: noqa: E501, F401
5
+ # pyright: reportUnusedImport=false
4
6
  """Environment related utilities."""
5
7
 
8
+ import importlib
6
9
  import os
7
10
  import site
8
11
  import sys
@@ -53,12 +56,14 @@ def refresh_environment() -> None:
53
56
  # default code execution with docker
54
57
  # temp (until we handle/detect docker setup)
55
58
  os.environ["AUTOGEN_USE_DOCKER"] = "0"
59
+ os.environ["ANONYMIZED_TELEMETRY"] = "False"
56
60
  try_handle_the_np_thing()
57
61
  reload_autogen()
62
+ reload_chroma_if_needed()
58
63
 
59
64
 
60
65
  # pylint: disable=too-complex,too-many-try-statements,unused-import
61
- def reload_autogen() -> None: # noqa: C901
66
+ def reload_autogen() -> None: # noqa: C901 # pragma: no cover
62
67
  """Reload the autogen package.
63
68
 
64
69
  Try to avoid "please install package x" errors
@@ -86,31 +91,38 @@ def reload_autogen() -> None: # noqa: C901
86
91
  default_io_stream = IOStream.get_default()
87
92
  except (ImportError, AttributeError):
88
93
  pass
89
-
94
+ autogen_modules = sorted(
95
+ [
96
+ name
97
+ for name in sys.modules
98
+ if name.startswith("autogen.")
99
+ and not name.startswith("autogen.io")
100
+ and not name.startswith("autogen.tools")
101
+ ],
102
+ key=len,
103
+ reverse=True, # Longer names (deeper modules) first
104
+ )
90
105
  try:
91
106
  # Remove autogen modules in reverse dependency order
92
- autogen_modules = sorted(
93
- [
94
- name
95
- for name in sys.modules
96
- if name.startswith("autogen.")
97
- and not name.startswith("autogen.io")
98
- and not name.startswith("autogen.tools")
99
- ],
100
- key=len,
101
- reverse=True, # Longer names (deeper modules) first
102
- )
103
107
  for mod_name in autogen_modules:
104
108
  if mod_name in sys.modules:
105
109
  del sys.modules[mod_name]
106
110
 
107
111
  if "autogen" in sys.modules:
108
112
  del sys.modules["autogen"]
109
-
113
+ site.main() # Rebuild the site module cache
110
114
  # Re-import autogen
111
115
  # pylint: disable=unused-import
112
116
  import autogen # pyright: ignore
113
117
 
118
+ for mod_name in sorted(autogen_modules, key=len, reverse=False):
119
+ # Re-import each module
120
+ try:
121
+ importlib.import_module(mod_name)
122
+ except ImportError as e:
123
+ # If a module fails to import, we can log it or handle it
124
+ print(f"Failed to re-import {mod_name}: {e}", file=sys.stderr)
125
+
114
126
  # Restore IOStream state if we had it
115
127
  if default_io_stream is not None:
116
128
  try:
@@ -125,11 +137,43 @@ def reload_autogen() -> None: # noqa: C901
125
137
  # If reload fails, at least try to re-import autogen
126
138
  try:
127
139
  import autogen # type: ignore # noqa: F401
128
- except ImportError:
140
+
141
+ for mod_name in sorted(autogen_modules, key=len, reverse=False):
142
+ # Re-import each module
143
+ try:
144
+ importlib.import_module(mod_name)
145
+ except ImportError as err:
146
+ # If a module fails to import, we can log it or handle it
147
+ print(
148
+ f"Failed to re-import {mod_name}: {err}",
149
+ file=sys.stderr,
150
+ )
151
+ except Exception: # pylint: disable=broad-exception-caught
129
152
  pass
130
153
  raise e
131
154
 
132
155
 
156
+ def reload_chroma_if_needed() -> None: # pragma: no cover
157
+ """Reload the chroma package if it is installed."""
158
+ cheomadb_modules = [
159
+ name
160
+ for name in sys.modules
161
+ if name.startswith("chromadb.") or name == "chromadb"
162
+ ]
163
+ if not cheomadb_modules:
164
+ return
165
+
166
+ for mod_name in sorted(cheomadb_modules, key=len, reverse=True):
167
+ # Remove chromadb modules in reverse dependency order
168
+ if mod_name in sys.modules:
169
+ del sys.modules[mod_name]
170
+ try:
171
+ import chromadb # type: ignore[unused-ignore, import-not-found, import-untyped]
172
+ except ImportError:
173
+ # If chromadb is not installed, we can ignore this
174
+ return
175
+
176
+
133
177
  def try_handle_the_np_thing() -> None:
134
178
  """Try to handle the numpy deprecation warning."""
135
179
  # we might get:
@@ -141,7 +185,7 @@ def try_handle_the_np_thing() -> None:
141
185
  os.environ["NPY_PROMOTION_STATE"] = "weak"
142
186
  import numpy as np
143
187
 
144
- if not hasattr(np, "_no_pep50_warning"):
188
+ if not hasattr(np, "_no_pep50_warning"): # pragma: no branch
145
189
  import contextlib
146
190
 
147
191
  @contextlib.contextmanager
@@ -5,11 +5,14 @@
5
5
  """Utilities for running code."""
6
6
 
7
7
  import datetime
8
+ import json
8
9
  import shutil
9
10
  from pathlib import Path
10
11
  from typing import Optional, Union
11
12
 
12
13
  from .gen_seq_diagram import generate_sequence_diagram
14
+ from .patch_io_stream import get_printer
15
+ from .timeline_processor import TimelineProcessor
13
16
 
14
17
 
15
18
  def after_run(
@@ -18,6 +21,7 @@ def after_run(
18
21
  flow_name: str,
19
22
  uploads_root: Optional[Path] = None,
20
23
  skip_mmd: bool = False,
24
+ skip_timeline: bool = False,
21
25
  ) -> None:
22
26
  """Actions to perform after running the flow.
23
27
 
@@ -34,25 +38,21 @@ def after_run(
34
38
  skip_mmd : bool, optional
35
39
  Whether to skip the mermaid sequence diagram generation,
36
40
  by default, False
41
+ skip_timeline : bool, optional
42
+ Whether to skip the timeline processing, by default False
37
43
  """
38
44
  if isinstance(output_file, str):
39
45
  output_file = Path(output_file)
40
46
  mmd_dir = output_file.parent if output_file else Path.cwd()
41
47
  if skip_mmd is False:
42
- events_csv_path = temp_dir / "logs" / "events.csv"
43
- if events_csv_path.exists():
44
- print("Generating mermaid sequence diagram...")
45
- mmd_path = temp_dir / f"{flow_name}.mmd"
46
- generate_sequence_diagram(events_csv_path, mmd_path)
47
- if (
48
- not output_file
49
- and mmd_path.exists()
50
- and mmd_path != mmd_dir / f"{flow_name}.mmd"
51
- ):
52
- try:
53
- shutil.copyfile(mmd_path, mmd_dir / f"{flow_name}.mmd")
54
- except BaseException: # pylint: disable=broad-exception-caught
55
- pass
48
+ _make_mermaid_diagram(
49
+ temp_dir=temp_dir,
50
+ output_file=output_file,
51
+ flow_name=flow_name,
52
+ mmd_dir=mmd_dir,
53
+ )
54
+ if skip_timeline is False:
55
+ _make_timeline_json(temp_dir=temp_dir)
56
56
  if output_file:
57
57
  destination_dir = output_file.parent
58
58
  destination_dir = (
@@ -71,6 +71,62 @@ def after_run(
71
71
  shutil.rmtree(temp_dir)
72
72
 
73
73
 
74
+ def _make_mermaid_diagram(
75
+ temp_dir: Path,
76
+ output_file: Optional[Union[str, Path]],
77
+ flow_name: str,
78
+ mmd_dir: Path,
79
+ ) -> None:
80
+ events_csv_path = temp_dir / "logs" / "events.csv"
81
+ if events_csv_path.exists():
82
+ print("Generating mermaid sequence diagram...")
83
+ mmd_path = temp_dir / f"{flow_name}.mmd"
84
+ generate_sequence_diagram(events_csv_path, mmd_path)
85
+ if (
86
+ not output_file
87
+ and mmd_path.exists()
88
+ and mmd_path != mmd_dir / f"{flow_name}.mmd"
89
+ ):
90
+ try:
91
+ shutil.copyfile(mmd_path, mmd_dir / f"{flow_name}.mmd")
92
+ except BaseException: # pylint: disable=broad-exception-caught
93
+ pass
94
+
95
+
96
+ def _make_timeline_json(
97
+ temp_dir: Path,
98
+ ) -> None:
99
+ """Make the timeline JSON file."""
100
+ events_csv_path = temp_dir / "logs" / "events.csv"
101
+ if events_csv_path.exists():
102
+ log_files = TimelineProcessor.get_files(temp_dir / "logs")
103
+ if any(log_files.values()):
104
+ output_file = temp_dir / "timeline.json"
105
+ # pylint: disable=too-many-try-statements
106
+ try:
107
+ processor = TimelineProcessor()
108
+ processor.load_csv_files(
109
+ agents_file=log_files["agents"],
110
+ chat_file=log_files["chat"],
111
+ events_file=log_files["events"],
112
+ functions_file=log_files["functions"],
113
+ )
114
+ results = processor.process_timeline()
115
+ with open(output_file, "w", encoding="utf-8") as f:
116
+ json.dump(results, f, indent=2, default=str)
117
+ short_results = TimelineProcessor.get_short_results(results)
118
+ printer = get_printer()
119
+ printer(
120
+ json.dumps(
121
+ {"type": "timeline", "content": short_results},
122
+ default=str,
123
+ ),
124
+ flush=True,
125
+ )
126
+ except BaseException: # pylint: disable=broad-exception-caught
127
+ pass
128
+
129
+
74
130
  def copy_results(
75
131
  temp_dir: Path,
76
132
  output_file: Path,
@@ -15,6 +15,7 @@ from .utils import strip_ansi
15
15
 
16
16
  def install_requirements(
17
17
  extra_requirements: set[str],
18
+ upgrade: bool = False,
18
19
  printer: Callable[..., None] = print,
19
20
  ) -> None:
20
21
  """Install the requirements.
@@ -23,6 +24,8 @@ def install_requirements(
23
24
  ----------
24
25
  extra_requirements : set[str]
25
26
  The extra requirements.
27
+ upgrade : bool, optional
28
+ Whether to upgrade the requirements, by default False.
26
29
  printer : Callable[..., None]
27
30
  The printer function to use, defaults to print.
28
31
  """
@@ -38,6 +41,8 @@ def install_requirements(
38
41
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
39
42
  if not is_root():
40
43
  pip_install.append("--user")
44
+ if upgrade:
45
+ pip_install.append("--upgrade")
41
46
  pip_install.extend(extra_requirements)
42
47
  # pylint: disable=too-many-try-statements
43
48
  try:
@@ -63,6 +68,7 @@ def install_requirements(
63
68
 
64
69
  async def a_install_requirements(
65
70
  extra_requirements: set[str],
71
+ upgrade: bool = False,
66
72
  printer: Callable[..., None] = print,
67
73
  ) -> None:
68
74
  """Install the requirements asynchronously.
@@ -71,6 +77,8 @@ async def a_install_requirements(
71
77
  ----------
72
78
  extra_requirements : set[str]
73
79
  The extra requirements.
80
+ upgrade : bool, optional
81
+ Whether to upgrade the requirements, by default False.
74
82
  printer : Callable[..., None]
75
83
  The printer function to use, defaults to print.
76
84
  """
@@ -83,6 +91,8 @@ async def a_install_requirements(
83
91
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = "1"
84
92
  if not is_root():
85
93
  pip_install.extend(["--user"])
94
+ if upgrade:
95
+ pip_install.append("--upgrade")
86
96
  pip_install.extend(extra_requirements)
87
97
  # pylint: disable=too-many-try-statements
88
98
  try:
@@ -103,3 +113,35 @@ async def a_install_requirements(
103
113
  os.environ["PIP_BREAK_SYSTEM_PACKAGES"] = break_system_packages
104
114
  else:
105
115
  del os.environ["PIP_BREAK_SYSTEM_PACKAGES"]
116
+
117
+
118
+ def install_waldiez(
119
+ upgrade: bool = True,
120
+ printer: Callable[..., None] = print,
121
+ ) -> None:
122
+ """Install Waldiez.
123
+
124
+ Parameters
125
+ ----------
126
+ upgrade : bool, optional
127
+ Whether to upgrade Waldiez, by default True.
128
+ printer : Callable[..., None]
129
+ The printer function to use, defaults to print.
130
+ """
131
+ install_requirements({"waldiez"}, upgrade, printer)
132
+
133
+
134
+ async def a_install_waldiez(
135
+ upgrade: bool = True,
136
+ printer: Callable[..., None] = print,
137
+ ) -> None:
138
+ """Install Waldiez asynchronously.
139
+
140
+ Parameters
141
+ ----------
142
+ upgrade : bool, optional
143
+ Whether to upgrade Waldiez, by default True.
144
+ printer : Callable[..., None]
145
+ The printer function to use, defaults to print.
146
+ """
147
+ await a_install_requirements({"waldiez"}, upgrade, printer)
@@ -7,7 +7,10 @@ from pathlib import Path
7
7
  from typing import TYPE_CHECKING, Protocol, Union, runtime_checkable
8
8
 
9
9
  if TYPE_CHECKING:
10
- from autogen import ChatResult # type: ignore[import-untyped]
10
+ from autogen.io.run_response import ( # type: ignore[import-untyped]
11
+ AsyncRunResponseProtocol,
12
+ RunResponseProtocol,
13
+ )
11
14
 
12
15
 
13
16
  @runtime_checkable
@@ -59,7 +62,6 @@ class WaldiezRunnerProtocol(Protocol):
59
62
  output_path: str | Path | None,
60
63
  uploads_root: str | Path | None,
61
64
  structured_io: bool | None = None,
62
- skip_patch_io: bool | None = None,
63
65
  skip_mmd: bool = False,
64
66
  ) -> None:
65
67
  """Start running the Waldiez flow in a non-blocking way.
@@ -74,9 +76,6 @@ class WaldiezRunnerProtocol(Protocol):
74
76
  The runtime uploads root.
75
77
  structured_io : bool
76
78
  Whether to use structured IO instead of the default 'input/print'.
77
- skip_patch_io : bool | None
78
- Whether to skip patching I/O, by default None.
79
- If None, it will use the value from the context.
80
79
  skip_mmd : bool
81
80
  Whether to skip generating the mermaid diagram.
82
81
 
@@ -91,7 +90,6 @@ class WaldiezRunnerProtocol(Protocol):
91
90
  output_path: str | Path | None,
92
91
  uploads_root: str | Path | None,
93
92
  structured_io: bool | None = None,
94
- skip_patch_io: bool | None = None,
95
93
  skip_mmd: bool = False,
96
94
  ) -> None:
97
95
  """Asynchronously start running the Waldiez flow in a non-blocking way.
@@ -106,9 +104,6 @@ class WaldiezRunnerProtocol(Protocol):
106
104
  The runtime uploads root.
107
105
  structured_io : bool
108
106
  Whether to use structured IO instead of the default 'input/print'.
109
- skip_patch_io : bool | None
110
- Whether to skip patching I/O, by default None.
111
- If None, it will use the value from the context.
112
107
  skip_mmd : bool
113
108
  Whether to skip generating the mermaid diagram.
114
109
 
@@ -123,13 +118,10 @@ class WaldiezRunnerProtocol(Protocol):
123
118
  output_path: str | Path | None,
124
119
  uploads_root: str | Path | None,
125
120
  structured_io: bool | None = None,
126
- threaded: bool | None = None,
127
- skip_patch_io: bool | None = None,
128
121
  skip_mmd: bool = False,
129
122
  ) -> Union[
130
- "ChatResult",
131
- list["ChatResult"],
132
- dict[int, "ChatResult"],
123
+ list["RunResponseProtocol"],
124
+ list["AsyncRunResponseProtocol"],
133
125
  ]: # pyright: ignore
134
126
  """Run the Waldiez flow in a blocking way.
135
127
 
@@ -141,20 +133,17 @@ class WaldiezRunnerProtocol(Protocol):
141
133
  The runtime uploads root.
142
134
  structured_io : bool
143
135
  Whether to use structured IO instead of the default 'input/print'.
144
- threaded : bool | None
145
- Whether to run the flow in a separate thread.
146
- skip_patch_io : bool
147
- Whether to skip patching I/O, by default None.
148
- If None, it will use the value from the context.
149
136
  skip_mmd : bool
150
137
  Whether to skip generating the mermaid diagram.
151
138
 
152
139
  Returns
153
140
  -------
154
- Union[ChatResult, list[ChatResult], dict[int, ChatResult]]
155
- The result of the run, which can be a single ChatResult,
156
- a list of ChatResults,
157
- or a dictionary mapping indices to ChatResults.
141
+ Union[
142
+ list["RunResponseProtocol"],
143
+ list["AsyncRunResponseProtocol"],
144
+ ]
145
+ The result of the run, which can be a list of RunResponseProtocol
146
+ or a list of AsyncRunResponseProtocol.
158
147
  """
159
148
 
160
149
  async def a_run(
@@ -162,12 +151,10 @@ class WaldiezRunnerProtocol(Protocol):
162
151
  output_path: str | Path | None,
163
152
  uploads_root: str | Path | None,
164
153
  structured_io: bool | None = None,
165
- skip_patch_io: bool | None = None,
166
154
  skip_mmd: bool = False,
167
155
  ) -> Union[
168
- "ChatResult",
169
- list["ChatResult"],
170
- dict[int, "ChatResult"],
156
+ list["RunResponseProtocol"],
157
+ list["AsyncRunResponseProtocol"],
171
158
  ]: # pyright: ignore
172
159
  """Run the Waldiez flow.
173
160
 
@@ -179,40 +166,41 @@ class WaldiezRunnerProtocol(Protocol):
179
166
  The runtime uploads root.
180
167
  structured_io : bool
181
168
  Whether to use structured IO instead of the default 'input/print'.
182
- skip_patch_io : bool
183
- Whether to skip patching I/O, by default None.
184
- If None, it will use the value from the context.
185
169
  skip_mmd : bool
186
170
  Whether to skip generating the mermaid diagram.
187
171
 
188
172
  Returns
189
173
  -------
190
- Union[ChatResult, list[ChatResult], dict[int, ChatResult]]
191
- The result of the run, which can be a single ChatResult,
192
- a list of ChatResults,
193
- or a dictionary mapping indices to ChatResults.
174
+ Union[
175
+ list["RunResponseProtocol"],
176
+ list["AsyncRunResponseProtocol"],
177
+ ]
178
+ The result of the run, which can be a list of RunResponseProtocol
179
+ or a list of AsyncRunResponseProtocol.
194
180
  """
195
181
 
196
182
  def after_run(
197
183
  self,
198
184
  results: Union[
199
- "ChatResult",
200
- list["ChatResult"],
201
- dict[int, "ChatResult"],
185
+ list["RunResponseProtocol"],
186
+ list["AsyncRunResponseProtocol"],
202
187
  ],
203
188
  output_file: Path,
204
189
  uploads_root: Path | None,
205
190
  temp_dir: Path,
206
191
  skip_mmd: bool,
192
+ skip_timeline: bool,
207
193
  ) -> None:
208
194
  """Actions to perform after running the flow.
209
195
 
210
196
  Parameters
211
197
  ----------
212
- results : Union[ChatResult, list[ChatResult], dict[int, ChatResult]]
213
- The results of the run, which can be a single ChatResult,
214
- a list of ChatResults,
215
- or a dictionary mapping indices to ChatResults.
198
+ results : Union[
199
+ list["RunResponseProtocol"],
200
+ list["AsyncRunResponseProtocol"],
201
+ ]
202
+ The results of the run, which can be a list of RunResponseProtocol
203
+ or a list of AsyncRunResponseProtocol.
216
204
  output_file : Path
217
205
  The path to the output file.
218
206
  uploads_root : Path | None
@@ -221,28 +209,32 @@ class WaldiezRunnerProtocol(Protocol):
221
209
  The path to the temporary directory.
222
210
  skip_mmd : bool
223
211
  Whether to skip generating the mermaid diagram.
212
+ skip_timeline : bool
213
+ Whether to skip generating the timeline JSON.
224
214
  """
225
215
 
226
216
  async def a_after_run(
227
217
  self,
228
218
  results: Union[
229
- "ChatResult",
230
- list["ChatResult"],
231
- dict[int, "ChatResult"],
219
+ list["RunResponseProtocol"],
220
+ list["AsyncRunResponseProtocol"],
232
221
  ],
233
222
  output_file: Path,
234
223
  uploads_root: Path | None,
235
224
  temp_dir: Path,
236
225
  skip_mmd: bool,
226
+ skip_timeline: bool,
237
227
  ) -> None:
238
228
  """Asynchronously perform actions after running the flow.
239
229
 
240
230
  Parameters
241
231
  ----------
242
- results : Union[ChatResult, list[ChatResult], dict[int, ChatResult]]
243
- The results of the run, which can be a single ChatResult,
244
- a list of ChatResults,
245
- or a dictionary mapping indices to ChatResults.
232
+ results : Union[
233
+ list["RunResponseProtocol"],
234
+ list["AsyncRunResponseProtocol"]
235
+ ]
236
+ The results of the run, which can be a list of RunResponseProtocol
237
+ or a list of AsyncRunResponseProtocol.
246
238
  output_file : Path
247
239
  The path to the output file.
248
240
  uploads_root : Path | None
@@ -251,6 +243,8 @@ class WaldiezRunnerProtocol(Protocol):
251
243
  The path to the temporary directory.
252
244
  skip_mmd : bool
253
245
  Whether to skip generating the mermaid diagram.
246
+ skip_timeline : bool
247
+ Whether to skip generating the timeline JSON.
254
248
  """
255
249
 
256
250
  def is_running(self) -> bool: # pyright: ignore
@@ -6,17 +6,17 @@
6
6
  from typing import TYPE_CHECKING, TypedDict, Union
7
7
 
8
8
  if TYPE_CHECKING:
9
- from autogen import ChatResult # type: ignore[import-untyped]
9
+ from autogen.io.run_response import ( # type: ignore[import-untyped]
10
+ AsyncRunResponseProtocol,
11
+ RunResponseProtocol,
12
+ )
10
13
 
11
14
 
12
15
  class WaldiezRunResults(TypedDict):
13
16
  """Results of the Waldiez run."""
14
17
 
15
18
  results: Union[
16
- "ChatResult",
17
- list["ChatResult"],
18
- dict[int, "ChatResult"],
19
- None,
19
+ list["RunResponseProtocol"], list["AsyncRunResponseProtocol"]
20
20
  ]
21
21
  exception: Exception | None
22
22
  completed: bool