agentscope-runtime 1.0.1__py3-none-any.whl → 1.0.2__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.
- agentscope_runtime/adapters/agentscope/message.py +32 -7
- agentscope_runtime/adapters/agentscope/stream.py +121 -91
- agentscope_runtime/adapters/agno/__init__.py +0 -0
- agentscope_runtime/adapters/agno/message.py +30 -0
- agentscope_runtime/adapters/agno/stream.py +122 -0
- agentscope_runtime/adapters/langgraph/__init__.py +12 -0
- agentscope_runtime/adapters/langgraph/message.py +257 -0
- agentscope_runtime/adapters/langgraph/stream.py +205 -0
- agentscope_runtime/cli/__init__.py +7 -0
- agentscope_runtime/cli/cli.py +63 -0
- agentscope_runtime/cli/commands/__init__.py +2 -0
- agentscope_runtime/cli/commands/chat.py +815 -0
- agentscope_runtime/cli/commands/deploy.py +1062 -0
- agentscope_runtime/cli/commands/invoke.py +58 -0
- agentscope_runtime/cli/commands/list_cmd.py +103 -0
- agentscope_runtime/cli/commands/run.py +176 -0
- agentscope_runtime/cli/commands/sandbox.py +128 -0
- agentscope_runtime/cli/commands/status.py +60 -0
- agentscope_runtime/cli/commands/stop.py +185 -0
- agentscope_runtime/cli/commands/web.py +166 -0
- agentscope_runtime/cli/loaders/__init__.py +6 -0
- agentscope_runtime/cli/loaders/agent_loader.py +295 -0
- agentscope_runtime/cli/state/__init__.py +10 -0
- agentscope_runtime/cli/utils/__init__.py +18 -0
- agentscope_runtime/cli/utils/console.py +378 -0
- agentscope_runtime/cli/utils/validators.py +118 -0
- agentscope_runtime/engine/app/agent_app.py +7 -4
- agentscope_runtime/engine/deployers/__init__.py +1 -0
- agentscope_runtime/engine/deployers/agentrun_deployer.py +152 -22
- agentscope_runtime/engine/deployers/base.py +27 -2
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +158 -31
- agentscope_runtime/engine/deployers/local_deployer.py +188 -25
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +109 -18
- agentscope_runtime/engine/deployers/state/__init__.py +9 -0
- agentscope_runtime/engine/deployers/state/manager.py +388 -0
- agentscope_runtime/engine/deployers/state/schema.py +96 -0
- agentscope_runtime/engine/deployers/utils/build_cache.py +736 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +105 -30
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +31 -10
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +15 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +30 -2
- agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
- agentscope_runtime/engine/deployers/utils/package.py +56 -6
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +16 -2
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +155 -5
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +107 -123
- agentscope_runtime/engine/runner.py +25 -6
- agentscope_runtime/engine/schemas/exception.py +580 -0
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
- agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
- agentscope_runtime/sandbox/utils.py +2 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/METADATA +24 -7
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/RECORD +58 -28
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/entry_points.txt +1 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Console output utilities for CLI using Rich library."""
|
|
3
|
+
|
|
4
|
+
import io
|
|
5
|
+
import json
|
|
6
|
+
from typing import Optional, Any
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from rich.json import JSON
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Centralized style configuration
|
|
15
|
+
CONSOLE_CONFIG = {
|
|
16
|
+
"success": {
|
|
17
|
+
"emoji": "✓",
|
|
18
|
+
"style": "bold green",
|
|
19
|
+
},
|
|
20
|
+
"error": {
|
|
21
|
+
"emoji": "✗",
|
|
22
|
+
"style": "bold red",
|
|
23
|
+
},
|
|
24
|
+
"warning": {
|
|
25
|
+
"emoji": "⚠",
|
|
26
|
+
"style": "bold yellow",
|
|
27
|
+
},
|
|
28
|
+
"info": {
|
|
29
|
+
"emoji": "ℹ",
|
|
30
|
+
"style": "bold blue",
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Module-level console instances (lazy initialization)
|
|
35
|
+
_console = None
|
|
36
|
+
_err_console = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _get_console() -> Console:
|
|
40
|
+
"""Get or create the shared console instance for stdout."""
|
|
41
|
+
global _console
|
|
42
|
+
if _console is None:
|
|
43
|
+
_console = Console()
|
|
44
|
+
return _console
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _get_err_console() -> Console:
|
|
48
|
+
"""Get or create the shared console instance for stderr."""
|
|
49
|
+
global _err_console
|
|
50
|
+
if _err_console is None:
|
|
51
|
+
_err_console = Console(stderr=True)
|
|
52
|
+
return _err_console
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _process_kwargs(kwargs: dict) -> tuple[dict, str]:
|
|
56
|
+
"""
|
|
57
|
+
Process kwargs to handle Click-specific parameters.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Tuple of (rich_kwargs, end_char)
|
|
61
|
+
"""
|
|
62
|
+
# Handle Click's nl parameter
|
|
63
|
+
nl = kwargs.pop("nl", True)
|
|
64
|
+
end = "\n" if nl else ""
|
|
65
|
+
|
|
66
|
+
# Handle Click's err parameter (should be handled by console selection)
|
|
67
|
+
kwargs.pop("err", None)
|
|
68
|
+
|
|
69
|
+
# Click's color parameters - ignore, use theme instead
|
|
70
|
+
kwargs.pop("fg", None)
|
|
71
|
+
kwargs.pop("bg", None)
|
|
72
|
+
kwargs.pop("bold", None)
|
|
73
|
+
kwargs.pop("dim", None)
|
|
74
|
+
|
|
75
|
+
return kwargs, end
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def echo_success(message: str, **kwargs) -> None:
|
|
79
|
+
"""
|
|
80
|
+
Print success message in green with checkmark.
|
|
81
|
+
|
|
82
|
+
Uses Rich library for enhanced terminal output with automatic
|
|
83
|
+
cross-platform support (including Windows).
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
message: Message to display
|
|
87
|
+
**kwargs: Additional Rich Console.print() parameters
|
|
88
|
+
(e.g., highlight=False, markup=False)
|
|
89
|
+
|
|
90
|
+
Note:
|
|
91
|
+
Legacy Click kwargs (nl, err, fg, bold) are supported for
|
|
92
|
+
backward compatibility but are deprecated.
|
|
93
|
+
|
|
94
|
+
Example:
|
|
95
|
+
>>> echo_success("Deployment completed successfully")
|
|
96
|
+
✓ Deployment completed successfully
|
|
97
|
+
"""
|
|
98
|
+
console = _get_console()
|
|
99
|
+
config = CONSOLE_CONFIG["success"]
|
|
100
|
+
kwargs, end = _process_kwargs(kwargs)
|
|
101
|
+
|
|
102
|
+
formatted_message = f"{config['emoji']} {message}"
|
|
103
|
+
console.print(formatted_message, style=config["style"], end=end, **kwargs)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def echo_error(message: str, **kwargs) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Print error message in red with X mark to stderr.
|
|
109
|
+
|
|
110
|
+
Uses Rich library for enhanced terminal output with automatic
|
|
111
|
+
cross-platform support (including Windows).
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
message: Message to display
|
|
115
|
+
**kwargs: Additional Rich Console.print() parameters
|
|
116
|
+
|
|
117
|
+
Note:
|
|
118
|
+
Legacy Click kwargs (nl, err, fg, bold) are supported for
|
|
119
|
+
backward compatibility but are deprecated.
|
|
120
|
+
|
|
121
|
+
Example:
|
|
122
|
+
>>> echo_error("Deployment failed")
|
|
123
|
+
✗ Deployment failed
|
|
124
|
+
"""
|
|
125
|
+
console = _get_err_console()
|
|
126
|
+
config = CONSOLE_CONFIG["error"]
|
|
127
|
+
kwargs, end = _process_kwargs(kwargs)
|
|
128
|
+
|
|
129
|
+
formatted_message = f"{config['emoji']} {message}"
|
|
130
|
+
console.print(formatted_message, style=config["style"], end=end, **kwargs)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def echo_warning(message: str, **kwargs) -> None:
|
|
134
|
+
"""
|
|
135
|
+
Print warning message in yellow with warning symbol.
|
|
136
|
+
|
|
137
|
+
Uses Rich library for enhanced terminal output with automatic
|
|
138
|
+
cross-platform support (including Windows).
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
message: Message to display
|
|
142
|
+
**kwargs: Additional Rich Console.print() parameters
|
|
143
|
+
|
|
144
|
+
Note:
|
|
145
|
+
Legacy Click kwargs (nl, err, fg, bold) are supported for
|
|
146
|
+
backward compatibility but are deprecated.
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
>>> echo_warning("Configuration file not found, using defaults")
|
|
150
|
+
⚠ Configuration file not found, using defaults
|
|
151
|
+
"""
|
|
152
|
+
console = _get_console()
|
|
153
|
+
config = CONSOLE_CONFIG["warning"]
|
|
154
|
+
kwargs, end = _process_kwargs(kwargs)
|
|
155
|
+
|
|
156
|
+
formatted_message = f"{config['emoji']} {message}"
|
|
157
|
+
console.print(formatted_message, style=config["style"], end=end, **kwargs)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def echo_info(message: str, **kwargs) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Print info message in blue with info symbol.
|
|
163
|
+
|
|
164
|
+
Uses Rich library for enhanced terminal output with automatic
|
|
165
|
+
cross-platform support (including Windows).
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
message: Message to display
|
|
169
|
+
**kwargs: Additional Rich Console.print() parameters
|
|
170
|
+
|
|
171
|
+
Note:
|
|
172
|
+
Legacy Click kwargs (nl, err, fg, bold) are supported for
|
|
173
|
+
backward compatibility but are deprecated.
|
|
174
|
+
|
|
175
|
+
Example:
|
|
176
|
+
>>> echo_info("Loading configuration...")
|
|
177
|
+
ℹ Loading configuration...
|
|
178
|
+
"""
|
|
179
|
+
console = _get_console()
|
|
180
|
+
config = CONSOLE_CONFIG["info"]
|
|
181
|
+
kwargs, end = _process_kwargs(kwargs)
|
|
182
|
+
|
|
183
|
+
formatted_message = f"{config['emoji']} {message}"
|
|
184
|
+
console.print(formatted_message, style=config["style"], end=end, **kwargs)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def echo_header(message: str, **kwargs) -> None:
|
|
188
|
+
"""
|
|
189
|
+
Print header message in bold.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
message: Message to display
|
|
193
|
+
**kwargs: Additional Rich Console.print() parameters
|
|
194
|
+
|
|
195
|
+
Example:
|
|
196
|
+
>>> echo_header("Deployment Summary")
|
|
197
|
+
Deployment Summary
|
|
198
|
+
"""
|
|
199
|
+
console = _get_console()
|
|
200
|
+
kwargs, end = _process_kwargs(kwargs)
|
|
201
|
+
console.print(message, style="bold", end=end, **kwargs)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def echo_dim(message: str, **kwargs) -> None:
|
|
205
|
+
"""
|
|
206
|
+
Print dimmed message.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
message: Message to display
|
|
210
|
+
**kwargs: Additional Rich Console.print() parameters
|
|
211
|
+
|
|
212
|
+
Example:
|
|
213
|
+
>>> echo_dim("Additional details...")
|
|
214
|
+
Additional details...
|
|
215
|
+
"""
|
|
216
|
+
console = _get_console()
|
|
217
|
+
kwargs, end = _process_kwargs(kwargs)
|
|
218
|
+
console.print(message, style="dim", end=end, **kwargs)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def format_table(
|
|
222
|
+
headers: list[str],
|
|
223
|
+
rows: list[list[Any]],
|
|
224
|
+
max_width: Optional[int] = None,
|
|
225
|
+
) -> str:
|
|
226
|
+
"""
|
|
227
|
+
Format data as a Rich Table (returns rendered string).
|
|
228
|
+
|
|
229
|
+
Uses Rich library for enhanced table rendering with better alignment
|
|
230
|
+
and visual appeal compared to ASCII tables.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
headers: List of column headers
|
|
234
|
+
rows: List of rows, where each row is a list of cell values
|
|
235
|
+
max_width: Optional maximum width for columns
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Rendered table as a string for backward compatibility
|
|
239
|
+
|
|
240
|
+
Example:
|
|
241
|
+
>>> headers = ["ID", "Status"]
|
|
242
|
+
>>> rows = [["deploy_1", "running"], ["deploy_2", "stopped"]]
|
|
243
|
+
>>> print(format_table(headers, rows))
|
|
244
|
+
"""
|
|
245
|
+
if not rows:
|
|
246
|
+
return "No data to display."
|
|
247
|
+
|
|
248
|
+
# Create Rich table
|
|
249
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
250
|
+
|
|
251
|
+
# Add columns
|
|
252
|
+
for header in headers:
|
|
253
|
+
table.add_column(header, max_width=max_width)
|
|
254
|
+
|
|
255
|
+
# Add rows
|
|
256
|
+
for row in rows:
|
|
257
|
+
table.add_row(*[str(cell) for cell in row])
|
|
258
|
+
|
|
259
|
+
# Render table to string for backward compatibility
|
|
260
|
+
string_io = io.StringIO()
|
|
261
|
+
temp_console = Console(file=string_io, force_terminal=True)
|
|
262
|
+
temp_console.print(table)
|
|
263
|
+
return string_io.getvalue()
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def format_json(data: Any, indent: int = 2) -> str:
|
|
267
|
+
"""
|
|
268
|
+
Format data as JSON with syntax highlighting.
|
|
269
|
+
|
|
270
|
+
Uses Rich library for syntax-highlighted JSON output.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
data: Data to format as JSON
|
|
274
|
+
indent: Indentation level (default: 2)
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Rendered JSON as a string with syntax highlighting
|
|
278
|
+
|
|
279
|
+
Example:
|
|
280
|
+
>>> data = {"key": "value", "number": 123}
|
|
281
|
+
>>> print(format_json(data))
|
|
282
|
+
"""
|
|
283
|
+
# Rich's JSON requires a string, not an object
|
|
284
|
+
json_string = json.dumps(data, indent=indent, default=str)
|
|
285
|
+
|
|
286
|
+
# Render to string for backward compatibility
|
|
287
|
+
string_io = io.StringIO()
|
|
288
|
+
temp_console = Console(file=string_io, force_terminal=True)
|
|
289
|
+
temp_console.print(JSON(json_string, indent=indent))
|
|
290
|
+
return string_io.getvalue()
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def format_deployment_info(deployment: dict) -> str:
|
|
294
|
+
"""
|
|
295
|
+
Format deployment information using Rich Table.
|
|
296
|
+
|
|
297
|
+
Uses Rich library for structured key-value display.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
deployment: Dictionary containing deployment information
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
Rendered deployment info as a string
|
|
304
|
+
|
|
305
|
+
Example:
|
|
306
|
+
>>> deployment = {
|
|
307
|
+
... "id": "local_123",
|
|
308
|
+
... "platform": "local",
|
|
309
|
+
... "status": "running",
|
|
310
|
+
... "url": "http://localhost:8000",
|
|
311
|
+
... "created_at": "2025-01-01 12:00:00",
|
|
312
|
+
... "agent_source": "agent.py"
|
|
313
|
+
... }
|
|
314
|
+
>>> print(format_deployment_info(deployment))
|
|
315
|
+
"""
|
|
316
|
+
# Create table with no header for key-value pairs
|
|
317
|
+
table = Table(show_header=False, box=None, padding=(0, 2))
|
|
318
|
+
table.add_column("Key", style="bold cyan")
|
|
319
|
+
table.add_column("Value", style="white")
|
|
320
|
+
|
|
321
|
+
# Add deployment information
|
|
322
|
+
table.add_row("Deployment ID", deployment["id"])
|
|
323
|
+
table.add_row("Platform", deployment["platform"])
|
|
324
|
+
table.add_row("Status", deployment["status"])
|
|
325
|
+
table.add_row("URL", deployment["url"])
|
|
326
|
+
table.add_row("Created", deployment["created_at"])
|
|
327
|
+
table.add_row("Agent Source", deployment["agent_source"])
|
|
328
|
+
|
|
329
|
+
# Add token if present
|
|
330
|
+
if deployment.get("token"):
|
|
331
|
+
token = deployment["token"]
|
|
332
|
+
display_token = f"{token[:20]}..." if len(token) > 20 else token
|
|
333
|
+
table.add_row("Token", display_token)
|
|
334
|
+
|
|
335
|
+
# Render to string for backward compatibility
|
|
336
|
+
string_io = io.StringIO()
|
|
337
|
+
temp_console = Console(file=string_io, force_terminal=True)
|
|
338
|
+
temp_console.print(table)
|
|
339
|
+
return string_io.getvalue()
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def confirm(message: str, default: bool = False) -> bool:
|
|
343
|
+
"""
|
|
344
|
+
Prompt user for confirmation.
|
|
345
|
+
|
|
346
|
+
Uses Click's confirm function (unchanged from original implementation).
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
message: Confirmation message
|
|
350
|
+
default: Default value if user just presses Enter
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
True if user confirms, False otherwise
|
|
354
|
+
|
|
355
|
+
Example:
|
|
356
|
+
>>> if confirm("Delete deployment?"):
|
|
357
|
+
... # proceed with deletion
|
|
358
|
+
"""
|
|
359
|
+
return click.confirm(message, default=default)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def prompt(message: str, default: Optional[str] = None) -> str:
|
|
363
|
+
"""
|
|
364
|
+
Prompt user for input.
|
|
365
|
+
|
|
366
|
+
Uses Click's prompt function (unchanged from original implementation).
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
message: Prompt message
|
|
370
|
+
default: Default value if user just presses Enter
|
|
371
|
+
|
|
372
|
+
Returns:
|
|
373
|
+
User input as string
|
|
374
|
+
|
|
375
|
+
Example:
|
|
376
|
+
>>> name = prompt("Enter deployment name")
|
|
377
|
+
"""
|
|
378
|
+
return click.prompt(message, default=default)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Input validation utilities for CLI."""
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from agentscope_runtime.engine.deployers.state import DeploymentStateManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ValidationError(Exception):
|
|
10
|
+
"""Raised when validation fails."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def validate_agent_source(source: str) -> tuple[str, str]:
|
|
14
|
+
"""
|
|
15
|
+
Validate and determine the type of agent source.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
source: Path to file/directory or deployment ID
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
Tuple of (source_type, normalized_path/id)
|
|
22
|
+
source_type can be: 'file', 'directory', 'deployment_id'
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
ValidationError: If source is invalid
|
|
26
|
+
"""
|
|
27
|
+
if not source:
|
|
28
|
+
raise ValidationError("Agent source cannot be empty")
|
|
29
|
+
|
|
30
|
+
# Check if it's a file
|
|
31
|
+
if os.path.isfile(source):
|
|
32
|
+
if not source.endswith(".py"):
|
|
33
|
+
raise ValidationError(
|
|
34
|
+
f"Agent source file must be a Python file: {source}",
|
|
35
|
+
)
|
|
36
|
+
return ("file", os.path.abspath(source))
|
|
37
|
+
|
|
38
|
+
# Check if it's a directory
|
|
39
|
+
if os.path.isdir(source):
|
|
40
|
+
return ("directory", os.path.abspath(source))
|
|
41
|
+
|
|
42
|
+
# Check if it's a deployment ID by querying state manager
|
|
43
|
+
# This ensures we only accept deployment IDs that actually exist
|
|
44
|
+
# Support both formats: platform_timestamp_id (with underscore) and UUID
|
|
45
|
+
# format
|
|
46
|
+
state_manager = DeploymentStateManager()
|
|
47
|
+
if state_manager.exists(source):
|
|
48
|
+
return ("deployment_id", source)
|
|
49
|
+
|
|
50
|
+
raise ValidationError(
|
|
51
|
+
f"Invalid agent source: {source}\n"
|
|
52
|
+
"Must be a Python file (.py), directory, or deployment ID",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def validate_port(port: int) -> int:
|
|
57
|
+
"""Validate port number."""
|
|
58
|
+
if not isinstance(port, int):
|
|
59
|
+
try:
|
|
60
|
+
port = int(port)
|
|
61
|
+
except (ValueError, TypeError) as e:
|
|
62
|
+
raise ValidationError(f"Port must be an integer: {port}") from e
|
|
63
|
+
|
|
64
|
+
if port < 1 or port > 65535:
|
|
65
|
+
raise ValidationError(f"Port must be between 1 and 65535: {port}")
|
|
66
|
+
|
|
67
|
+
return port
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def validate_platform(platform: str, supported_platforms: list[str]) -> str:
|
|
71
|
+
"""Validate platform name."""
|
|
72
|
+
if platform not in supported_platforms:
|
|
73
|
+
raise ValidationError(
|
|
74
|
+
f"Unsupported platform: {platform}\n"
|
|
75
|
+
f"Supported platforms: {', '.join(supported_platforms)}",
|
|
76
|
+
)
|
|
77
|
+
return platform
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def validate_file_exists(file_path: str) -> str:
|
|
81
|
+
"""Validate that file exists."""
|
|
82
|
+
if not os.path.isfile(file_path):
|
|
83
|
+
raise ValidationError(f"File not found: {file_path}")
|
|
84
|
+
return os.path.abspath(file_path)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def validate_directory_exists(dir_path: str) -> str:
|
|
88
|
+
"""Validate that directory exists."""
|
|
89
|
+
if not os.path.isdir(dir_path):
|
|
90
|
+
raise ValidationError(f"Directory not found: {dir_path}")
|
|
91
|
+
return os.path.abspath(dir_path)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def validate_url(url: str) -> str:
|
|
95
|
+
"""Basic URL validation."""
|
|
96
|
+
if not url:
|
|
97
|
+
raise ValidationError("URL cannot be empty")
|
|
98
|
+
|
|
99
|
+
if not (url.startswith("http://") or url.startswith("https://")):
|
|
100
|
+
raise ValidationError(
|
|
101
|
+
f"URL must start with http:// or https://: {url}",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
return url
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def validate_deployment_id(deploy_id: str) -> str:
|
|
108
|
+
"""Validate deployment ID format."""
|
|
109
|
+
if not deploy_id:
|
|
110
|
+
raise ValidationError("Deployment ID cannot be empty")
|
|
111
|
+
|
|
112
|
+
if "_" not in deploy_id:
|
|
113
|
+
raise ValidationError(
|
|
114
|
+
f"Invalid deployment ID format: {deploy_id}\n"
|
|
115
|
+
"Expected format: platform_timestamp_id",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
return deploy_id
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import logging
|
|
3
|
+
import os
|
|
3
4
|
import types
|
|
4
5
|
import platform
|
|
5
6
|
import subprocess
|
|
@@ -22,6 +23,8 @@ from ..schemas.agent_schemas import AgentRequest
|
|
|
22
23
|
from ...version import __version__
|
|
23
24
|
|
|
24
25
|
logger = logging.getLogger(__name__)
|
|
26
|
+
HOST = os.getenv("HOST", "0.0.0.0")
|
|
27
|
+
PORT = int(os.getenv("PORT", "8080"))
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
class AgentApp(BaseApp):
|
|
@@ -150,8 +153,8 @@ class AgentApp(BaseApp):
|
|
|
150
153
|
|
|
151
154
|
def run(
|
|
152
155
|
self,
|
|
153
|
-
host=
|
|
154
|
-
port=
|
|
156
|
+
host=HOST,
|
|
157
|
+
port=PORT,
|
|
155
158
|
web_ui=False,
|
|
156
159
|
**kwargs,
|
|
157
160
|
):
|
|
@@ -171,7 +174,7 @@ class AgentApp(BaseApp):
|
|
|
171
174
|
|
|
172
175
|
Args:
|
|
173
176
|
host (str): Host address to bind to. Default "0.0.0.0".
|
|
174
|
-
port (int): Port number to serve the application on. Default
|
|
177
|
+
port (int): Port number to serve the application on. Default 8080.
|
|
175
178
|
web_ui (bool): If True, launches the Agentscope Web UI in a
|
|
176
179
|
separate process, pointing it to the API endpoint. This
|
|
177
180
|
allows interactive use via browser. Default False.
|
|
@@ -180,7 +183,7 @@ class AgentApp(BaseApp):
|
|
|
180
183
|
|
|
181
184
|
Example:
|
|
182
185
|
>>> app = AgentApp(app_name="MyAgent")
|
|
183
|
-
>>> app.
|
|
186
|
+
>>> app.chat(host="127.0.0.1", port=8080, web_ui=True)
|
|
184
187
|
"""
|
|
185
188
|
# Build runner
|
|
186
189
|
self._build_runner()
|