waldiez 0.5.10__py3-none-any.whl → 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of waldiez might be problematic. Click here for more details.

Files changed (192) hide show
  1. waldiez/__init__.py +1 -1
  2. waldiez/_version.py +1 -1
  3. waldiez/cli.py +19 -7
  4. waldiez/cli_extras/jupyter.py +3 -0
  5. waldiez/cli_extras/runner.py +3 -1
  6. waldiez/cli_extras/studio.py +3 -1
  7. waldiez/exporter.py +9 -3
  8. waldiez/exporting/agent/exporter.py +15 -16
  9. waldiez/exporting/agent/extras/captain_agent_extras.py +6 -6
  10. waldiez/exporting/agent/extras/doc_agent_extras.py +6 -6
  11. waldiez/exporting/agent/extras/group_manager_agent_extas.py +40 -24
  12. waldiez/exporting/agent/extras/group_member_extras.py +6 -5
  13. waldiez/exporting/agent/extras/handoffs/after_work.py +2 -1
  14. waldiez/exporting/agent/extras/handoffs/available.py +2 -1
  15. waldiez/exporting/agent/extras/handoffs/condition.py +3 -2
  16. waldiez/exporting/agent/extras/handoffs/handoff.py +2 -1
  17. waldiez/exporting/agent/extras/handoffs/target.py +7 -4
  18. waldiez/exporting/agent/extras/rag/chroma_extras.py +27 -19
  19. waldiez/exporting/agent/extras/rag/mongo_extras.py +8 -8
  20. waldiez/exporting/agent/extras/rag/pgvector_extras.py +5 -5
  21. waldiez/exporting/agent/extras/rag/qdrant_extras.py +5 -4
  22. waldiez/exporting/agent/extras/rag/vector_db_extras.py +1 -1
  23. waldiez/exporting/agent/extras/rag_user_proxy_agent_extras.py +5 -7
  24. waldiez/exporting/agent/extras/reasoning_agent_extras.py +3 -5
  25. waldiez/exporting/agent/termination.py +1 -0
  26. waldiez/exporting/chats/exporter.py +4 -4
  27. waldiez/exporting/chats/processor.py +1 -2
  28. waldiez/exporting/chats/utils/common.py +89 -48
  29. waldiez/exporting/chats/utils/group.py +9 -9
  30. waldiez/exporting/chats/utils/nested.py +7 -7
  31. waldiez/exporting/chats/utils/sequential.py +1 -1
  32. waldiez/exporting/chats/utils/single.py +2 -2
  33. waldiez/exporting/core/constants.py +3 -1
  34. waldiez/exporting/core/content.py +7 -7
  35. waldiez/exporting/core/context.py +5 -3
  36. waldiez/exporting/core/exporter.py +5 -3
  37. waldiez/exporting/core/exporters.py +2 -2
  38. waldiez/exporting/core/extras/agent_extras/captain_extras.py +2 -2
  39. waldiez/exporting/core/extras/agent_extras/group_manager_extras.py +2 -2
  40. waldiez/exporting/core/extras/agent_extras/rag_user_extras.py +2 -2
  41. waldiez/exporting/core/extras/agent_extras/standard_extras.py +3 -8
  42. waldiez/exporting/core/extras/base.py +7 -5
  43. waldiez/exporting/core/extras/flow_extras.py +4 -5
  44. waldiez/exporting/core/extras/model_extras.py +2 -2
  45. waldiez/exporting/core/extras/path_resolver.py +1 -2
  46. waldiez/exporting/core/extras/serializer.py +13 -11
  47. waldiez/exporting/core/protocols.py +6 -5
  48. waldiez/exporting/core/result.py +25 -28
  49. waldiez/exporting/core/types.py +11 -10
  50. waldiez/exporting/core/utils/llm_config.py +4 -4
  51. waldiez/exporting/core/validation.py +10 -11
  52. waldiez/exporting/flow/execution_generator.py +99 -10
  53. waldiez/exporting/flow/exporter.py +2 -2
  54. waldiez/exporting/flow/factory.py +2 -2
  55. waldiez/exporting/flow/file_generator.py +4 -2
  56. waldiez/exporting/flow/merger.py +5 -3
  57. waldiez/exporting/flow/orchestrator.py +72 -2
  58. waldiez/exporting/flow/utils/common.py +6 -6
  59. waldiez/exporting/flow/utils/importing.py +7 -8
  60. waldiez/exporting/flow/utils/linting.py +25 -9
  61. waldiez/exporting/flow/utils/logging.py +5 -77
  62. waldiez/exporting/models/exporter.py +8 -8
  63. waldiez/exporting/models/processor.py +5 -5
  64. waldiez/exporting/tools/exporter.py +2 -2
  65. waldiez/exporting/tools/processor.py +7 -4
  66. waldiez/io/__init__.py +11 -5
  67. waldiez/io/_ws.py +12 -6
  68. waldiez/io/models/constants.py +10 -10
  69. waldiez/io/models/content/audio.py +1 -0
  70. waldiez/io/models/content/base.py +20 -18
  71. waldiez/io/models/content/file.py +1 -0
  72. waldiez/io/models/content/image.py +1 -0
  73. waldiez/io/models/content/text.py +1 -0
  74. waldiez/io/models/content/video.py +1 -0
  75. waldiez/io/models/user_input.py +10 -5
  76. waldiez/io/models/user_response.py +17 -16
  77. waldiez/io/mqtt.py +18 -31
  78. waldiez/io/redis.py +18 -22
  79. waldiez/io/structured.py +122 -70
  80. waldiez/io/utils.py +19 -10
  81. waldiez/io/ws.py +7 -3
  82. waldiez/logger.py +16 -3
  83. waldiez/models/agents/__init__.py +3 -0
  84. waldiez/models/agents/agent/agent.py +25 -17
  85. waldiez/models/agents/agent/agent_data.py +25 -22
  86. waldiez/models/agents/agent/code_execution.py +9 -11
  87. waldiez/models/agents/agent/termination_message.py +10 -12
  88. waldiez/models/agents/agent/update_system_message.py +2 -4
  89. waldiez/models/agents/agents.py +8 -8
  90. waldiez/models/agents/assistant/assistant.py +6 -3
  91. waldiez/models/agents/assistant/assistant_data.py +2 -2
  92. waldiez/models/agents/captain/captain_agent.py +7 -4
  93. waldiez/models/agents/captain/captain_agent_data.py +5 -7
  94. waldiez/models/agents/doc_agent/doc_agent.py +7 -4
  95. waldiez/models/agents/doc_agent/doc_agent_data.py +9 -10
  96. waldiez/models/agents/doc_agent/rag_query_engine.py +10 -12
  97. waldiez/models/agents/extra_requirements.py +3 -3
  98. waldiez/models/agents/group_manager/group_manager.py +12 -7
  99. waldiez/models/agents/group_manager/group_manager_data.py +13 -12
  100. waldiez/models/agents/group_manager/speakers.py +17 -19
  101. waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +7 -4
  102. waldiez/models/agents/rag_user_proxy/rag_user_proxy_data.py +4 -1
  103. waldiez/models/agents/rag_user_proxy/retrieve_config.py +69 -63
  104. waldiez/models/agents/rag_user_proxy/vector_db_config.py +19 -19
  105. waldiez/models/agents/reasoning/reasoning_agent.py +7 -4
  106. waldiez/models/agents/reasoning/reasoning_agent_data.py +3 -2
  107. waldiez/models/agents/reasoning/reasoning_agent_reason_config.py +8 -8
  108. waldiez/models/agents/user_proxy/user_proxy.py +6 -3
  109. waldiez/models/agents/user_proxy/user_proxy_data.py +1 -1
  110. waldiez/models/chat/chat.py +28 -20
  111. waldiez/models/chat/chat_data.py +22 -21
  112. waldiez/models/chat/chat_message.py +9 -9
  113. waldiez/models/chat/chat_nested.py +9 -9
  114. waldiez/models/chat/chat_summary.py +6 -6
  115. waldiez/models/common/__init__.py +2 -0
  116. waldiez/models/common/ag2_version.py +2 -0
  117. waldiez/models/common/base.py +2 -0
  118. waldiez/models/common/dict_utils.py +8 -6
  119. waldiez/models/common/handoff.py +20 -17
  120. waldiez/models/common/method_utils.py +9 -7
  121. waldiez/models/common/naming.py +49 -0
  122. waldiez/models/flow/flow.py +11 -6
  123. waldiez/models/flow/flow_data.py +23 -17
  124. waldiez/models/flow/info.py +3 -3
  125. waldiez/models/flow/naming.py +2 -1
  126. waldiez/models/model/_aws.py +11 -13
  127. waldiez/models/model/_llm.py +8 -0
  128. waldiez/models/model/_price.py +2 -4
  129. waldiez/models/model/extra_requirements.py +1 -3
  130. waldiez/models/model/model.py +2 -2
  131. waldiez/models/model/model_data.py +21 -21
  132. waldiez/models/tool/extra_requirements.py +2 -4
  133. waldiez/models/tool/predefined/_duckduckgo.py +1 -0
  134. waldiez/models/tool/predefined/_email.py +4 -0
  135. waldiez/models/tool/predefined/_google.py +1 -0
  136. waldiez/models/tool/predefined/_perplexity.py +2 -1
  137. waldiez/models/tool/predefined/_searxng.py +2 -1
  138. waldiez/models/tool/predefined/_tavily.py +1 -0
  139. waldiez/models/tool/predefined/_wikipedia.py +2 -1
  140. waldiez/models/tool/predefined/_youtube.py +1 -0
  141. waldiez/models/tool/tool.py +8 -5
  142. waldiez/models/tool/tool_data.py +2 -2
  143. waldiez/models/waldiez.py +152 -4
  144. waldiez/runner.py +11 -5
  145. waldiez/running/async_utils.py +192 -0
  146. waldiez/running/base_runner.py +155 -241
  147. waldiez/running/dir_utils.py +52 -0
  148. waldiez/running/environment.py +10 -44
  149. waldiez/running/events_mixin.py +252 -0
  150. waldiez/running/exceptions.py +20 -0
  151. waldiez/running/gen_seq_diagram.py +18 -15
  152. waldiez/running/io_utils.py +216 -0
  153. waldiez/running/protocol.py +11 -5
  154. waldiez/running/requirements_mixin.py +65 -0
  155. waldiez/running/results_mixin.py +926 -0
  156. waldiez/running/standard_runner.py +24 -27
  157. waldiez/running/step_by_step/breakpoints_mixin.py +503 -47
  158. waldiez/running/step_by_step/command_handler.py +154 -0
  159. waldiez/running/step_by_step/events_processor.py +379 -0
  160. waldiez/running/step_by_step/step_by_step_models.py +425 -41
  161. waldiez/running/step_by_step/step_by_step_runner.py +437 -382
  162. waldiez/running/subprocess_runner/__base__.py +13 -8
  163. waldiez/running/subprocess_runner/_async_runner.py +6 -4
  164. waldiez/running/subprocess_runner/_sync_runner.py +11 -6
  165. waldiez/running/subprocess_runner/runner.py +48 -23
  166. waldiez/running/timeline_processor.py +1 -1
  167. waldiez/utils/__init__.py +2 -0
  168. waldiez/utils/conflict_checker.py +4 -4
  169. waldiez/utils/python_manager.py +415 -0
  170. waldiez/ws/__init__.py +8 -7
  171. waldiez/ws/_file_handler.py +18 -20
  172. waldiez/ws/_mock.py +75 -0
  173. waldiez/ws/cli.py +58 -10
  174. waldiez/ws/client_manager.py +77 -53
  175. waldiez/ws/errors.py +3 -0
  176. waldiez/ws/models.py +61 -53
  177. waldiez/ws/reloader.py +33 -4
  178. waldiez/ws/server.py +121 -52
  179. waldiez/ws/session_manager.py +8 -9
  180. waldiez/ws/session_stats.py +1 -1
  181. waldiez/ws/utils.py +33 -5
  182. {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/METADATA +107 -109
  183. waldiez-0.6.1.dist-info/RECORD +254 -0
  184. waldiez/running/post_run.py +0 -180
  185. waldiez/running/pre_run.py +0 -159
  186. waldiez/running/run_results.py +0 -14
  187. waldiez/running/utils.py +0 -511
  188. waldiez-0.5.10.dist-info/RECORD +0 -248
  189. {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/WHEEL +0 -0
  190. {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/entry_points.txt +0 -0
  191. {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/licenses/LICENSE +0 -0
  192. {waldiez-0.5.10.dist-info → waldiez-0.6.1.dist-info}/licenses/NOTICE.md +0 -0
@@ -1,11 +1,27 @@
1
1
  # SPDX-License-Identifier: Apache-2.0.
2
2
  # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+
4
+ # pylint: disable=unused-argument,disable=line-too-long
5
+ # pyright: reportUnusedParameter=false, reportUnnecessaryIsInstance=false
6
+ # pyright: reportDeprecated=false
7
+ # flake8: noqa: E501
3
8
  """Step-by-step execution models for Waldiez."""
4
9
 
10
+ import re
5
11
  from enum import Enum
6
- from typing import Annotated, Any, Dict, Literal, Union
12
+ from typing import Annotated, Any, Literal, Union
13
+
14
+ from pydantic import BaseModel, Field, ValidationInfo, field_validator
15
+ from typing_extensions import override
16
+
7
17
 
8
- from pydantic import BaseModel, Field
18
+ class WaldiezBreakpointType(Enum):
19
+ """Types of breakpoints available."""
20
+
21
+ EVENT = "event" # Break on specific event type
22
+ AGENT = "agent" # Break on any event from specific agent
23
+ AGENT_EVENT = "agent_event" # Break on specific event from specific agent
24
+ ALL = "all" # Break on all events (default step mode)
9
25
 
10
26
 
11
27
  class WaldiezDebugStepAction(Enum):
@@ -41,6 +57,364 @@ VALID_CONTROL_COMMANDS = {
41
57
  }
42
58
 
43
59
 
60
+ class WaldiezBreakpoint(BaseModel):
61
+ """Breakpoint definition with enhanced validation."""
62
+
63
+ type: WaldiezBreakpointType
64
+ event_type: str | None = None # Required for EVENT and AGENT_EVENT
65
+ agent: str | None = None # Required for AGENT and AGENT_EVENT
66
+ description: str | None = None # Human-readable description
67
+
68
+ # noinspection PyNestedDecorators,PyUnusedLocal
69
+ @field_validator("event_type")
70
+ @classmethod
71
+ def validate_event_type(
72
+ cls,
73
+ v: str | None,
74
+ info: ValidationInfo,
75
+ ) -> str | None:
76
+ """Validate event type format.
77
+
78
+ Parameters
79
+ ----------
80
+ v : str | None
81
+ The event type to validate.
82
+ info : ValidationInfo
83
+ Validation context information.
84
+
85
+ Returns
86
+ -------
87
+ str | None
88
+ The validated event type or None if not provided.
89
+
90
+ Raises
91
+ ------
92
+ ValueError
93
+ If the event type format is invalid.
94
+ """
95
+ if v is None:
96
+ return v
97
+
98
+ # Basic validation - event types should be alphanumeric with underscores
99
+ if not re.match(r"^[a-zA-Z][a-zA-Z0-9_]*$", v):
100
+ msg = (
101
+ "Invalid breakpoint format. Event type must start with a letter and contain only "
102
+ "letters, numbers, and underscores"
103
+ )
104
+ raise ValueError(msg)
105
+ return v
106
+
107
+ # noinspection PyNestedDecorators,PyUnusedLocal
108
+ @field_validator("agent")
109
+ @classmethod
110
+ def validate_agent(
111
+ cls,
112
+ v: str | None,
113
+ info: ValidationInfo,
114
+ ) -> str | None:
115
+ """Validate agent name/id format.
116
+
117
+ Parameters
118
+ ----------
119
+ v : str | None
120
+ The agent name or id to validate.
121
+ info : ValidationInfo
122
+ Validation context information.
123
+
124
+ Returns
125
+ -------
126
+ str | None
127
+ The validated agent or None if not provided.
128
+
129
+ Raises
130
+ ------
131
+ ValueError
132
+ If the agent format is invalid.
133
+ """
134
+ if v is None:
135
+ return v
136
+
137
+ # Agent name/id should not be empty or just whitespace
138
+ if not v.strip():
139
+ raise ValueError("Agent cannot be empty or just whitespace")
140
+
141
+ return v.strip()
142
+
143
+ @override
144
+ def model_post_init(self, __context: Any, /) -> None:
145
+ """Validate breakpoint consistency after initialization.
146
+
147
+ Raises
148
+ ------
149
+ ValueError
150
+ If the breakpoint configuration is invalid.
151
+ """
152
+ if self.type == WaldiezBreakpointType.EVENT and not self.event_type:
153
+ raise ValueError("EVENT breakpoints require an event_type")
154
+
155
+ if self.type == WaldiezBreakpointType.AGENT and not self.agent:
156
+ raise ValueError("AGENT breakpoints require an agent_name")
157
+
158
+ if self.type == WaldiezBreakpointType.AGENT_EVENT:
159
+ if not self.event_type or not self.agent:
160
+ msg = (
161
+ "AGENT_EVENT breakpoints require both"
162
+ " event_type and agent_name"
163
+ )
164
+ raise ValueError(msg)
165
+
166
+ @override
167
+ def __hash__(self) -> int:
168
+ """Get the hash value for the breakpoint."""
169
+ return hash((self.type, self.event_type, self.agent))
170
+
171
+ @override
172
+ def __str__(self) -> str:
173
+ """Get the string representation for display."""
174
+ if self.type == WaldiezBreakpointType.EVENT:
175
+ return f"event:{self.event_type}"
176
+ if self.type == WaldiezBreakpointType.AGENT:
177
+ return f"agent:{self.agent}"
178
+ if self.type == WaldiezBreakpointType.AGENT_EVENT:
179
+ return f"{self.agent}:{self.event_type}"
180
+ # else: # ALL
181
+ return "all"
182
+
183
+ # pylint: disable=too-complex
184
+ @classmethod
185
+ def from_string( # noqa: C901
186
+ cls,
187
+ breakpoint_str: str,
188
+ ) -> "WaldiezBreakpoint":
189
+ """Parse breakpoint from string format with enhanced validation.
190
+
191
+ Parameters
192
+ ----------
193
+ breakpoint_str : str
194
+ The string representation of the breakpoint.
195
+
196
+ Returns
197
+ -------
198
+ WaldiezBreakpoint
199
+ The parsed breakpoint object.
200
+
201
+ Raises
202
+ ------
203
+ ValueError
204
+ If the breakpoint string format is invalid.
205
+ """
206
+ if not breakpoint_str or not isinstance(
207
+ breakpoint_str,
208
+ str,
209
+ ):
210
+ raise ValueError("Breakpoint specification cannot be empty")
211
+
212
+ breakpoint_str = breakpoint_str.strip()
213
+ if not breakpoint_str:
214
+ raise ValueError(
215
+ "Breakpoint specification cannot be just whitespace"
216
+ )
217
+
218
+ if breakpoint_str == "all":
219
+ return cls(type=WaldiezBreakpointType.ALL)
220
+
221
+ if breakpoint_str.startswith("event:"):
222
+ event_type = breakpoint_str[6:] # Remove "event:" prefix
223
+ if not event_type:
224
+ raise ValueError("Event type cannot be empty after 'event:'")
225
+ return cls(
226
+ type=WaldiezBreakpointType.EVENT,
227
+ event_type=event_type,
228
+ )
229
+
230
+ if breakpoint_str.startswith("agent:"):
231
+ agent = breakpoint_str[6:] # Remove "agent:" prefix
232
+ if not agent:
233
+ raise ValueError(
234
+ "Agent identifier cannot be empty after 'agent:'"
235
+ )
236
+ return cls(
237
+ type=WaldiezBreakpointType.AGENT,
238
+ agent=agent,
239
+ )
240
+
241
+ if ":" in breakpoint_str and not breakpoint_str.startswith(
242
+ ("event:", "agent:")
243
+ ):
244
+ # Format: "agent:event_type"
245
+ parts = breakpoint_str.split(":", 1)
246
+ if len(parts) != 2:
247
+ raise ValueError("Invalid agent:event format")
248
+
249
+ agent, event_type = parts
250
+ if not agent or not event_type:
251
+ raise ValueError(
252
+ "Both agent identifier and event type must be specified"
253
+ )
254
+
255
+ return cls(
256
+ type=WaldiezBreakpointType.AGENT_EVENT,
257
+ agent=agent,
258
+ event_type=event_type,
259
+ )
260
+ if ":" in breakpoint_str:
261
+ msg = (
262
+ "Invalid breakpoint format. Use 'event:type', 'agent:name', "
263
+ "'agent:event', or 'all'"
264
+ )
265
+ raise ValueError(msg)
266
+
267
+ return cls(
268
+ type=WaldiezBreakpointType.EVENT,
269
+ event_type=breakpoint_str,
270
+ )
271
+
272
+ def matches_agent(
273
+ self,
274
+ event: dict[str, Any],
275
+ agent_id_to_name: dict[str, str],
276
+ sender_only: bool,
277
+ ) -> bool:
278
+ """Check if the event's sender or recipient matches the breakpoint's agent.
279
+
280
+ Parameters
281
+ ----------
282
+ event : dict[str, Any]
283
+ The event to check against.
284
+ agent_id_to_name : dict[str, str]
285
+ The mapping between an agent's id and its name.
286
+ sender_only : dict[str, Any]
287
+ Only check for sender match.
288
+
289
+ Returns
290
+ -------
291
+ bool
292
+ True if the event's sender or recipient matches the breakpoint's agent.
293
+ """
294
+ if not self.agent:
295
+ return False
296
+ # Normalize both the event's sender/recipient and the breakpoint's agent
297
+ _event_sender = event.get("sender", "")
298
+ event_sender = agent_id_to_name.get(_event_sender, _event_sender)
299
+ _event_recipient = event.get("recipient", "")
300
+ event_recipient = agent_id_to_name.get(
301
+ _event_recipient, _event_recipient
302
+ )
303
+ breakpoint_agent = (
304
+ agent_id_to_name.get(self.agent, self.agent) if self.agent else ""
305
+ )
306
+ if not breakpoint_agent:
307
+ return False
308
+ if sender_only:
309
+ return breakpoint_agent == event_sender
310
+ return breakpoint_agent in (event_sender, event_recipient)
311
+
312
+ def matches(
313
+ self,
314
+ event: dict[str, Any],
315
+ agent_id_to_name: dict[str, str],
316
+ sender_only: bool,
317
+ ) -> bool:
318
+ """Check if this breakpoint matches the given event.
319
+
320
+ Parameters
321
+ ----------
322
+ event : dict[str, Any]
323
+ The event to check against.
324
+ agent_id_to_name : dict[str, str]
325
+ The mapping between an agent's id and its name.
326
+ sender_only : dict[str, Any]
327
+ On agent events, only check for sender match.
328
+
329
+ Returns
330
+ -------
331
+ bool
332
+ True if the event matches the breakpoint, False otherwise.
333
+ """
334
+ if self.type == WaldiezBreakpointType.ALL:
335
+ return True
336
+
337
+ if self.type == WaldiezBreakpointType.EVENT:
338
+ return event.get("type") == self.event_type
339
+
340
+ if self.type == WaldiezBreakpointType.AGENT:
341
+ return self.matches_agent(
342
+ event, agent_id_to_name, sender_only=sender_only
343
+ )
344
+
345
+ if self.type == WaldiezBreakpointType.AGENT_EVENT:
346
+ event_type = event.get("type", "")
347
+ if event_type != self.event_type:
348
+ return False
349
+ return self.matches_agent(
350
+ event, agent_id_to_name, sender_only=sender_only
351
+ )
352
+
353
+ # noinspection PyUnreachableCode
354
+ return False
355
+
356
+
357
+ class WaldiezDebugConfig(BaseModel):
358
+ """Configuration for debug session settings."""
359
+
360
+ max_event_history: int = Field(default=1000, ge=1, le=10000)
361
+ auto_continue: bool = Field(default=False)
362
+ step_mode: bool = Field(default=True)
363
+ enable_stats_collection: bool = Field(default=True)
364
+ command_timeout_seconds: float = Field(default=300.0, gt=0)
365
+
366
+
367
+ class WaldiezDebugBreakpointsList(BaseModel):
368
+ """Debug breakpoints message."""
369
+
370
+ type: Literal["debug_breakpoints_list"] = "debug_breakpoints_list"
371
+ breakpoints: (
372
+ list[str | WaldiezBreakpoint] | list[str] | list[WaldiezBreakpoint]
373
+ )
374
+
375
+ @property
376
+ def breakpoint_objects(self) -> list[WaldiezBreakpoint]:
377
+ """Get all breakpoints as WaldiezBreakpoint objects."""
378
+ result: list[WaldiezBreakpoint] = []
379
+ for bp in self.breakpoints:
380
+ if isinstance(bp, str):
381
+ try:
382
+ result.append(WaldiezBreakpoint.from_string(bp))
383
+ except ValueError:
384
+ continue
385
+ else:
386
+ result.append(bp)
387
+ return result
388
+
389
+
390
+ class WaldiezDebugBreakpointAdded(BaseModel):
391
+ """Debug breakpoint added message."""
392
+
393
+ type: Literal["debug_breakpoint_added"] = "debug_breakpoint_added"
394
+ breakpoint: str | WaldiezBreakpoint
395
+
396
+ @property
397
+ def breakpoint_object(self) -> WaldiezBreakpoint:
398
+ """Get breakpoint as WaldiezBreakpoint object."""
399
+ if isinstance(self.breakpoint, str):
400
+ return WaldiezBreakpoint.from_string(self.breakpoint)
401
+ return self.breakpoint
402
+
403
+
404
+ class WaldiezDebugBreakpointRemoved(BaseModel):
405
+ """Debug breakpoint removed message."""
406
+
407
+ type: Literal["debug_breakpoint_removed"] = "debug_breakpoint_removed"
408
+ breakpoint: str | WaldiezBreakpoint
409
+
410
+ @property
411
+ def breakpoint_object(self) -> WaldiezBreakpoint:
412
+ """Get breakpoint as WaldiezBreakpoint object."""
413
+ if isinstance(self.breakpoint, str):
414
+ return WaldiezBreakpoint.from_string(self.breakpoint)
415
+ return self.breakpoint
416
+
417
+
44
418
  class WaldiezDebugHelpCommand(BaseModel):
45
419
  """Help command information."""
46
420
 
@@ -84,14 +458,14 @@ class WaldiezDebugEventInfo(BaseModel):
84
458
  """Debug event info message."""
85
459
 
86
460
  type: Literal["debug_event_info"] = "debug_event_info"
87
- event: Dict[str, Any]
461
+ event: dict[str, Any]
88
462
 
89
463
 
90
464
  class WaldiezDebugStats(BaseModel):
91
465
  """Debug stats message."""
92
466
 
93
467
  type: Literal["debug_stats"] = "debug_stats"
94
- stats: Dict[str, Any]
468
+ stats: dict[str, Any]
95
469
 
96
470
 
97
471
  class WaldiezDebugHelp(BaseModel):
@@ -108,28 +482,6 @@ class WaldiezDebugError(BaseModel):
108
482
  error: str
109
483
 
110
484
 
111
- class WaldiezDebugBreakpointsList(BaseModel):
112
- """Debug breakpoints message."""
113
-
114
- type: Literal["debug_breakpoints_list"] = "debug_breakpoints_list"
115
- breakpoints: list[str] # Event types
116
- # Optional: Could extend to include agent+event combinations
117
-
118
-
119
- class WaldiezDebugBreakpointAdded(BaseModel):
120
- """Debug breakpoint added message."""
121
-
122
- type: Literal["debug_breakpoint_added"] = "debug_breakpoint_added"
123
- breakpoint: str
124
-
125
-
126
- class WaldiezDebugBreakpointRemoved(BaseModel):
127
- """Debug breakpoint removed message."""
128
-
129
- type: Literal["debug_breakpoint_removed"] = "debug_breakpoint_removed"
130
- breakpoint: str
131
-
132
-
133
485
  class WaldiezDebugBreakpointCleared(BaseModel):
134
486
  """Debug breakpoint cleared message."""
135
487
 
@@ -137,6 +489,7 @@ class WaldiezDebugBreakpointCleared(BaseModel):
137
489
  message: str
138
490
 
139
491
 
492
+ # pylint: disable=invalid-name
140
493
  WaldiezDebugMessage = Annotated[
141
494
  Union[
142
495
  WaldiezDebugPrint,
@@ -165,44 +518,69 @@ class WaldiezDebugMessageWrapper(BaseModel):
165
518
  HELP_MESSAGE = WaldiezDebugHelp(
166
519
  help=[
167
520
  WaldiezDebugHelpCommandGroup(
168
- title="Commands",
521
+ title="Basic Commands",
169
522
  commands=[
170
523
  WaldiezDebugHelpCommand(
171
- cmds=["continue", "c"], desc="Continue to the next step."
524
+ cmds=["continue", "c"], desc="Continue to the next step"
172
525
  ),
173
526
  WaldiezDebugHelpCommand(
174
- cmds=["step", "s"], desc="Step through the next event."
527
+ cmds=["step", "s"], desc="Step through the next event"
175
528
  ),
176
529
  WaldiezDebugHelpCommand(
177
- cmds=["run", "r"], desc="Run without stopping."
530
+ cmds=["run", "r"], desc="Run without stopping"
178
531
  ),
179
532
  WaldiezDebugHelpCommand(
180
- cmds=["quit", "q"], desc="Quit the debugger."
533
+ cmds=["quit", "q"], desc="Quit the debugger"
181
534
  ),
182
535
  WaldiezDebugHelpCommand(
183
- cmds=["info", "i"], desc="Show detailed event information."
536
+ cmds=["info", "i"], desc="Show detailed event information"
184
537
  ),
185
538
  WaldiezDebugHelpCommand(
186
- cmds=["help", "h"], desc="Show this help message."
539
+ cmds=["help", "h"], desc="Show this help message"
187
540
  ),
188
541
  WaldiezDebugHelpCommand(
189
- cmds=["stats", "st"], desc="Show execution statistics."
542
+ cmds=["stats", "st"], desc="Show execution statistics"
190
543
  ),
544
+ ],
545
+ ),
546
+ WaldiezDebugHelpCommandGroup(
547
+ title="Breakpoint Commands",
548
+ commands=[
191
549
  WaldiezDebugHelpCommand(
192
550
  cmds=["add_breakpoint", "ab"],
193
- desc="Add breakpoint for event type.",
551
+ desc="Add breakpoint. Usage: 'ab [spec]' where spec is 'event:<type>', 'agent:<name>', '<name>:<event>', or 'all'",
194
552
  ),
195
553
  WaldiezDebugHelpCommand(
196
554
  cmds=["remove_breakpoint", "rb"],
197
- desc="Remove breakpoint for event type.",
555
+ desc="Remove breakpoint. Usage: 'rb [spec]' with same format as add",
198
556
  ),
199
557
  WaldiezDebugHelpCommand(
200
- cmds=["list_breakpoints", "lb"],
201
- desc="List all breakpoints.",
558
+ cmds=["list_breakpoints", "lb"], desc="List all breakpoints"
202
559
  ),
203
560
  WaldiezDebugHelpCommand(
204
561
  cmds=["clear_breakpoints", "cb"],
205
- desc="Clear all breakpoints.",
562
+ desc="Clear all breakpoints",
563
+ ),
564
+ ],
565
+ ),
566
+ WaldiezDebugHelpCommandGroup(
567
+ title="Breakpoint Examples",
568
+ commands=[
569
+ WaldiezDebugHelpCommand(
570
+ desc="'ab' - Add breakpoint for the current event type"
571
+ ),
572
+ WaldiezDebugHelpCommand(
573
+ desc="'ab event:tool_call' - Break on all 'tool_call' events"
574
+ ),
575
+ WaldiezDebugHelpCommand(
576
+ desc="'ab agent:user' - Break on any event from 'user' agent"
577
+ ),
578
+ WaldiezDebugHelpCommand(
579
+ desc="'ab assistant:tool_call' - Break on 'tool_call' events from 'assistant'"
580
+ ),
581
+ WaldiezDebugHelpCommand(desc="'ab all' - Break on all events"),
582
+ WaldiezDebugHelpCommand(
583
+ desc="'rb event:tool_call' - Remove 'tool_call' event breakpoint"
206
584
  ),
207
585
  ],
208
586
  ),
@@ -213,10 +591,16 @@ HELP_MESSAGE = WaldiezDebugHelp(
213
591
  desc="Press Enter alone to continue (same as 'c')"
214
592
  ),
215
593
  WaldiezDebugHelpCommand(
216
- desc="Use (s)tep to go through events one by one."
594
+ desc="Use (s)tep to go through events one by one"
595
+ ),
596
+ WaldiezDebugHelpCommand(
597
+ desc="Use (r)un to continue without stopping"
598
+ ),
599
+ WaldiezDebugHelpCommand(
600
+ desc="Set specific breakpoints to avoid noise: 'ab event:message'"
217
601
  ),
218
602
  WaldiezDebugHelpCommand(
219
- desc="Use (r)un to continue without stopping."
603
+ desc="Check (st)ats regularly to monitor progress"
220
604
  ),
221
605
  ],
222
606
  ),