waldiez 0.5.9__py3-none-any.whl → 0.5.10__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 (88) hide show
  1. waldiez/_version.py +1 -1
  2. waldiez/cli.py +112 -24
  3. waldiez/exporting/agent/exporter.py +3 -0
  4. waldiez/exporting/agent/extras/captain_agent_extras.py +44 -7
  5. waldiez/exporting/agent/extras/handoffs/condition.py +3 -1
  6. waldiez/exporting/chats/utils/common.py +25 -23
  7. waldiez/exporting/core/__init__.py +0 -2
  8. waldiez/exporting/core/context.py +13 -13
  9. waldiez/exporting/core/protocols.py +0 -141
  10. waldiez/exporting/core/result.py +5 -5
  11. waldiez/exporting/flow/merger.py +2 -2
  12. waldiez/exporting/flow/orchestrator.py +1 -0
  13. waldiez/exporting/flow/utils/common.py +2 -2
  14. waldiez/exporting/flow/utils/importing.py +1 -0
  15. waldiez/exporting/flow/utils/logging.py +6 -7
  16. waldiez/exporting/tools/exporter.py +5 -0
  17. waldiez/exporting/tools/factory.py +4 -0
  18. waldiez/exporting/tools/processor.py +5 -1
  19. waldiez/io/_ws.py +13 -5
  20. waldiez/io/models/content/image.py +1 -0
  21. waldiez/io/models/user_input.py +4 -4
  22. waldiez/io/models/user_response.py +1 -0
  23. waldiez/io/mqtt.py +1 -1
  24. waldiez/io/structured.py +17 -17
  25. waldiez/io/utils.py +1 -1
  26. waldiez/io/ws.py +9 -11
  27. waldiez/logger.py +180 -63
  28. waldiez/models/agents/agent/update_system_message.py +0 -2
  29. waldiez/models/agents/doc_agent/doc_agent.py +8 -1
  30. waldiez/models/common/dict_utils.py +169 -40
  31. waldiez/models/flow/flow.py +6 -6
  32. waldiez/models/flow/info.py +5 -1
  33. waldiez/models/model/_llm.py +28 -14
  34. waldiez/models/model/model.py +4 -1
  35. waldiez/models/model/model_data.py +18 -5
  36. waldiez/models/tool/predefined/_config.py +5 -1
  37. waldiez/models/tool/predefined/_duckduckgo.py +4 -0
  38. waldiez/models/tool/predefined/_email.py +474 -0
  39. waldiez/models/tool/predefined/_google.py +4 -1
  40. waldiez/models/tool/predefined/_perplexity.py +3 -0
  41. waldiez/models/tool/predefined/_searxng.py +3 -0
  42. waldiez/models/tool/predefined/_tavily.py +4 -1
  43. waldiez/models/tool/predefined/_wikipedia.py +4 -1
  44. waldiez/models/tool/predefined/_youtube.py +4 -1
  45. waldiez/models/tool/predefined/protocol.py +3 -0
  46. waldiez/models/tool/tool.py +22 -4
  47. waldiez/models/waldiez.py +12 -0
  48. waldiez/runner.py +37 -54
  49. waldiez/running/__init__.py +6 -0
  50. waldiez/running/base_runner.py +310 -353
  51. waldiez/running/environment.py +1 -0
  52. waldiez/running/exceptions.py +9 -0
  53. waldiez/running/post_run.py +4 -4
  54. waldiez/running/pre_run.py +51 -40
  55. waldiez/running/protocol.py +21 -101
  56. waldiez/running/run_results.py +1 -1
  57. waldiez/running/standard_runner.py +84 -277
  58. waldiez/running/step_by_step/__init__.py +46 -0
  59. waldiez/running/step_by_step/breakpoints_mixin.py +188 -0
  60. waldiez/running/step_by_step/step_by_step_models.py +224 -0
  61. waldiez/running/step_by_step/step_by_step_runner.py +745 -0
  62. waldiez/running/subprocess_runner/__base__.py +282 -0
  63. waldiez/running/subprocess_runner/__init__.py +16 -0
  64. waldiez/running/subprocess_runner/_async_runner.py +362 -0
  65. waldiez/running/subprocess_runner/_sync_runner.py +455 -0
  66. waldiez/running/subprocess_runner/runner.py +561 -0
  67. waldiez/running/timeline_processor.py +1 -1
  68. waldiez/running/utils.py +376 -1
  69. waldiez/utils/version.py +2 -6
  70. waldiez/ws/__init__.py +70 -0
  71. waldiez/ws/__main__.py +15 -0
  72. waldiez/ws/_file_handler.py +201 -0
  73. waldiez/ws/cli.py +211 -0
  74. waldiez/ws/client_manager.py +835 -0
  75. waldiez/ws/errors.py +416 -0
  76. waldiez/ws/models.py +971 -0
  77. waldiez/ws/reloader.py +342 -0
  78. waldiez/ws/server.py +469 -0
  79. waldiez/ws/session_manager.py +393 -0
  80. waldiez/ws/session_stats.py +83 -0
  81. waldiez/ws/utils.py +385 -0
  82. {waldiez-0.5.9.dist-info → waldiez-0.5.10.dist-info}/METADATA +74 -74
  83. {waldiez-0.5.9.dist-info → waldiez-0.5.10.dist-info}/RECORD +87 -65
  84. waldiez/running/patch_io_stream.py +0 -210
  85. {waldiez-0.5.9.dist-info → waldiez-0.5.10.dist-info}/WHEEL +0 -0
  86. {waldiez-0.5.9.dist-info → waldiez-0.5.10.dist-info}/entry_points.txt +0 -0
  87. {waldiez-0.5.9.dist-info → waldiez-0.5.10.dist-info}/licenses/LICENSE +0 -0
  88. {waldiez-0.5.9.dist-info → waldiez-0.5.10.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.9"
8
+ __version__ = VERSION = "0.5.10"
waldiez/cli.py CHANGED
@@ -7,8 +7,9 @@
7
7
 
8
8
  import json
9
9
  import os
10
+ import sys
10
11
  from pathlib import Path
11
- from typing import Optional
12
+ from typing import TYPE_CHECKING, Literal, Optional
12
13
 
13
14
  import anyio
14
15
  import typer
@@ -19,9 +20,14 @@ from .cli_extras import add_cli_extras
19
20
  from .logger import get_logger
20
21
  from .models import Waldiez
21
22
  from .utils import get_waldiez_version
23
+ from .ws import add_ws_app
24
+
25
+ if TYPE_CHECKING:
26
+ # noinspection PyUnusedImports
27
+ from waldiez.running import WaldiezBaseRunner
22
28
 
23
29
  load_dotenv()
24
- LOG = get_logger()
30
+ LOG = get_logger(level="debug")
25
31
 
26
32
  app = typer.Typer(
27
33
  name="waldiez",
@@ -55,7 +61,13 @@ def show_version(
55
61
  raise typer.Exit()
56
62
 
57
63
 
58
- @app.command()
64
+ @app.command(
65
+ context_settings={
66
+ "help_option_names": ["-h", "--help"],
67
+ "allow_extra_args": True,
68
+ "ignore_unknown_options": True,
69
+ },
70
+ )
59
71
  def run(
60
72
  file: Annotated[
61
73
  Path,
@@ -113,15 +125,52 @@ def run(
113
125
  readable=True,
114
126
  resolve_path=True,
115
127
  ),
128
+ step: bool = typer.Option( # noqa: B008
129
+ False,
130
+ "--step",
131
+ "-s",
132
+ help=(
133
+ "Run the flow in step-by-step mode. "
134
+ "This will pause execution after each step, allowing for debugging."
135
+ ),
136
+ is_eager=True,
137
+ rich_help_panel="Debug",
138
+ ),
139
+ subprocess: bool = typer.Option(
140
+ False,
141
+ "--subprocess",
142
+ "-p",
143
+ help=(
144
+ "Run the flow using the subprocess runner. "
145
+ "This will execute the flow in a separate process."
146
+ ),
147
+ is_eager=True,
148
+ ),
116
149
  ) -> None:
117
150
  """Run a Waldiez flow."""
118
151
  os.environ["AUTOGEN_USE_DOCKER"] = "0"
119
152
  os.environ["NEP50_DISABLE_WARNING"] = "1"
120
153
  output_path = _get_output_path(output, force)
121
- from waldiez.runner import WaldiezRunner
154
+ from waldiez.runner import create_runner
122
155
 
156
+ run_mode: Literal["standard", "debug", "subprocess"] = "standard"
157
+ if subprocess:
158
+ run_mode = "subprocess"
159
+ elif step:
160
+ run_mode = "debug"
161
+ subprocess_mode = "run"
162
+ if run_mode == "subprocess":
163
+ subprocess_mode = "debug" if step else "run"
123
164
  try:
124
- runner = WaldiezRunner.load(file)
165
+ runner = create_runner(
166
+ Waldiez.load(file),
167
+ mode=run_mode,
168
+ output_path=output_path,
169
+ uploads_root=uploads_root,
170
+ structured_io=structured,
171
+ dot_env=env_file,
172
+ subprocess_mode=subprocess_mode,
173
+ )
125
174
  except FileNotFoundError as error:
126
175
  typer.echo(f"File not found: {file}")
127
176
  raise typer.Exit(code=1) from error
@@ -131,25 +180,7 @@ def run(
131
180
  except ValueError as error:
132
181
  typer.echo(f"Invalid .waldiez file: {error}")
133
182
  raise typer.Exit(code=1) from error
134
- if runner.is_async:
135
- anyio.run(
136
- runner.a_run,
137
- output_path,
138
- uploads_root,
139
- structured, # structured_io
140
- False, # skip_mmd
141
- False, # skip_timeline
142
- env_file,
143
- )
144
- else:
145
- runner.run(
146
- output_path=output_path,
147
- uploads_root=uploads_root,
148
- structured_io=structured,
149
- skip_mmd=False,
150
- skip_timeline=False,
151
- dot_env=env_file,
152
- )
183
+ _do_run(runner, output_path, uploads_root, structured, env_file)
153
184
 
154
185
 
155
186
  @app.command()
@@ -252,7 +283,64 @@ def _get_output_path(output: Optional[Path], force: bool) -> Optional[Path]:
252
283
  return output
253
284
 
254
285
 
286
+ def _do_run(
287
+ runner: "WaldiezBaseRunner", # noqa: F821
288
+ output_path: Path | None,
289
+ uploads_root: Path | None,
290
+ structured: bool,
291
+ env_file: Path | None,
292
+ ) -> None:
293
+ _error: Exception | None = None
294
+ _stopped: bool = False
295
+ from waldiez.running import StopRunningException
296
+
297
+ try:
298
+ if runner.waldiez.is_async:
299
+ anyio.run(
300
+ runner.a_run,
301
+ output_path,
302
+ uploads_root,
303
+ structured, # structured_io
304
+ False, # skip_mmd
305
+ False, # skip_timeline
306
+ env_file,
307
+ )
308
+ # os._exit(0 if _error is None else 1)
309
+ else:
310
+ runner.run(
311
+ output_path=output_path,
312
+ uploads_root=uploads_root,
313
+ structured_io=structured,
314
+ skip_mmd=False,
315
+ skip_timeline=False,
316
+ dot_env=env_file,
317
+ )
318
+ except Exception as error:
319
+ _error = (
320
+ error if StopRunningException.reason not in str(error) else None
321
+ )
322
+ _stopped = StopRunningException.reason in str(error)
323
+ _error = error if not _stopped else None
324
+ if _error:
325
+ LOG.error("Execution failed: %s", error)
326
+ else:
327
+ LOG.warning(StopRunningException.reason)
328
+ raise typer.Exit(code=1 if error else 0) from error
329
+ except KeyboardInterrupt:
330
+ LOG.warning("Execution interrupted.")
331
+ _stopped = True
332
+ typer.echo("Execution stopped by user.")
333
+ finally:
334
+ if _stopped:
335
+ os._exit(0)
336
+ elif _error:
337
+ os._exit(1)
338
+ else:
339
+ sys.exit(0)
340
+
341
+
255
342
  add_cli_extras(app)
343
+ add_ws_app(app)
256
344
 
257
345
  if __name__ == "__main__":
258
346
  app()
@@ -300,6 +300,9 @@ class AgentExporter(Exporter[StandardExtras]):
300
300
  if captain_result.before_agent:
301
301
  extras.append_before_agent(captain_result.before_agent)
302
302
 
303
+ if captain_result.after_agent:
304
+ extras.append_after_agent(captain_result.after_agent)
305
+
303
306
  return extras
304
307
 
305
308
  def create_reasoning_extras(self) -> StandardExtras:
@@ -1,6 +1,8 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
3
  # pylint: disable=too-few-public-methods,no-self-use
4
+ # pylint: disable=line-too-long
5
+ # flake8: noqa: E501
4
6
  """Captain agent configuration processor."""
5
7
 
6
8
  import json
@@ -102,8 +104,32 @@ class CaptainAgentProcessor:
102
104
  result.set_nested_config(nested_config)
103
105
  serialized_nested_config = self.serializer.serialize(nested_config)
104
106
  result.add_arg(f"nested_config={serialized_nested_config}", tabs=1)
107
+ result.append_before_agent(
108
+ self._patch_default_nested_config(),
109
+ )
105
110
  return result
106
111
 
112
+ @staticmethod
113
+ def _patch_default_nested_config() -> str:
114
+ """Patch the default nested configuration.
115
+
116
+ Returns
117
+ -------
118
+ str
119
+ The patched nested configuration.
120
+ """
121
+ content = """
122
+ # try to avoid having both temperature and top_p in the config
123
+ try:
124
+ _CAPTAIN_AGENT_DEFAULT_CONFIG = CaptainAgent.DEFAULT_NESTED_CONFIG
125
+ _CAPTAIN_AGENT_DEFAULT_CONFIG.get("autobuild_build_config", {}).get("default_llm_config", {}).pop("top_p", None)
126
+ CaptainAgent.DEFAULT_NESTED_CONFIG = _CAPTAIN_AGENT_DEFAULT_CONFIG
127
+ except Exception as e:
128
+ print(f"Error occurred while patching default nested config: {e}")
129
+ """
130
+
131
+ return content
132
+
107
133
  def _generate_nested_config(
108
134
  self,
109
135
  agent: WaldiezCaptainAgent,
@@ -135,9 +161,9 @@ class CaptainAgentProcessor:
135
161
  ) as f:
136
162
  json.dump(llm_config_list, f, ensure_ascii=False, indent=4)
137
163
  llm_config = llm_config_list[0]
138
- if "temperature" not in llm_config:
164
+ if "temperature" not in llm_config and "top_p" not in llm_config:
139
165
  llm_config["temperature"] = 1
140
- if "top_p" not in llm_config:
166
+ if "top_p" not in llm_config and "temperature" not in llm_config:
141
167
  llm_config["top_p"] = 0.95
142
168
  if "max_tokens" not in llm_config:
143
169
  llm_config["max_tokens"] = 2048
@@ -177,9 +203,15 @@ class CaptainAgentProcessor:
177
203
  if not config_list:
178
204
  default_model = self._get_default_model(uuid.uuid4().hex)
179
205
  default_llm_config = default_model.get_llm_config(skip_price=True)
180
- if "temperature" not in default_llm_config:
206
+ if (
207
+ "temperature" not in default_llm_config
208
+ and "top_p" not in default_llm_config
209
+ ):
181
210
  default_llm_config["temperature"] = temperature
182
- if "top_p" not in default_llm_config:
211
+ if (
212
+ "top_p" not in default_llm_config
213
+ and "temperature" not in default_llm_config
214
+ ):
183
215
  default_llm_config["top_p"] = top_p
184
216
  if "max_tokens" not in default_llm_config:
185
217
  default_llm_config["max_tokens"] = max_tokens
@@ -220,15 +252,20 @@ class CaptainAgentProcessor:
220
252
  code_execution_config["timeout"] = (
221
253
  self.agent.data.code_execution_config.timeout or 300
222
254
  )
223
- return {
255
+ to_return: dict[str, Any] = {
224
256
  "default_llm_config": {
225
- "temperature": llm_config["temperature"],
226
- "top_p": llm_config["top_p"],
227
257
  "max_tokens": llm_config["max_tokens"],
228
258
  },
229
259
  "code_execution_config": code_execution_config,
230
260
  "coding": coding,
231
261
  }
262
+ if llm_config.get("temperature") is not None:
263
+ to_return["default_llm_config"]["temperature"] = llm_config[
264
+ "temperature"
265
+ ]
266
+ elif llm_config.get("top_p") is not None:
267
+ to_return["default_llm_config"]["top_p"] = llm_config["top_p"]
268
+ return to_return
232
269
 
233
270
  def _get_waldiez_model(self, model_id: str) -> WaldiezModel:
234
271
  """Get the Waldiez model by its ID.
@@ -151,8 +151,10 @@ class ConditionProcessor:
151
151
  """Process an expression context condition handoff."""
152
152
  expression = self.serializer(condition.expression)
153
153
  condition_string = (
154
- f"ExpressionContextCondition(expression={expression})"
154
+ "ExpressionContextCondition("
155
+ f"expression=ContextExpression({expression}))"
155
156
  )
156
157
  self.result.content += condition_string
157
158
  extra_import = f"{self.IMPORT_PREFIX}ExpressionContextCondition"
158
159
  self.result.extra_imports.add(extra_import)
160
+ self.result.extra_imports.add(f"{self.IMPORT_PREFIX}ContextExpression")
@@ -73,7 +73,7 @@ def get_event_handler_string(
73
73
  content = (
74
74
  f"{tab}if on_event:\n"
75
75
  f"{tab} if not isinstance(results, list):\n"
76
- f"{tab} results = [results]\n"
76
+ f"{tab} results = [results] # pylint: disable=redefined-variable-type\n"
77
77
  f"{tab} for index, result in enumerate(results):\n"
78
78
  )
79
79
  if is_async:
@@ -81,9 +81,10 @@ def get_event_handler_string(
81
81
  f"{tab} async for event in result.events:\n"
82
82
  f"{tab} try:\n"
83
83
  f"{tab} should_continue = await on_event(event)\n"
84
- f"{tab} except Exception as e:\n"
85
- f"{tab} raise RuntimeError(\n"
86
- f"{tab} 'Error in event handler: ' + str(e)\n"
84
+ f"{tab} except BaseException as e:\n"
85
+ f'{tab} print(f"Error in event handler: {{e}}")\n'
86
+ f"{tab} raise SystemExit(\n"
87
+ f'{tab} "Error in event handler: " + str(e)\n'
87
88
  f"{tab} ) from e\n"
88
89
  )
89
90
  else:
@@ -91,22 +92,23 @@ def get_event_handler_string(
91
92
  f"{tab} for event in result.events:\n"
92
93
  f"{tab} try:\n"
93
94
  f"{tab} should_continue = on_event(event)\n"
94
- f"{tab} except Exception as e:\n"
95
- f"{tab} raise RuntimeError(\n"
96
- f"{tab} 'Error in event handler: ' + str(e)\n"
95
+ f"{tab} except BaseException as e:\n"
96
+ f'{tab} print(f"Error in event handler: {{e}}")\n'
97
+ f"{tab} raise SystemExit(\n"
98
+ f'{tab} "Error in event handler: " + str(e)\n'
97
99
  f"{tab} ) from e\n"
98
100
  )
99
101
  content += (
100
- f"{tab} if event.type == 'run_completion':\n"
101
- f"{tab} should_continue = False\n"
102
- f"{tab} if not should_continue:\n"
102
+ f'{tab} if event.type == "run_completion":\n'
103
103
  f"{tab} break\n"
104
+ f"{tab} if not should_continue:\n"
105
+ f'{tab} raise SystemExit("Event handler stopped processing")\n'
104
106
  )
105
107
  content += get_result_dicts_string(tab, is_async)
106
108
  content += (
107
109
  f"{tab}else:\n"
108
110
  f"{tab} if not isinstance(results, list):\n"
109
- f"{tab} results = [results]\n"
111
+ f"{tab} results = [results] # pylint: disable=redefined-variable-type\n"
110
112
  f"{tab} for index, result in enumerate(results):\n"
111
113
  )
112
114
  if is_async:
@@ -135,22 +137,22 @@ def get_result_dicts_string(tab: str, is_async: bool) -> str:
135
137
  """
136
138
  space = f"{tab} "
137
139
  flow_content = f"{space}result_dict = {{\n"
138
- flow_content += f"{space} 'index': index,\n"
140
+ flow_content += f'{space} "index": index,\n'
139
141
  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"
142
+ flow_content += f'{space} "messages": await result.messages,\n'
143
+ flow_content += f'{space} "summary": await result.summary,\n'
144
+ flow_content += f'{space} "cost": (await result.cost).model_dump(mode="json", fallback=str) if await result.cost else None,\n'
145
+ 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
146
  flow_content += (
145
- f"{space} 'last_speaker': await result.last_speaker,\n"
147
+ f'{space} "last_speaker": await result.last_speaker,\n'
146
148
  )
147
149
  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"
150
+ flow_content += f'{space} "messages": result.messages,\n'
151
+ flow_content += f'{space} "summary": result.summary,\n'
152
+ flow_content += f'{space} "cost": result.cost.model_dump(mode="json", fallback=str) if result.cost else None,\n'
153
+ flow_content += f'{space} "context_variables": result.context_variables.model_dump(mode="json", fallback=str) if result.context_variables else None,\n'
154
+ flow_content += f'{space} "last_speaker": result.last_speaker,\n'
155
+ flow_content += f'{space} "uuid": str(result.uuid),\n'
154
156
  flow_content += f"{space}}}\n"
155
157
  flow_content += f"{space}result_dicts.append(result_dict)\n"
156
158
  return flow_content
@@ -90,7 +90,6 @@ from .extras.tool_extras import (
90
90
  from .protocols import (
91
91
  ContentGenerator,
92
92
  ExportContributor,
93
- ExportingLogger,
94
93
  PathResolver,
95
94
  Serializer,
96
95
  Validator,
@@ -128,7 +127,6 @@ __all__ = [
128
127
  "ConfigurableExporter",
129
128
  # Protocols
130
129
  "ContentGenerator",
131
- "ExportingLogger",
132
130
  "ExportContributor",
133
131
  "Validator",
134
132
  "Serializer",
@@ -6,11 +6,11 @@ import threading
6
6
  from dataclasses import dataclass
7
7
  from typing import Any, Optional
8
8
 
9
- from waldiez.logger import WaldiezLogger
9
+ from waldiez.logger import WaldiezLogger, get_logger
10
10
 
11
11
  from .extras.path_resolver import DefaultPathResolver
12
12
  from .extras.serializer import DefaultSerializer
13
- from .protocols import ExportingLogger, PathResolver, Serializer, Validator
13
+ from .protocols import PathResolver, Serializer, Validator
14
14
  from .types import ExportConfig
15
15
 
16
16
 
@@ -22,7 +22,7 @@ class ExporterContext:
22
22
  path_resolver: PathResolver | None = None
23
23
  validator: Validator | None = None
24
24
  config: ExportConfig | None = None
25
- logger: ExportingLogger | None = None
25
+ logger: WaldiezLogger | None = None
26
26
 
27
27
  def get_serializer(self) -> Serializer:
28
28
  """Get serializer or raise if not set.
@@ -112,15 +112,15 @@ class ExporterContext:
112
112
  """
113
113
  self.config = config
114
114
 
115
- def get_logger(self) -> ExportingLogger:
115
+ def get_logger(self) -> WaldiezLogger:
116
116
  """Get logger or create a default one.
117
117
 
118
118
  Returns
119
119
  -------
120
- ExportingLogger
120
+ WaldiezLogger
121
121
  The logger instance.
122
122
  """
123
- return self.logger or WaldiezLogger()
123
+ return self.logger or get_logger()
124
124
 
125
125
 
126
126
  # pylint: disable=too-few-public-methods
@@ -168,7 +168,7 @@ class DefaultExporterContext(ExporterContext):
168
168
  serializer: Serializer | None = None,
169
169
  validator: Validator | None = None,
170
170
  path_resolver: PathResolver | None = None,
171
- logger: ExportingLogger | None = None,
171
+ logger: WaldiezLogger | None = None,
172
172
  config: ExportConfig | None = None,
173
173
  ) -> None:
174
174
  if hasattr(self, "_initialized"):
@@ -176,7 +176,7 @@ class DefaultExporterContext(ExporterContext):
176
176
  super().__init__(
177
177
  serializer=serializer or DefaultSerializer(),
178
178
  path_resolver=path_resolver or DefaultPathResolver(),
179
- logger=logger or WaldiezLogger(),
179
+ logger=logger or get_logger(),
180
180
  validator=validator,
181
181
  config=config,
182
182
  )
@@ -185,7 +185,7 @@ class DefaultExporterContext(ExporterContext):
185
185
 
186
186
  def get_default_exporter_context(
187
187
  config: ExportConfig | None = None,
188
- logger: ExportingLogger | None = None,
188
+ logger: WaldiezLogger | None = None,
189
189
  ) -> ExporterContext:
190
190
  """Get the default exporter context.
191
191
 
@@ -204,7 +204,7 @@ def get_default_exporter_context(
204
204
  return DefaultExporterContext(
205
205
  serializer=DefaultSerializer(),
206
206
  path_resolver=DefaultPathResolver(),
207
- logger=logger or WaldiezLogger(),
207
+ logger=logger or get_logger(),
208
208
  config=config,
209
209
  )
210
210
 
@@ -214,7 +214,7 @@ def create_exporter_context(
214
214
  validator: Validator | None = None,
215
215
  path_resolver: PathResolver | None = None,
216
216
  config: ExportConfig | None = None,
217
- logger: ExportingLogger | None = None,
217
+ logger: WaldiezLogger | None = None,
218
218
  ) -> ExporterContext:
219
219
  """Create an exporter context with the given components.
220
220
 
@@ -228,7 +228,7 @@ def create_exporter_context(
228
228
  The validator component, by default None
229
229
  config : ExportConfig | None, optional
230
230
  The export configuration, by default None
231
- logger : ExportingLogger | None, optional
231
+ logger : WaldiezLogger | None, optional
232
232
  The logger instance, by default None
233
233
 
234
234
  Returns
@@ -240,6 +240,6 @@ def create_exporter_context(
240
240
  serializer=serializer or DefaultSerializer(),
241
241
  path_resolver=path_resolver or DefaultPathResolver(),
242
242
  validator=validator,
243
- logger=logger or WaldiezLogger(),
243
+ logger=logger or get_logger(),
244
244
  config=config,
245
245
  )
@@ -139,144 +139,3 @@ class ContentGenerator(Protocol):
139
139
  ExporterContentError
140
140
  If exporting fails.
141
141
  """
142
-
143
-
144
- @runtime_checkable
145
- class ExportingLogger(Protocol):
146
- """Protocol for logging during exporting."""
147
-
148
- def log(
149
- self, message: Any, *args: Any, level: str = "info", **kwargs: Any
150
- ) -> None:
151
- """Log a message with the specified level.
152
-
153
- Parameters
154
- ----------
155
- message : Any
156
- The message to log or message template for formatting.
157
- level : str, optional
158
- The logging level to use (e.g., "debug", "info", "warning", "error",
159
- "critical"). Defaults to "info".
160
- *args : Any
161
- Arguments to format into the message using % formatting.
162
- **kwargs : Any
163
- Keyword arguments to format into the message using str.format().
164
- """
165
-
166
- def error(self, message: Any, *args: Any, **kwargs: Any) -> None:
167
- """Log an error message.
168
-
169
- Parameters
170
- ----------
171
- message : Any
172
- The error message to log or message template.
173
- *args : Any
174
- Arguments to format into the message.
175
- **kwargs : Any
176
- Keyword arguments to format into the message using str.format().
177
- """
178
-
179
- def warning(self, message: Any, *args: Any, **kwargs: Any) -> None:
180
- """Log a warning message.
181
-
182
- Parameters
183
- ----------
184
- message : Any
185
- The warning message to log or message template.
186
- *args : Any
187
- Arguments to format into the message.
188
- **kwargs : Any
189
- Keyword arguments to format into the message using str.format().
190
- """
191
-
192
- def info(self, message: Any, *args: Any, **kwargs: Any) -> None:
193
- """Log an informational message.
194
-
195
- Parameters
196
- ----------
197
- message : Any
198
- The informational message to log or message template.
199
- *args : Any
200
- Arguments to format into the message.
201
- **kwargs : Any
202
- Keyword arguments to format into the message using str.format().
203
- """
204
-
205
- def success(self, message: Any, *args: Any, **kwargs: Any) -> None:
206
- """Log a success message.
207
-
208
- Parameters
209
- ----------
210
- message : Any
211
- The success message to log or message template.
212
- *args : Any
213
- Arguments to format into the message.
214
- **kwargs : Any
215
- Keyword arguments to format into the message using str.format().
216
- """
217
-
218
- def debug(self, message: Any, *args: Any, **kwargs: Any) -> None:
219
- """Log a debug message.
220
-
221
- Parameters
222
- ----------
223
- message : Any
224
- The debug message to log or message template.
225
- *args : Any
226
- Arguments to format into the message.
227
- **kwargs : Any
228
- Keyword arguments to format into the message using str.format().
229
- """
230
- self.log(message, *args, level="debug", **kwargs)
231
-
232
- def critical(self, message: Any, *args: Any, **kwargs: Any) -> None:
233
- """Log a critical error message.
234
-
235
- Parameters
236
- ----------
237
- message : Any
238
- The critical error message to log or message template.
239
- *args : Any
240
- Arguments to format into the message.
241
- **kwargs : Any
242
- Keyword arguments to format into the message using str.format().
243
- """
244
- self.log(message, *args, level="critical", **kwargs)
245
-
246
- def exception(self, message: Any, *args: Any, **kwargs: Any) -> None:
247
- """Log an exception message.
248
-
249
- Parameters
250
- ----------
251
- message : Any
252
- The exception message to log or message template.
253
- *args : Any
254
- Arguments to format into the message.
255
- **kwargs : Any
256
- Keyword arguments to format into the message using str.format().
257
- """
258
- self.log(message, *args, level="exception", **kwargs)
259
-
260
- def set_level(self, level: str) -> None:
261
- """Set the logging level.
262
-
263
- Parameters
264
- ----------
265
- level : str
266
- The logging level to set
267
- (e.g., "debug", "info", "warning", "error", "critical").
268
-
269
- Raises
270
- ------
271
- ValueError
272
- If the provided level is invalid.
273
- """
274
-
275
- def get_level(self) -> str: # pyright: ignore
276
- """Get the current logging level.
277
-
278
- Returns
279
- -------
280
- str
281
- The current logging level.
282
- """