waldiez 0.5.8__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 +8 -6
  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.8.dist-info → waldiez-0.5.10.dist-info}/METADATA +74 -74
  83. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/RECORD +87 -65
  84. waldiez/running/patch_io_stream.py +0 -210
  85. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/WHEEL +0 -0
  86. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/entry_points.txt +0 -0
  87. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/licenses/LICENSE +0 -0
  88. {waldiez-0.5.8.dist-info → waldiez-0.5.10.dist-info}/licenses/NOTICE.md +0 -0
waldiez/ws/cli.py ADDED
@@ -0,0 +1,211 @@
1
+ # SPDX-License-Identifier: Apache-2.0.
2
+ # Copyright (c) 2024 - 2025 Waldiez and contributors.
3
+ # pylint: disable=too-many-locals
4
+ """CLI interface for Waldiez WebSocket server."""
5
+
6
+ import asyncio
7
+ import logging
8
+ import re
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import Annotated, Any, Optional, Set
12
+
13
+ import typer
14
+
15
+ from .server import run_server
16
+
17
+ DEFAULT_WORKSPACE_DIR = Path.cwd()
18
+
19
+
20
+ def setup_logging(verbose: bool = False) -> None:
21
+ """Set up logging configuration.
22
+
23
+ Parameters
24
+ ----------
25
+ verbose : bool
26
+ Enable verbose logging
27
+ """
28
+ level = logging.DEBUG if verbose else logging.INFO
29
+ format_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
30
+
31
+ logging.basicConfig(
32
+ level=level,
33
+ format=format_str,
34
+ handlers=[logging.StreamHandler(sys.stdout)],
35
+ )
36
+
37
+ # Set websockets logger to WARNING to reduce noise
38
+ logging.getLogger("websockets").setLevel(logging.WARNING)
39
+
40
+
41
+ app = typer.Typer(
42
+ name="waldiez-ws",
43
+ help="Waldiez WebSocket server",
44
+ add_completion=False,
45
+ context_settings={
46
+ "help_option_names": ["-h", "--help"],
47
+ "allow_extra_args": True,
48
+ "ignore_unknown_options": True,
49
+ },
50
+ )
51
+
52
+
53
+ @app.command()
54
+ def serve(
55
+ host: Annotated[
56
+ str, typer.Option(help="Server host address")
57
+ ] = "localhost",
58
+ port: Annotated[int, typer.Option(help="Server port")] = 8765,
59
+ max_clients: Annotated[
60
+ int,
61
+ typer.Option(
62
+ "--max-clients", help="Maximum number of concurrent clients"
63
+ ),
64
+ ] = 1,
65
+ allowed_origins: Annotated[
66
+ Optional[list[str]],
67
+ typer.Option(
68
+ "--allowed-origin",
69
+ help=(
70
+ "Allowed origins for CORS (can be used multiple times). "
71
+ "Supports regex patterns. "
72
+ "Examples: 'https://example.com', '.*\\.mydomain\\.com'"
73
+ ),
74
+ ),
75
+ ] = None,
76
+ auto_reload: Annotated[
77
+ bool,
78
+ typer.Option(
79
+ "--auto-reload",
80
+ help=(
81
+ "Enable auto-reload on file changes "
82
+ "(requires: pip install watchdog)"
83
+ ),
84
+ ),
85
+ ] = False,
86
+ watch_dir: Annotated[
87
+ Optional[list[Path]],
88
+ typer.Option(
89
+ "--watch-dir",
90
+ help=(
91
+ "Additional directories to watch for auto-reload "
92
+ "(can be used multiple times)"
93
+ ),
94
+ ),
95
+ ] = None,
96
+ workspace_dir: Annotated[
97
+ Path,
98
+ typer.Option(
99
+ "--workspace",
100
+ help="Path to the workspace directory",
101
+ resolve_path=True,
102
+ dir_okay=True,
103
+ file_okay=False,
104
+ ),
105
+ ] = DEFAULT_WORKSPACE_DIR,
106
+ ping_interval: Annotated[
107
+ float,
108
+ typer.Option(
109
+ "--ping-interval", help="WebSocket ping interval in seconds"
110
+ ),
111
+ ] = 20.0,
112
+ ping_timeout: Annotated[
113
+ float,
114
+ typer.Option(
115
+ "--ping-timeout", help="WebSocket ping timeout in seconds"
116
+ ),
117
+ ] = 20.0,
118
+ max_size: Annotated[
119
+ int, typer.Option("--max-size", help="Maximum message size in bytes")
120
+ ] = 8388608,
121
+ verbose: Annotated[
122
+ bool, typer.Option("--verbose", "-v", help="Enable verbose logging")
123
+ ] = False,
124
+ ) -> None:
125
+ """Start Waldiez WebSocket server.
126
+
127
+ Parameters
128
+ ----------
129
+ host : str
130
+ Server host address
131
+ port : int
132
+ Server port
133
+ max_clients : int
134
+ Maximum number of concurrent clients
135
+ allowed_origins : list[str] | None
136
+ List of allowed origins for CORS (default: None)
137
+ auto_reload : bool
138
+ Enable auto-reload on file changes
139
+ watch_dir : tuple[Path, ...]
140
+ Additional directories to watch for auto-reload
141
+ workspace_dir : Path
142
+ Path to the workspace directory
143
+ ping_interval : float
144
+ WebSocket ping interval in seconds
145
+ ping_timeout : float
146
+ WebSocket ping timeout in seconds
147
+ max_size : int
148
+ Maximum message size in bytes
149
+ verbose : bool
150
+ Enable verbose logging
151
+ """
152
+ setup_logging(verbose)
153
+
154
+ logger = logging.getLogger(__name__)
155
+
156
+ # Convert watch directories to set
157
+ watch_dirs: Optional[Set[Path]] = None
158
+ if watch_dir:
159
+ watch_dirs = set(watch_dir)
160
+
161
+ compiled_origins: list[re.Pattern[str]] | None = None
162
+ if allowed_origins:
163
+ try:
164
+ compiled_origins = [
165
+ re.compile(pattern) for pattern in allowed_origins
166
+ ]
167
+ except re.error as e:
168
+ typer.echo(f"Invalid regex pattern in allowed origins: {e}")
169
+ sys.exit(1)
170
+
171
+ # Server configuration
172
+ server_config: dict[str, Any] = {
173
+ "max_clients": max_clients,
174
+ "allowed_origins": compiled_origins,
175
+ "ping_interval": ping_interval,
176
+ "ping_timeout": ping_timeout,
177
+ "max_size": max_size,
178
+ }
179
+
180
+ logger.info("Starting Waldiez WebSocket server...")
181
+ logger.info("Configuration:")
182
+ logger.info(" Host: %s", host)
183
+ logger.info(" Port: %d", port)
184
+ logger.info(" Max clients: %d", max_clients)
185
+ logger.info(" Allowed origins: %s", allowed_origins or ["*"])
186
+ logger.info(" Auto-reload: %s", auto_reload)
187
+ logger.info(" Workspace directory: %s", workspace_dir)
188
+
189
+ if watch_dirs:
190
+ logger.info(" Watch directories: %s", watch_dirs)
191
+
192
+ try:
193
+ asyncio.run(
194
+ run_server(
195
+ host=host,
196
+ port=port,
197
+ workspace_dir=workspace_dir,
198
+ auto_reload=auto_reload,
199
+ watch_dirs=watch_dirs,
200
+ **server_config,
201
+ )
202
+ )
203
+ except KeyboardInterrupt:
204
+ logger.info("Server stopped by user")
205
+ except Exception as e: # pylint: disable=broad-exception-caught
206
+ logger.error("Server error: %s", e)
207
+ sys.exit(1)
208
+
209
+
210
+ if __name__ == "__main__":
211
+ app()