waldiez 0.5.5__py3-none-any.whl → 0.5.7__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 (107) hide show
  1. waldiez/_version.py +1 -1
  2. waldiez/cli.py +1 -1
  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/sequential.py +3 -68
  22. waldiez/exporting/chats/utils/single.py +1 -38
  23. waldiez/exporting/core/context.py +39 -38
  24. waldiez/exporting/core/exporter.py +10 -10
  25. waldiez/exporting/core/exporters.py +36 -0
  26. waldiez/exporting/core/extras/base.py +2 -2
  27. waldiez/exporting/core/extras/chat_extras.py +4 -2
  28. waldiez/exporting/core/extras/path_resolver.py +6 -4
  29. waldiez/exporting/core/extras/serializer.py +1 -0
  30. waldiez/exporting/core/protocols.py +6 -0
  31. waldiez/exporting/core/result.py +8 -7
  32. waldiez/exporting/core/types.py +2 -2
  33. waldiez/exporting/core/utils/llm_config.py +2 -0
  34. waldiez/exporting/flow/factory.py +2 -2
  35. waldiez/exporting/flow/file_generator.py +8 -7
  36. waldiez/exporting/flow/merger.py +8 -7
  37. waldiez/exporting/flow/orchestrator.py +22 -8
  38. waldiez/exporting/flow/utils/__init__.py +2 -0
  39. waldiez/exporting/flow/utils/common.py +16 -0
  40. waldiez/exporting/flow/utils/logging.py +5 -2
  41. waldiez/exporting/models/factory.py +6 -7
  42. waldiez/exporting/tools/exporter.py +5 -5
  43. waldiez/exporting/tools/factory.py +4 -5
  44. waldiez/exporting/tools/processor.py +3 -3
  45. waldiez/exporting/tools/registration.py +1 -0
  46. waldiez/io/_ws.py +2 -0
  47. waldiez/io/models/content/audio.py +1 -0
  48. waldiez/io/models/content/file.py +1 -0
  49. waldiez/io/models/content/image.py +1 -0
  50. waldiez/io/models/content/text.py +1 -0
  51. waldiez/io/models/content/video.py +1 -0
  52. waldiez/io/models/user_input.py +1 -0
  53. waldiez/io/models/user_response.py +1 -0
  54. waldiez/io/mqtt.py +6 -3
  55. waldiez/io/redis.py +7 -9
  56. waldiez/io/structured.py +8 -6
  57. waldiez/io/utils.py +11 -4
  58. waldiez/io/ws.py +4 -3
  59. waldiez/logger.py +11 -1
  60. waldiez/models/agents/agent/agent.py +1 -0
  61. waldiez/models/agents/agent/agent_data.py +2 -2
  62. waldiez/models/agents/agent/nested_chat.py +1 -4
  63. waldiez/models/agents/agent/termination_message.py +0 -7
  64. waldiez/models/agents/agent/update_system_message.py +2 -2
  65. waldiez/models/agents/doc_agent/doc_agent_data.py +33 -26
  66. waldiez/models/agents/doc_agent/rag_query_engine.py +1 -1
  67. waldiez/models/agents/extra_requirements.py +5 -5
  68. waldiez/models/agents/group_manager/group_manager.py +3 -7
  69. waldiez/models/agents/group_manager/speakers.py +0 -7
  70. waldiez/models/agents/rag_user_proxy/rag_user_proxy.py +0 -2
  71. waldiez/models/agents/rag_user_proxy/rag_user_proxy_data.py +0 -2
  72. waldiez/models/agents/rag_user_proxy/retrieve_config.py +1 -17
  73. waldiez/models/agents/rag_user_proxy/vector_db_config.py +0 -5
  74. waldiez/models/chat/chat_data.py +0 -2
  75. waldiez/models/chat/chat_summary.py +5 -3
  76. waldiez/models/common/handoff.py +26 -18
  77. waldiez/models/common/naming.py +1 -0
  78. waldiez/models/flow/flow.py +9 -7
  79. waldiez/models/model/_llm.py +4 -2
  80. waldiez/models/model/extra_requirements.py +3 -3
  81. waldiez/models/model/model.py +3 -2
  82. waldiez/models/tool/extra_requirements.py +2 -2
  83. waldiez/models/tool/predefined/_google.py +3 -1
  84. waldiez/models/tool/predefined/_perplexity.py +4 -1
  85. waldiez/models/tool/predefined/_searxng.py +4 -1
  86. waldiez/models/tool/predefined/_wikipedia.py +5 -1
  87. waldiez/models/tool/tool.py +7 -7
  88. waldiez/models/tool/tool_data.py +39 -2
  89. waldiez/models/waldiez.py +29 -29
  90. waldiez/runner.py +1 -0
  91. waldiez/running/base_runner.py +9 -4
  92. waldiez/running/environment.py +2 -0
  93. waldiez/running/patch_io_stream.py +2 -0
  94. waldiez/running/post_run.py +3 -0
  95. waldiez/running/pre_run.py +1 -0
  96. waldiez/running/standard_runner.py +28 -4
  97. waldiez/running/timeline_processor.py +12 -1
  98. waldiez/running/utils.py +2 -0
  99. waldiez/utils/conflict_checker.py +1 -1
  100. waldiez/utils/version.py +1 -0
  101. {waldiez-0.5.5.dist-info → waldiez-0.5.7.dist-info}/METADATA +59 -57
  102. {waldiez-0.5.5.dist-info → waldiez-0.5.7.dist-info}/RECORD +106 -107
  103. waldiez/exporting/agent/extras/group/target.py +0 -178
  104. {waldiez-0.5.5.dist-info → waldiez-0.5.7.dist-info}/WHEEL +0 -0
  105. {waldiez-0.5.5.dist-info → waldiez-0.5.7.dist-info}/entry_points.txt +0 -0
  106. {waldiez-0.5.5.dist-info → waldiez-0.5.7.dist-info}/licenses/LICENSE +0 -0
  107. {waldiez-0.5.5.dist-info → waldiez-0.5.7.dist-info}/licenses/NOTICE.md +0 -0
