agentscope-runtime 1.0.0b2__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 +78 -10
- agentscope_runtime/adapters/agentscope/stream.py +155 -101
- agentscope_runtime/adapters/agentscope/tool/tool.py +1 -3
- 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 +15 -5
- agentscope_runtime/engine/deployers/__init__.py +1 -0
- agentscope_runtime/engine/deployers/agentrun_deployer.py +154 -24
- 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 +68 -9
- 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 +32 -12
- agentscope_runtime/engine/schemas/agent_schemas.py +21 -7
- agentscope_runtime/engine/schemas/exception.py +580 -0
- agentscope_runtime/engine/services/agent_state/__init__.py +2 -0
- agentscope_runtime/engine/services/agent_state/state_service_factory.py +55 -0
- agentscope_runtime/engine/services/memory/__init__.py +2 -0
- agentscope_runtime/engine/services/memory/memory_service_factory.py +126 -0
- agentscope_runtime/engine/services/sandbox/__init__.py +2 -0
- agentscope_runtime/engine/services/sandbox/sandbox_service_factory.py +49 -0
- agentscope_runtime/engine/services/service_factory.py +119 -0
- agentscope_runtime/engine/services/session_history/__init__.py +2 -0
- agentscope_runtime/engine/services/session_history/session_history_service_factory.py +73 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +35 -10
- agentscope_runtime/engine/tracing/wrapper.py +49 -31
- 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.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/METADATA +82 -11
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/RECORD +71 -36
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/entry_points.txt +1 -0
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
# pylint:disable=too-many-return-statements
|
|
2
|
+
# pylint:disable=too-many-return-statements, too-many-branches
|
|
3
3
|
|
|
4
4
|
"""Shared helpers for building detached deployment bundles."""
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
7
|
|
|
9
8
|
import json
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
10
11
|
import shutil
|
|
11
12
|
import tempfile
|
|
12
13
|
import zipfile
|
|
@@ -14,10 +15,14 @@ from pathlib import Path
|
|
|
14
15
|
from typing import Any, Dict, List, Optional, Tuple, Type, Union
|
|
15
16
|
|
|
16
17
|
from .app_runner_utils import ensure_runner_from_app
|
|
17
|
-
from .package import
|
|
18
|
+
from .package import (
|
|
19
|
+
package,
|
|
20
|
+
ProjectInfo,
|
|
21
|
+
DEFAULT_ENTRYPOINT_FILE,
|
|
22
|
+
DEPLOYMENT_ZIP,
|
|
23
|
+
generate_build_directory,
|
|
24
|
+
)
|
|
18
25
|
from ..adapter.protocol_adapter import ProtocolAdapter
|
|
19
|
-
from .package import DEPLOYMENT_ZIP
|
|
20
|
-
from .wheel_packager import _parse_pyproject_toml
|
|
21
26
|
|
|
22
27
|
try:
|
|
23
28
|
import tomllib # Python 3.11+
|
|
@@ -36,19 +41,25 @@ def build_detached_app(
|
|
|
36
41
|
*,
|
|
37
42
|
app=None,
|
|
38
43
|
runner=None,
|
|
44
|
+
entrypoint: Optional[str] = None,
|
|
39
45
|
requirements: Optional[Union[str, List[str]]] = None,
|
|
40
46
|
extra_packages: Optional[List[str]] = None,
|
|
41
47
|
output_dir: Optional[str] = None,
|
|
42
48
|
dockerfile_path: Optional[str] = None,
|
|
43
49
|
use_local_runtime: Optional[bool] = None,
|
|
50
|
+
platform: str = "unknown",
|
|
44
51
|
**kwargs,
|
|
45
52
|
) -> Tuple[str, ProjectInfo]:
|
|
46
53
|
"""
|
|
47
54
|
Create a detached bundle directory ready for execution.
|
|
48
55
|
|
|
56
|
+
All temporary files are created in cwd/.agentscope_runtime/ by default.
|
|
57
|
+
|
|
49
58
|
Args:
|
|
50
59
|
app: AgentApp instance to deploy
|
|
51
60
|
runner: Runner instance to deploy
|
|
61
|
+
entrypoint: Entrypoint specification (e.g., "app.py" or
|
|
62
|
+
"app.py:handler")
|
|
52
63
|
requirements: Additional pip requirements (string or list)
|
|
53
64
|
extra_packages: Additional Python packages to include
|
|
54
65
|
output_dir: Output directory (creates temp dir if None)
|
|
@@ -64,8 +75,8 @@ def build_detached_app(
|
|
|
64
75
|
if app is not None and runner is None:
|
|
65
76
|
runner = ensure_runner_from_app(app)
|
|
66
77
|
|
|
67
|
-
if runner is None and app is None:
|
|
68
|
-
raise ValueError("Either app or runner must be provided")
|
|
78
|
+
if runner is None and app is None and entrypoint is None:
|
|
79
|
+
raise ValueError("Either app or runner or entrypoint must be provided")
|
|
69
80
|
|
|
70
81
|
normalized_requirements = _normalize_requirements(requirements)
|
|
71
82
|
|
|
@@ -75,17 +86,18 @@ def build_detached_app(
|
|
|
75
86
|
shutil.rmtree(build_root)
|
|
76
87
|
build_root.mkdir(parents=True, exist_ok=True)
|
|
77
88
|
else:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
),
|
|
82
|
-
)
|
|
89
|
+
# Use generate_build_directory for consistent naming
|
|
90
|
+
build_root = generate_build_directory(platform)
|
|
91
|
+
build_root.mkdir(parents=True, exist_ok=True)
|
|
83
92
|
|
|
84
93
|
package_path, project_info = package(
|
|
85
94
|
app=app,
|
|
86
95
|
runner=None if app is not None else runner,
|
|
96
|
+
entrypoint=entrypoint,
|
|
87
97
|
output_dir=str(build_root),
|
|
88
98
|
extra_packages=extra_packages,
|
|
99
|
+
requirements=normalized_requirements,
|
|
100
|
+
platform=platform,
|
|
89
101
|
**kwargs,
|
|
90
102
|
)
|
|
91
103
|
|
|
@@ -102,12 +114,7 @@ def build_detached_app(
|
|
|
102
114
|
with zipfile.ZipFile(deployment_zip, "r") as archive:
|
|
103
115
|
archive.extractall(project_root)
|
|
104
116
|
|
|
105
|
-
|
|
106
|
-
if use_local_runtime is None:
|
|
107
|
-
package_version = _get_package_version()
|
|
108
|
-
use_local_runtime = _is_dev_version(package_version)
|
|
109
|
-
|
|
110
|
-
_append_additional_requirements(
|
|
117
|
+
append_project_requirements(
|
|
111
118
|
project_root,
|
|
112
119
|
normalized_requirements,
|
|
113
120
|
use_local_runtime=use_local_runtime,
|
|
@@ -146,10 +153,10 @@ def _normalize_requirements(
|
|
|
146
153
|
return [str(item) for item in requirements]
|
|
147
154
|
|
|
148
155
|
|
|
149
|
-
def
|
|
156
|
+
def append_project_requirements(
|
|
150
157
|
extraction_dir: Path,
|
|
151
|
-
additional_requirements:
|
|
152
|
-
use_local_runtime: bool = False,
|
|
158
|
+
additional_requirements: Optional[Union[str, list]],
|
|
159
|
+
use_local_runtime: Optional[bool] = False,
|
|
153
160
|
) -> None:
|
|
154
161
|
"""
|
|
155
162
|
Append requirements to requirements.txt.
|
|
@@ -163,16 +170,15 @@ def _append_additional_requirements(
|
|
|
163
170
|
use_local_runtime: If True, build and use local runtime wheel.
|
|
164
171
|
Useful for development when runtime is not released.
|
|
165
172
|
"""
|
|
173
|
+
# Auto-detect if not specified
|
|
174
|
+
if use_local_runtime is None:
|
|
175
|
+
use_local_runtime = os.getenv("USE_LOCAL_RUNTIME", "False") == "True"
|
|
176
|
+
|
|
166
177
|
req_path = extraction_dir / "requirements.txt"
|
|
167
178
|
package_version = _get_package_version()
|
|
168
179
|
|
|
169
|
-
# Auto-detect if we should use local runtime
|
|
170
|
-
should_use_local = use_local_runtime or (
|
|
171
|
-
package_version and _is_dev_version(package_version)
|
|
172
|
-
)
|
|
173
|
-
|
|
174
180
|
with open(str(req_path), "w", encoding="utf-8") as f:
|
|
175
|
-
if
|
|
181
|
+
if use_local_runtime:
|
|
176
182
|
# Create wheels subdirectory
|
|
177
183
|
# Get base requirements from pyproject.toml
|
|
178
184
|
runtime_source = _get_runtime_source_path()
|
|
@@ -203,8 +209,6 @@ def _append_additional_requirements(
|
|
|
203
209
|
"fastapi",
|
|
204
210
|
"uvicorn",
|
|
205
211
|
f"agentscope-runtime=={package_version}",
|
|
206
|
-
f"agentscope-runtime[sandbox]=={package_version}",
|
|
207
|
-
f"agentscope-runtime[deployment]=={package_version}",
|
|
208
212
|
"pydantic",
|
|
209
213
|
"jinja2", # For template rendering
|
|
210
214
|
"psutil", # For process management
|
|
@@ -218,6 +222,9 @@ def _append_additional_requirements(
|
|
|
218
222
|
if not additional_requirements:
|
|
219
223
|
additional_requirements = []
|
|
220
224
|
|
|
225
|
+
if isinstance(additional_requirements, str):
|
|
226
|
+
additional_requirements = additional_requirements.split(",")
|
|
227
|
+
|
|
221
228
|
# Combine base requirements with user requirements
|
|
222
229
|
all_requirements = sorted(
|
|
223
230
|
list(
|
|
@@ -230,6 +237,72 @@ def _append_additional_requirements(
|
|
|
230
237
|
f.write(f"{req}\n")
|
|
231
238
|
|
|
232
239
|
|
|
240
|
+
def _parse_pyproject_toml(pyproject_path: Path) -> List[str]:
|
|
241
|
+
deps: List[str] = []
|
|
242
|
+
if not pyproject_path.is_file():
|
|
243
|
+
return deps
|
|
244
|
+
text = pyproject_path.read_text(encoding="utf-8")
|
|
245
|
+
|
|
246
|
+
try:
|
|
247
|
+
# Prefer stdlib tomllib (Python 3.11+)
|
|
248
|
+
if tomllib is None:
|
|
249
|
+
raise RuntimeError("tomllib not available")
|
|
250
|
+
data = tomllib.loads(text)
|
|
251
|
+
# PEP 621
|
|
252
|
+
proj = data.get("project") or {}
|
|
253
|
+
deps.extend(proj.get("dependencies") or [])
|
|
254
|
+
# Poetry fallback
|
|
255
|
+
poetry = (data.get("tool") or {}).get("poetry") or {}
|
|
256
|
+
poetry_deps = poetry.get("dependencies") or {}
|
|
257
|
+
for name, spec in poetry_deps.items():
|
|
258
|
+
if name.lower() == "python":
|
|
259
|
+
continue
|
|
260
|
+
if isinstance(spec, str):
|
|
261
|
+
deps.append(f"{name}{spec if spec.strip() else ''}")
|
|
262
|
+
elif isinstance(spec, dict):
|
|
263
|
+
version = spec.get("version")
|
|
264
|
+
if version:
|
|
265
|
+
deps.append(f"{name}{version}")
|
|
266
|
+
else:
|
|
267
|
+
deps.append(name)
|
|
268
|
+
except Exception:
|
|
269
|
+
# Minimal non-toml parser fallback
|
|
270
|
+
block_match = re.search(
|
|
271
|
+
r"dependencies\s*=\s*\[(.*?)\]",
|
|
272
|
+
text,
|
|
273
|
+
re.S | re.I,
|
|
274
|
+
)
|
|
275
|
+
if block_match:
|
|
276
|
+
block = block_match.group(1)
|
|
277
|
+
for m in re.finditer(r"['\"]([^'\"]+)['\"]", block):
|
|
278
|
+
deps.append(m.group(1))
|
|
279
|
+
# Poetry fallback: very limited, heuristic
|
|
280
|
+
poetry_block = re.search(
|
|
281
|
+
r"\[tool\.poetry\.dependencies\](.*?)\n\[",
|
|
282
|
+
text,
|
|
283
|
+
re.S,
|
|
284
|
+
)
|
|
285
|
+
if poetry_block:
|
|
286
|
+
for line in poetry_block.group(1).splitlines():
|
|
287
|
+
line = line.strip()
|
|
288
|
+
if not line or line.startswith("#"):
|
|
289
|
+
continue
|
|
290
|
+
if ":" in line:
|
|
291
|
+
# name = "^1.2.3"
|
|
292
|
+
m = re.match(
|
|
293
|
+
r"([A-Za-z0-9_.-]+)\s*=\s*['\"]([^'\"]+)['\"]",
|
|
294
|
+
line,
|
|
295
|
+
)
|
|
296
|
+
if m and m.group(1).lower() != "python":
|
|
297
|
+
deps.append(f"{m.group(1)}{m.group(2)}")
|
|
298
|
+
else:
|
|
299
|
+
# name without version
|
|
300
|
+
name = line.split("#")[0].strip()
|
|
301
|
+
if name and name.lower() != "python":
|
|
302
|
+
deps.append(name)
|
|
303
|
+
return deps
|
|
304
|
+
|
|
305
|
+
|
|
233
306
|
def _get_package_version() -> str:
|
|
234
307
|
"""
|
|
235
308
|
Get the package version from pyproject.toml file.
|
|
@@ -496,7 +569,9 @@ def _write_bundle_meta(bundle_dir: Path, entry_script: str) -> None:
|
|
|
496
569
|
meta_path.write_text(json.dumps(meta, indent=2), encoding="utf-8")
|
|
497
570
|
|
|
498
571
|
|
|
499
|
-
def get_bundle_entry_script(bundle_dir: Union[str, Path]) -> str:
|
|
572
|
+
def get_bundle_entry_script(bundle_dir: Optional[Union[str, Path]]) -> str:
|
|
573
|
+
if bundle_dir is None:
|
|
574
|
+
return DEFAULT_ENTRYPOINT_FILE
|
|
500
575
|
meta_path = Path(bundle_dir) / META_FILENAME
|
|
501
576
|
if meta_path.exists():
|
|
502
577
|
try:
|
|
@@ -17,11 +17,13 @@ class RegistryConfig(BaseModel):
|
|
|
17
17
|
registry_url: str = ""
|
|
18
18
|
username: str = None
|
|
19
19
|
password: str = None
|
|
20
|
-
namespace: str = "agentscope-runtime"
|
|
20
|
+
namespace: Optional[str] = "agentscope-runtime"
|
|
21
21
|
image_pull_secret: str = None
|
|
22
22
|
|
|
23
23
|
def get_full_url(self) -> str:
|
|
24
24
|
# Handle different registry URL formats
|
|
25
|
+
if self.registry_url == "localhost":
|
|
26
|
+
return self.registry_url
|
|
25
27
|
return f"{self.registry_url}/{self.namespace}"
|
|
26
28
|
|
|
27
29
|
|
|
@@ -201,27 +203,21 @@ class DockerImageBuilder:
|
|
|
201
203
|
error_msg,
|
|
202
204
|
) from e
|
|
203
205
|
|
|
204
|
-
def
|
|
206
|
+
def tag_image(
|
|
205
207
|
self,
|
|
206
208
|
image_name: str,
|
|
207
209
|
registry_config: Optional[RegistryConfig] = None,
|
|
208
|
-
quiet: bool = False,
|
|
209
210
|
) -> str:
|
|
210
211
|
"""
|
|
211
|
-
|
|
212
|
+
Tag image with registry info.
|
|
212
213
|
|
|
213
214
|
Args:
|
|
214
215
|
image_name: Full image name to push
|
|
215
216
|
registry_config: Optional registry config
|
|
216
217
|
(uses instance config if None)
|
|
217
|
-
quiet: Whether to suppress output
|
|
218
218
|
|
|
219
219
|
Returns:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
Raises:
|
|
223
|
-
subprocess.CalledProcessError: If push fails
|
|
224
|
-
ValueError: If no registry configuration is available
|
|
220
|
+
registry_image_name: Full image name with url
|
|
225
221
|
"""
|
|
226
222
|
config = registry_config
|
|
227
223
|
if not config:
|
|
@@ -240,6 +236,31 @@ class DockerImageBuilder:
|
|
|
240
236
|
)
|
|
241
237
|
else:
|
|
242
238
|
registry_image_name = image_name
|
|
239
|
+
return registry_image_name
|
|
240
|
+
|
|
241
|
+
def push_image(
|
|
242
|
+
self,
|
|
243
|
+
image_name: str,
|
|
244
|
+
registry_config: Optional[RegistryConfig] = None,
|
|
245
|
+
quiet: bool = False,
|
|
246
|
+
) -> str:
|
|
247
|
+
"""
|
|
248
|
+
Push image to registry.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
image_name: Full image name to push
|
|
252
|
+
registry_config: Optional registry config
|
|
253
|
+
(uses instance config if None)
|
|
254
|
+
quiet: Whether to suppress output
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
str: Full image name that was pushed
|
|
258
|
+
|
|
259
|
+
Raises:
|
|
260
|
+
subprocess.CalledProcessError: If push fails
|
|
261
|
+
ValueError: If no registry configuration is available
|
|
262
|
+
"""
|
|
263
|
+
registry_image_name = self.tag_image(image_name, registry_config)
|
|
243
264
|
|
|
244
265
|
try:
|
|
245
266
|
push_cmd = ["docker", "push", registry_image_name]
|
|
@@ -21,6 +21,7 @@ class DockerfileConfig(BaseModel):
|
|
|
21
21
|
startup_command: Optional[str] = None
|
|
22
22
|
health_check_endpoint: str = "/health"
|
|
23
23
|
custom_template: Optional[str] = None
|
|
24
|
+
platform: Optional[str] = None
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class DockerfileGenerator:
|
|
@@ -31,7 +32,7 @@ class DockerfileGenerator:
|
|
|
31
32
|
|
|
32
33
|
# Default Dockerfile template for Python applications
|
|
33
34
|
DEFAULT_TEMPLATE = """# Use official Python runtime as base image
|
|
34
|
-
FROM {base_image}
|
|
35
|
+
FROM --platform={platform} {base_image}
|
|
35
36
|
|
|
36
37
|
# Set working directory in container
|
|
37
38
|
WORKDIR /app
|
|
@@ -43,15 +44,20 @@ ENV PYTHONUNBUFFERED=1
|
|
|
43
44
|
# Configure package sources for better performance
|
|
44
45
|
RUN rm -f /etc/apt/sources.list.d/*.list
|
|
45
46
|
|
|
46
|
-
#
|
|
47
|
-
RUN echo "deb https://mirrors.aliyun.com/debian/ bookworm main contrib "
|
|
48
|
-
"non-free non-free-firmware" > /etc/apt/sources.list &&
|
|
49
|
-
echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main "
|
|
50
|
-
"contrib non-free non-free-firmware" >> /etc/apt/sources.list &&
|
|
51
|
-
echo "deb https://mirrors.aliyun.com/debian-security/ "
|
|
52
|
-
"bookworm-security main contrib non-free "
|
|
47
|
+
# add aliyun mirrors
|
|
48
|
+
RUN echo "deb https://mirrors.aliyun.com/debian/ bookworm main contrib " \
|
|
49
|
+
"non-free non-free-firmware" > /etc/apt/sources.list && \
|
|
50
|
+
echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main " \
|
|
51
|
+
"contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
|
52
|
+
echo "deb https://mirrors.aliyun.com/debian-security/ " \
|
|
53
|
+
"bookworm-security main contrib non-free " \
|
|
53
54
|
"non-free-firmware" >> /etc/apt/sources.list
|
|
54
55
|
|
|
56
|
+
# replace debian to aliyun
|
|
57
|
+
RUN mkdir -p /etc/apt/sources.list.d && \
|
|
58
|
+
cat > /etc/apt/sources.list.d/debian.sources <<'EOF'
|
|
59
|
+
EOF
|
|
60
|
+
|
|
55
61
|
# Clean up package lists
|
|
56
62
|
RUN rm -rf /var/lib/apt/lists/*
|
|
57
63
|
|
|
@@ -140,6 +146,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\
|
|
|
140
146
|
additional_packages_section=additional_packages_section,
|
|
141
147
|
env_vars_section=env_vars_section,
|
|
142
148
|
startup_command_section=startup_command_section,
|
|
149
|
+
platform=config.platform,
|
|
143
150
|
)
|
|
144
151
|
|
|
145
152
|
return content
|
|
@@ -28,7 +28,7 @@ class ImageConfig(BaseModel):
|
|
|
28
28
|
# Package configuration
|
|
29
29
|
requirements: Optional[List[str]] = None
|
|
30
30
|
extra_packages: Optional[List[str]] = None
|
|
31
|
-
build_context_dir: str =
|
|
31
|
+
build_context_dir: Optional[str] = None
|
|
32
32
|
endpoint_path: str = "/process"
|
|
33
33
|
protocol_adapters: Optional[List] = None # New: protocol adapters
|
|
34
34
|
custom_endpoints: Optional[
|
|
@@ -171,6 +171,8 @@ class ImageFactory:
|
|
|
171
171
|
app,
|
|
172
172
|
runner: Optional[Runner],
|
|
173
173
|
config: ImageConfig,
|
|
174
|
+
entrypoint: Optional[str] = None,
|
|
175
|
+
use_cache: bool = True,
|
|
174
176
|
) -> str:
|
|
175
177
|
"""
|
|
176
178
|
Build a complete Docker image for the Runner.
|
|
@@ -181,9 +183,15 @@ class ImageFactory:
|
|
|
181
183
|
3. Build Docker image
|
|
182
184
|
4. Optionally push to registry
|
|
183
185
|
|
|
186
|
+
All temporary files are created in cwd/.agentscope_runtime/ by default.
|
|
187
|
+
|
|
184
188
|
Args:
|
|
189
|
+
app: Agent app object
|
|
185
190
|
runner: Runner object containing agent and managers
|
|
186
191
|
config: Configuration for the image building process
|
|
192
|
+
entrypoint: Entrypoint specification (e.g., "app.py" or
|
|
193
|
+
"app.py:handler")
|
|
194
|
+
use_cache: Enable build cache (default: True)
|
|
187
195
|
|
|
188
196
|
Returns:
|
|
189
197
|
str: Full image name (with registry if pushed)
|
|
@@ -209,6 +217,7 @@ class ImageFactory:
|
|
|
209
217
|
port=config.port,
|
|
210
218
|
env_vars=config.env_vars,
|
|
211
219
|
startup_command=startup_command,
|
|
220
|
+
platform=config.platform,
|
|
212
221
|
)
|
|
213
222
|
|
|
214
223
|
dockerfile_path = self.dockerfile_generator.create_dockerfile(
|
|
@@ -222,10 +231,13 @@ class ImageFactory:
|
|
|
222
231
|
project_dir, _ = build_detached_app(
|
|
223
232
|
app=app,
|
|
224
233
|
runner=runner,
|
|
234
|
+
entrypoint=entrypoint,
|
|
225
235
|
requirements=config.requirements,
|
|
226
236
|
extra_packages=config.extra_packages,
|
|
227
237
|
output_dir=config.build_context_dir,
|
|
228
238
|
dockerfile_path=dockerfile_path,
|
|
239
|
+
use_cache=use_cache,
|
|
240
|
+
platform="k8s",
|
|
229
241
|
)
|
|
230
242
|
is_updated = True
|
|
231
243
|
logger.info(f"Project packaged: {project_dir}")
|
|
@@ -260,6 +272,15 @@ class ImageFactory:
|
|
|
260
272
|
config=build_config,
|
|
261
273
|
source_updated=is_updated,
|
|
262
274
|
)
|
|
275
|
+
logger.info(f"Image built: {full_image_name}")
|
|
276
|
+
|
|
277
|
+
# make sure tag the image if not push
|
|
278
|
+
registry_full_name = self.image_builder.tag_image(
|
|
279
|
+
full_image_name,
|
|
280
|
+
config.registry_config,
|
|
281
|
+
)
|
|
282
|
+
logger.info(f"Image tag to: {registry_full_name}")
|
|
283
|
+
|
|
263
284
|
logger.info(f"Image built locally: {full_image_name}")
|
|
264
285
|
|
|
265
286
|
return full_image_name
|
|
@@ -276,6 +297,7 @@ class ImageFactory:
|
|
|
276
297
|
self,
|
|
277
298
|
app=None,
|
|
278
299
|
runner: Optional[Runner] = None,
|
|
300
|
+
entrypoint: Optional[str] = None,
|
|
279
301
|
requirements: Optional[Union[str, List[str]]] = None,
|
|
280
302
|
extra_packages: Optional[List[str]] = None,
|
|
281
303
|
base_image: str = "python:3.10-slim-bookworm",
|
|
@@ -291,14 +313,19 @@ class ImageFactory:
|
|
|
291
313
|
host: str = "0.0.0.0",
|
|
292
314
|
embed_task_processor: bool = True,
|
|
293
315
|
extra_startup_args: Optional[Dict[str, Union[str, int, bool]]] = None,
|
|
316
|
+
use_cache: bool = True,
|
|
294
317
|
**kwargs,
|
|
295
318
|
) -> str:
|
|
296
319
|
"""
|
|
297
320
|
Simplified interface for building Runner images.
|
|
298
321
|
|
|
322
|
+
All temporary files are created in cwd/.agentscope_runtime/ by default.
|
|
323
|
+
|
|
299
324
|
Args:
|
|
300
325
|
app: agent app object
|
|
301
326
|
runner: Runner object
|
|
327
|
+
entrypoint: Entrypoint specification (e.g., "app.py" or
|
|
328
|
+
"app.py:handler")
|
|
302
329
|
requirements: Python requirements
|
|
303
330
|
extra_packages: Additional files to include
|
|
304
331
|
base_image: Docker base image
|
|
@@ -311,6 +338,7 @@ class ImageFactory:
|
|
|
311
338
|
host: Host to bind to (default: 0.0.0.0 for containers)
|
|
312
339
|
embed_task_processor: Whether to embed task processor
|
|
313
340
|
extra_startup_args: Additional startup arguments
|
|
341
|
+
use_cache: Enable build cache (default: True)
|
|
314
342
|
**kwargs: Additional configuration options
|
|
315
343
|
|
|
316
344
|
Returns:
|
|
@@ -348,7 +376,7 @@ class ImageFactory:
|
|
|
348
376
|
**kwargs,
|
|
349
377
|
)
|
|
350
378
|
|
|
351
|
-
return self._build_image(app, runner, config)
|
|
379
|
+
return self._build_image(app, runner, config, entrypoint, use_cache)
|
|
352
380
|
|
|
353
381
|
def cleanup(self):
|
|
354
382
|
"""Clean up all temporary resources"""
|