@@ -183,6 +183,22 @@ def get_after_run_content(
183
183
  return content
184
184
 
185
185
 
186
+ def get_common_env_var_setup() -> str:
187
+ """Get common environment variable setup for Waldiez flows.
188
+
189
+ Returns
190
+ -------
191
+ str
192
+ The content to set up common environment variables.
193
+ """
194
+ content = """
195
+ # Common environment variable setup for Waldiez flows
196
+ os.environ["AUTOGEN_USE_DOCKER"] = "0"
197
+ os.environ["ANONYMIZED_TELEMETRY"] = "False"
198
+ """
199
+ return content
200
+
201
+
186
202
  def get_np_no_nep50_handle() -> str:
187
203
  """Handle the "module numpy has no attribute _no_pep50_warning" error.
188
204
 
@@ -49,7 +49,7 @@ def get_start_logging(is_async: bool, for_notebook: bool) -> str:
49
49
  "Start logging.",
50
50
  for_notebook=for_notebook,
51
51
  )
52
- if is_async is False:
52
+ if not is_async:
53
53
  return f'''
54
54
  {tab}{comment}
55
55
  {tab}def start_logging() -> None:
@@ -83,6 +83,7 @@ def get_start_logging(is_async: bool, for_notebook: bool) -> str:
83
83
 
84
84
 
85
85
  # pylint: disable=differing-param-doc,differing-type-doc
86
+ # noinspection PyUnresolvedReferences
86
87
  def get_sync_sqlite_out() -> str:
87
88
  r"""Get the sqlite to csv and json conversion code string.
88
89
 
@@ -165,6 +166,7 @@ def get_sync_sqlite_out() -> str:
165
166
 
166
167
 
167
168
  # pylint: disable=differing-param-doc,differing-type-doc,line-too-long
169
+ # noinspection PyUnresolvedReferences
168
170
  def get_async_sqlite_out() -> str:
169
171
  r"""Get the sqlite to csv and json conversion code string.
170
172
 
@@ -325,6 +327,7 @@ def get_sqlite_out_call(tabs: int, is_async: bool) -> str:
325
327
  return content
326
328
 
327
329
 
330
+ # noinspection PyUnresolvedReferences
328
331
  def get_stop_logging(is_async: bool, tabs: int = 0) -> str:
329
332
  r"""Get the function to stop logging and gather logs.
330
333
 
@@ -343,7 +346,7 @@ def get_stop_logging(is_async: bool, tabs: int = 0) -> str:
343
346
  Example
344
347
  -------
345
348
  ```python
346
- >>> get_logging_stop_string()
349
+ >>> get_stop_logging()
347
350
  def stop_logging() -> None:
348
351
  \"\"\"Stop logging.\"\"\"
349
352
  runtime_logging.stop()
@@ -3,7 +3,6 @@
3
3
  """Factory function for creating a ModelsExporter instance."""
4
4
 
5
5
  from pathlib import Path
6
- from typing import Optional, Union
7
6
 
8
7
  from waldiez.models import WaldiezAgent, WaldiezModel
9
8
 
@@ -19,9 +18,9 @@ def create_models_exporter(
19
18
  models: list[WaldiezModel],
20
19
  model_names: dict[str, str],
21
20
  for_notebook: bool = False,
22
- cache_seed: Optional[int] = None,
23
- output_dir: Optional[Union[str, Path]] = None,
24
- context: Optional[ExporterContext] = None,
21
+ cache_seed: int | None = None,
22
+ output_dir: str | Path | None = None,
23
+ context: ExporterContext | None = None,
25
24
  ) -> ModelsExporter:
26
25
  """Create a models exporter.
27
26
 
@@ -39,11 +38,11 @@ def create_models_exporter(
39
38
  Mapping of model IDs to names.
40
39
  for_notebook : bool, optional
41
40
  Whether the export is for a notebook, by default False
42
- cache_seed : Optional[int], optional
41
+ cache_seed : int | None, optional
43
42
  The cache seed if any, by default None
44
- output_dir : Optional[Union[str, Path]], optional
43
+ output_dir : str | Path | None, optional
45
44
  Output directory for generated files, by default None
46
- context : Optional[ExporterContext], optional
45
+ context : ExporterContext | None, optional
47
46
  Exporter context with dependencies, by default None
48
47
 
49
48
  Returns
@@ -4,7 +4,7 @@
4
4
  """Tools exporter."""
5
5
 
6
6
  from pathlib import Path
7
- from typing import Any, Optional, Union
7
+ from typing import Any, Optional
8
8
 
9
9
  from waldiez.models import WaldiezAgent, WaldiezTool
10
10
 
@@ -32,8 +32,8 @@ class ToolsExporter(Exporter[ToolExtras]):
32
32
  agent_names: dict[str, str],
33
33
  tools: list[WaldiezTool],
34
34
  tool_names: dict[str, str],
35
- output_dir: Optional[Union[str, Path]] = None,
36
- context: Optional[ExporterContext] = None,
35
+ output_dir: str | Path | None = None,
36
+ context: ExporterContext | None = None,
37
37
  **kwargs: Any,
38
38
  ):
39
39
  """Initialize the tools exporter.
@@ -50,9 +50,9 @@ class ToolsExporter(Exporter[ToolExtras]):
50
50
  The tools to export.
51
51
  tool_names : dict[str, str]
52
52
  Mapping of tool IDs to names.
53
- output_dir : Optional[Union[str, Path]], optional
53
+ output_dir : str | Path | None
54
54
  Output directory for generated files, by default None
55
- context : Optional[ExporterContext], optional
55
+ context : ExporterContext | None
56
56
  Exporter context with dependencies, by default None
57
57
  **kwargs
58
58
  Additional keyword arguments.
@@ -3,7 +3,6 @@
3
3
  """Factory function for creating a ToolsExporter instance."""
4
4
 
5
5
  from pathlib import Path
6
- from typing import Optional, Union
7
6
 
8
7
  from waldiez.models import WaldiezAgent, WaldiezTool
9
8
 
@@ -17,8 +16,8 @@ def create_tools_exporter(
17
16
  agent_names: dict[str, str],
18
17
  tools: list[WaldiezTool],
19
18
  tool_names: dict[str, str],
20
- output_dir: Optional[Union[str, Path]] = None,
21
- context: Optional[ExporterContext] = None,
19
+ output_dir: str | Path | None = None,
20
+ context: ExporterContext | None = None,
22
21
  ) -> ToolsExporter:
23
22
  """Create a tools exporter.
24
23
 
@@ -34,9 +33,9 @@ def create_tools_exporter(
34
33
  The tools to export.
35
34
  tool_names : dict[str, str]
36
35
  Mapping of tool IDs to names.
37
- output_dir : Optional[Union[str, Path]], optional
36
+ output_dir : str | Path | None, optional
38
37
  Output directory for generated files, by default None
39
- context : Optional[ExporterContext], optional
38
+ context : ExporterContext | None, optional
40
39
  Exporter context with dependencies, by default None
41
40
 
42
41
  Returns
@@ -5,7 +5,6 @@
5
5
 
6
6
  from dataclasses import dataclass, field
7
7
  from pathlib import Path
8
- from typing import Optional
9
8
 
10
9
  from waldiez.models import WaldiezTool
11
10
 
@@ -34,7 +33,7 @@ class ToolProcessor:
34
33
  flow_name: str,
35
34
  tools: list[WaldiezTool],
36
35
  tool_names: dict[str, str],
37
- output_dir: Optional[Path] = None,
36
+ output_dir: Path | None = None,
38
37
  ):
39
38
  """Initialize the tool processor.
40
39
 
@@ -46,7 +45,7 @@ class ToolProcessor:
46
45
  The tools to process.
47
46
  tool_names : dict[str, str]
48
47
  Mapping of tool IDs to names.
49
- output_dir : Optional[Path], optional
48
+ output_dir : Path | None, optional
50
49
  Output directory for generated files, by default None
51
50
  """
52
51
  self.flow_name = flow_name
@@ -217,6 +216,7 @@ ag2_{tool_name} = ag2_{tool_name}_interop.convert_tool(
217
216
  )
218
217
 
219
218
  # pylint: disable=no-self-use
219
+ # noinspection PyMethodMayBeStatic
220
220
  def _sort_imports(self, imports: list[str]) -> list[str]:
221
221
  """Sort imports: 'import' statements first, then 'from' statements.
222
222
 
@@ -99,6 +99,7 @@ class ToolRegistrationProcessor:
99
99
  return "\n".join(registrations) if registrations else ""
100
100
 
101
101
  # pylint: disable=no-self-use
102
+ # noinspection PyMethodMayBeStatic
102
103
  def _create_registration(
103
104
  self,
104
105
  caller_name: str,
waldiez/io/_ws.py CHANGED
@@ -93,6 +93,7 @@ class WebSocketsAdapter:
93
93
  The received message, decoded as a string.
94
94
  """
95
95
  # pylint: disable=too-many-try-statements
96
+ # noinspection PyBroadException
96
97
  try:
97
98
  response = await asyncio.wait_for(
98
99
  self.websocket.recv(), timeout=timeout
@@ -143,6 +144,7 @@ class StarletteAdapter:
143
144
  str
144
145
  The received message, decoded as a string.
145
146
  """
147
+ # noinspection PyBroadException
146
148
  try:
147
149
  return await asyncio.wait_for(
148
150
  self.websocket.receive_text(), timeout=timeout
@@ -11,6 +11,7 @@ from pydantic import BaseModel
11
11
  from .base import AudioContent
12
12
 
13
13
 
14
+ # noinspection PyUnusedLocal
14
15
  class AudioMediaContent(BaseModel):
15
16
  """Audio media content."""
16
17
 
@@ -11,6 +11,7 @@ from pydantic import BaseModel
11
11
  from .base import FileContent
12
12
 
13
13
 
14
+ # noinspection PyUnusedLocal
14
15
  class FileMediaContent(BaseModel):
15
16
  """File media content."""
16
17
 
@@ -12,6 +12,7 @@ from ...utils import get_image
12
12
  from .base import ImageContent
13
13
 
14
14
 
15
+ # noinspection DuplicatedCode
15
16
  class ImageMediaContent(BaseModel):
16
17
  """Image media content."""
17
18
 
@@ -9,6 +9,7 @@ from pydantic import BaseModel
9
9
  from typing_extensions import Literal
10
10
 
11
11
 
12
+ # noinspection PyUnusedLocal
12
13
  class TextMediaContent(BaseModel):
13
14
  """Text media content."""
14
15
 
@@ -11,6 +11,7 @@ from typing_extensions import Literal
11
11
  from .base import VideoContent
12
12
 
13
13
 
14
+ # noinspection PyUnusedLocal
14
15
  class VideoMediaContent(BaseModel):
15
16
  """Video media content."""
16
17
 
@@ -186,6 +186,7 @@ class UserInputData(BaseModel):
186
186
 
187
187
  return None # pragma: no cover
188
188
 
189
+ # noinspection PyNestedDecorators
189
190
  @field_validator("content", mode="before")
190
191
  @classmethod
191
192
  def validate_content(cls, v: Any) -> MediaContent: # noqa: C901,D102
@@ -21,6 +21,7 @@ class UserResponse(StructuredBase):
21
21
  type: MessageType = "input_response"
22
22
  data: UserInputData | list[UserInputData] | str
23
23
 
24
+ # noinspection PyNestedDecorators
24
25
  @field_validator("data", mode="before")
25
26
  @classmethod
26
27
  def validate_data(
waldiez/io/mqtt.py CHANGED
@@ -33,6 +33,7 @@ except ImportError as error: # pragma: no cover
33
33
  "MQTT client not installed. Please install paho-mqtt with `pip install paho-mqtt`."
34
34
  ) from error
35
35
 
36
+ from autogen.events import BaseEvent # type: ignore
36
37
  from autogen.io import IOStream # type: ignore
37
38
  from autogen.messages import BaseMessage # type: ignore
38
39
 
@@ -54,6 +55,7 @@ MQTT_MAX_RECONNECT_COUNT = 12
54
55
  MQTT_MAX_RECONNECT_DELAY = 60
55
56
 
56
57
 
58
+ # noinspection PyUnusedLocal,PyBroadException
57
59
  class MqttIOStream(IOStream):
58
60
  """MQTT I/O stream."""
59
61
 
@@ -299,6 +301,7 @@ class MqttIOStream(IOStream):
299
301
  reconnect_count += 1
300
302
  LOG.info("Reconnect failed after %s attempts.", reconnect_count)
301
303
 
304
+ # noinspection PyUnresolvedReferences
302
305
  def _on_message(
303
306
  self, client: mqtt.Client, userdata: Any, msg: mqtt.MQTTMessage
304
307
  ) -> None:
@@ -476,13 +479,13 @@ class MqttIOStream(IOStream):
476
479
  )
477
480
  self._print(payload)
478
481
 
479
- def send(self, message: BaseMessage) -> None:
482
+ def send(self, message: BaseEvent | BaseMessage) -> None:
480
483
  """Send a structured message to MQTT.
481
484
 
482
485
  Parameters
483
486
  ----------
484
- message : BaseMessage
485
- The message to send.
487
+ message : BaseEvent | BaseMessage
488
+ The message or event to send.
486
489
  """
487
490
  try:
488
491
  message_dump = message.model_dump(mode="json")
waldiez/io/redis.py CHANGED
@@ -32,6 +32,7 @@ except ImportError as error: # pragma: no cover
32
32
  ) from error
33
33
  from autogen.events import BaseEvent # type: ignore
34
34
  from autogen.io import IOStream # type: ignore
35
+ from autogen.messages import BaseMessage # type: ignore
35
36
 
36
37
  from .models import (
37
38
  PrintMessage,
@@ -52,6 +53,7 @@ else:
52
53
  LOG = logging.getLogger(__name__)
53
54
 
54
55
 
56
+ # noinspection PyBroadException
55
57
  class RedisIOStream(IOStream):
56
58
  """Redis I/O stream."""
57
59
 
@@ -158,10 +160,8 @@ class RedisIOStream(IOStream):
158
160
 
159
161
  Parameters
160
162
  ----------
161
- message : str
163
+ payload : dict[str, Any]
162
164
  The message to print.
163
- message_type : str
164
- The message type.
165
165
  """
166
166
  LOG.debug("Sending print message: %s", payload)
167
167
  RedisIOStream.try_do(
@@ -177,10 +177,8 @@ class RedisIOStream(IOStream):
177
177
 
178
178
  Parameters
179
179
  ----------
180
- message : str
180
+ payload : dict[str, Any]
181
181
  The message to print.
182
- message_type : str
183
- The message type.
184
182
  """
185
183
  LOG.debug("Sending print message: %s", payload)
186
184
  RedisIOStream.try_do(
@@ -289,12 +287,12 @@ class RedisIOStream(IOStream):
289
287
  self._print(payload)
290
288
  return user_input
291
289
 
292
- def send(self, message: BaseEvent) -> None:
290
+ def send(self, message: BaseEvent | BaseMessage) -> None:
293
291
  """Send a structured message to Redis.
294
292
 
295
293
  Parameters
296
294
  ----------
297
- message : dict[str, Any]
295
+ message : BaseEvent | BaseMessage
298
296
  The message to send.
299
297
  """
300
298
  message_dump = get_message_dump(message)
@@ -549,7 +547,7 @@ class RedisIOStream(IOStream):
549
547
 
550
548
  Parameters
551
549
  ----------
552
- func : Awaitable[Any]
550
+ func : Callable[..., Awaitable[Any]]
553
551
  The async function to call.
554
552
  args : Any
555
553
  The positional arguments.
waldiez/io/structured.py CHANGED
@@ -14,6 +14,7 @@ from uuid import uuid4
14
14
 
15
15
  from autogen.events import BaseEvent # type: ignore
16
16
  from autogen.io import IOStream # type: ignore
17
+ from autogen.messages import BaseMessage # type: ignore
17
18
 
18
19
  from .models import (
19
20
  PrintMessage,
@@ -135,12 +136,12 @@ class StructuredIOStream(IOStream):
135
136
 
136
137
  # noinspection PyMethodMayBeStatic
137
138
  # pylint: disable=no-self-use,broad-exception-caught
138
- def send(self, message: BaseEvent) -> None:
139
- """Structured sending of a BaseEvent.
139
+ def send(self, message: BaseEvent | BaseMessage) -> None:
140
+ """Structured sending of a BaseEvent or BaseMessage.
140
141
 
141
142
  Parameters
142
143
  ----------
143
- message : BaseEvent
144
+ message : BaseEvent | BaseMessage
144
145
  The message to send.
145
146
  """
146
147
  message_dump = get_message_dump(message)
@@ -251,7 +252,7 @@ class StructuredIOStream(IOStream):
251
252
  str | dict[str, Any]
252
253
  The loaded user input, either as a string or a dictionary.
253
254
  """
254
- response: str | dict[str, Any] = user_input_raw
255
+ response: str | dict[str, Any]
255
256
  try:
256
257
  # Attempt to parse the input as JSON
257
258
  response = json.loads(user_input_raw)
@@ -283,8 +284,8 @@ class StructuredIOStream(IOStream):
283
284
 
284
285
  Parameters
285
286
  ----------
286
- user_input : str
287
- The raw user input string.
287
+ user_input : dict[str, Any]
288
+ The user input dictionary containing the response data.
288
289
  request_id : str
289
290
  The request ID to match against.
290
291
 
@@ -341,6 +342,7 @@ class StructuredIOStream(IOStream):
341
342
  data="",
342
343
  )
343
344
 
345
+ # noinspection PyMethodMayBeStatic
344
346
  def _handle_list_response(
345
347
  self,
346
348
  data: list[dict[str, Any]],
waldiez/io/utils.py CHANGED
@@ -12,6 +12,7 @@ from typing import Any, Literal, Union
12
12
 
13
13
  from autogen.agentchat.contrib.img_utils import get_pil_image # type: ignore
14
14
  from autogen.events import BaseEvent # type: ignore
15
+ from autogen.messages import BaseMessage # type: ignore
15
16
 
16
17
  MessageType = Literal[
17
18
  "input_request",
@@ -169,6 +170,7 @@ def try_parse_maybe_serialized(value: str) -> Any:
169
170
  """
170
171
  for parser in (json.loads, ast.literal_eval):
171
172
  # pylint: disable=broad-exception-caught, too-many-try-statements
173
+ # noinspection PyBroadException
172
174
  try:
173
175
  parsed: dict[str, Any] | list[Any] | str = parser(value)
174
176
  # Normalize: if it's a single-item list of a string
@@ -185,14 +187,12 @@ def try_parse_maybe_serialized(value: str) -> Any:
185
187
  return value # Return original if all parsing fails
186
188
 
187
189
 
188
- def get_message_dump(
189
- message: BaseEvent,
190
- ) -> dict[str, Any]:
190
+ def get_message_dump(message: BaseEvent | BaseMessage) -> dict[str, Any]:
191
191
  """Get the message dump.
192
192
 
193
193
  Parameters
194
194
  ----------
195
- message : BaseEvent
195
+ message : BaseEvent | BaseMessage
196
196
  The message to dump.
197
197
 
198
198
  Returns
@@ -200,7 +200,14 @@ def get_message_dump(
200
200
  dict[str, Any]
201
201
  The dumped message.
202
202
  """
203
+ if not hasattr(message, "model_dump"): # pragma: no cover
204
+ return {
205
+ "error": "Message does not have model_dump method.",
206
+ "type": message.__class__.__name__,
207
+ }
208
+
203
209
  # pylint: disable=broad-exception-caught
210
+ # noinspection PyBroadException
204
211
  try:
205
212
  message_dump = message.model_dump(mode="json")
206
213
  except Exception:
waldiez/io/ws.py CHANGED
@@ -12,6 +12,7 @@ from typing import Any
12
12
 
13
13
  from autogen.events import BaseEvent # type: ignore
14
14
  from autogen.io import IOStream # type: ignore
15
+ from autogen.messages import BaseMessage # type: ignore
15
16
 
16
17
  from ._ws import (
17
18
  WebSocketConnection,
@@ -110,7 +111,7 @@ class AsyncWebsocketsIOStream(IOStream):
110
111
  ----------
111
112
  args : tuple
112
113
  The arguments to print.
113
- kwargs : dict
114
+ kwargs : Any
114
115
  The keyword arguments to print.
115
116
  """
116
117
  sep = kwargs.get("sep", " ")
@@ -134,12 +135,12 @@ class AsyncWebsocketsIOStream(IOStream):
134
135
  LOG.info(json_dump)
135
136
  self._try_send(json_dump)
136
137
 
137
- def send(self, message: BaseEvent) -> None:
138
+ def send(self, message: BaseEvent | BaseMessage) -> None:
138
139
  """Send a message to the WebSocket connection.
139
140
 
140
141
  Parameters
141
142
  ----------
142
- message : BaseEvent
143
+ message : BaseEvent | BaseMessage
143
144
  The message to send.
144
145
  """
145
146
  message_dump = get_message_dump(message)
waldiez/logger.py CHANGED
@@ -6,6 +6,7 @@
6
6
  import inspect
7
7
  import os
8
8
  import re
9
+ import string
9
10
  import threading
10
11
  import traceback
11
12
  from datetime import datetime
@@ -323,6 +324,7 @@ class WaldiezLogger:
323
324
  def _get_caller_info(cls) -> str:
324
325
  """Get caller information (filename and line number) from the stack."""
325
326
  frame = inspect.currentframe()
327
+ # noinspection PyBroadException
326
328
  try:
327
329
  if frame is None: # pragma: no cover
328
330
  return ""
@@ -377,7 +379,15 @@ class WaldiezLogger:
377
379
  @staticmethod
378
380
  def _has_format_braces(msg_str: str) -> bool:
379
381
  """Check if the message contains .format() style placeholders."""
380
- return bool(re.search(r"\{[^}]*\}", msg_str))
382
+ # noinspection PyBroadException
383
+ try:
384
+ formatter = string.Formatter()
385
+ for _, field_name, _, _ in formatter.parse(msg_str):
386
+ if field_name is not None:
387
+ return True
388
+ return False
389
+ except Exception: # pylint: disable=broad-exception-caught
390
+ return False
381
391
 
382
392
  @staticmethod
383
393
  def _has_percent_placeholders(msg_str: str) -> bool:
@@ -24,6 +24,7 @@ if TYPE_CHECKING:
24
24
  from ...chat import WaldiezChat
25
25
 
26
26
 
27
+ # noinspection PyUnresolvedReferences
27
28
  class WaldiezAgent(WaldiezBase):
28
29
  """Waldiez Agent to be inherited by all other agents.
29
30
 
@@ -146,7 +146,7 @@ class WaldiezAgentData(WaldiezBase):
146
146
  Field(
147
147
  default_factory=list,
148
148
  title="Tools",
149
- description=("A list of tools (id and executor) to register."),
149
+ description="A list of tools (id and executor) to register.",
150
150
  ),
151
151
  ] = []
152
152
  nested_chats: Annotated[
@@ -194,7 +194,7 @@ class WaldiezAgentData(WaldiezBase):
194
194
  Field(
195
195
  default_factory=list,
196
196
  title="Handoffs",
197
- description=("A list of handoffs (target ids) to register."),
197
+ description="A list of handoffs (target ids) to register.",
198
198
  ),
199
199
  ] = []
200
200
  after_work: Annotated[
@@ -50,16 +50,13 @@ class WaldiezAgentNestedChat(WaldiezBase):
50
50
  messages : list[WaldiezAgentNestedChatMessage]
51
51
  The list of messages (chat ids and 'is_reply'z)
52
52
  to include the in the nested chat registration.
53
- order : int
54
- The order of the nested chat (if used as a handoff).
55
- Defaults to 0.
56
53
  """
57
54
 
58
55
  triggered_by: Annotated[
59
56
  list[str],
60
57
  Field(
61
58
  title="Triggered By",
62
- description=("A list of agent ids that trigger the nested chat."),
59
+ description="A list of agent ids that trigger the nested chat.",
63
60
  alias="triggeredBy",
64
61
  default_factory=list,
65
62
  ),
@@ -33,13 +33,6 @@ class WaldiezAgentTerminationMessage(WaldiezBase):
33
33
  The method must be called `is_termination_message`,
34
34
  have one argument (`message`) which is a dict, and
35
35
  return a bool (whether the message is a termination message or not.)
36
- string : str
37
- The value of the termination message.
38
-
39
- Functions
40
- ---------
41
- validate_termination_message() -> Self
42
- Validate the termination message configuration.
43
36
  """
44
37
 
45
38
  type: Annotated[
@@ -27,9 +27,9 @@ class WaldiezAgentUpdateSystemMessage(WaldiezBase):
27
27
 
28
28
  Attributes
29
29
  ----------
30
- update_function_type : Literal["string", "callable"]
30
+ type : Literal["string", "callable"]
31
31
  The type of the update function. Can be either a string or a callable.
32
- update_function : str
32
+ content : str
33
33
  The string template or function definition to update
34
34
  the agent's system message. Can be a string or a Callable.
35
35
  If the `function_type` is 'string' it will be used as a