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.
Files changed (71) hide show
  1. agentscope_runtime/adapters/agentscope/message.py +78 -10
  2. agentscope_runtime/adapters/agentscope/stream.py +155 -101
  3. agentscope_runtime/adapters/agentscope/tool/tool.py +1 -3
  4. agentscope_runtime/adapters/agno/__init__.py +0 -0
  5. agentscope_runtime/adapters/agno/message.py +30 -0
  6. agentscope_runtime/adapters/agno/stream.py +122 -0
  7. agentscope_runtime/adapters/langgraph/__init__.py +12 -0
  8. agentscope_runtime/adapters/langgraph/message.py +257 -0
  9. agentscope_runtime/adapters/langgraph/stream.py +205 -0
  10. agentscope_runtime/cli/__init__.py +7 -0
  11. agentscope_runtime/cli/cli.py +63 -0
  12. agentscope_runtime/cli/commands/__init__.py +2 -0
  13. agentscope_runtime/cli/commands/chat.py +815 -0
  14. agentscope_runtime/cli/commands/deploy.py +1062 -0
  15. agentscope_runtime/cli/commands/invoke.py +58 -0
  16. agentscope_runtime/cli/commands/list_cmd.py +103 -0
  17. agentscope_runtime/cli/commands/run.py +176 -0
  18. agentscope_runtime/cli/commands/sandbox.py +128 -0
  19. agentscope_runtime/cli/commands/status.py +60 -0
  20. agentscope_runtime/cli/commands/stop.py +185 -0
  21. agentscope_runtime/cli/commands/web.py +166 -0
  22. agentscope_runtime/cli/loaders/__init__.py +6 -0
  23. agentscope_runtime/cli/loaders/agent_loader.py +295 -0
  24. agentscope_runtime/cli/state/__init__.py +10 -0
  25. agentscope_runtime/cli/utils/__init__.py +18 -0
  26. agentscope_runtime/cli/utils/console.py +378 -0
  27. agentscope_runtime/cli/utils/validators.py +118 -0
  28. agentscope_runtime/engine/app/agent_app.py +15 -5
  29. agentscope_runtime/engine/deployers/__init__.py +1 -0
  30. agentscope_runtime/engine/deployers/agentrun_deployer.py +154 -24
  31. agentscope_runtime/engine/deployers/base.py +27 -2
  32. agentscope_runtime/engine/deployers/kubernetes_deployer.py +158 -31
  33. agentscope_runtime/engine/deployers/local_deployer.py +188 -25
  34. agentscope_runtime/engine/deployers/modelstudio_deployer.py +109 -18
  35. agentscope_runtime/engine/deployers/state/__init__.py +9 -0
  36. agentscope_runtime/engine/deployers/state/manager.py +388 -0
  37. agentscope_runtime/engine/deployers/state/schema.py +96 -0
  38. agentscope_runtime/engine/deployers/utils/build_cache.py +736 -0
  39. agentscope_runtime/engine/deployers/utils/detached_app.py +105 -30
  40. agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +31 -10
  41. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +15 -8
  42. agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +30 -2
  43. agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
  44. agentscope_runtime/engine/deployers/utils/package.py +56 -6
  45. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +68 -9
  46. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +155 -5
  47. agentscope_runtime/engine/deployers/utils/wheel_packager.py +107 -123
  48. agentscope_runtime/engine/runner.py +32 -12
  49. agentscope_runtime/engine/schemas/agent_schemas.py +21 -7
  50. agentscope_runtime/engine/schemas/exception.py +580 -0
  51. agentscope_runtime/engine/services/agent_state/__init__.py +2 -0
  52. agentscope_runtime/engine/services/agent_state/state_service_factory.py +55 -0
  53. agentscope_runtime/engine/services/memory/__init__.py +2 -0
  54. agentscope_runtime/engine/services/memory/memory_service_factory.py +126 -0
  55. agentscope_runtime/engine/services/sandbox/__init__.py +2 -0
  56. agentscope_runtime/engine/services/sandbox/sandbox_service_factory.py +49 -0
  57. agentscope_runtime/engine/services/service_factory.py +119 -0
  58. agentscope_runtime/engine/services/session_history/__init__.py +2 -0
  59. agentscope_runtime/engine/services/session_history/session_history_service_factory.py +73 -0
  60. agentscope_runtime/engine/services/utils/tablestore_service_utils.py +35 -10
  61. agentscope_runtime/engine/tracing/wrapper.py +49 -31
  62. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
  63. agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
  64. agentscope_runtime/sandbox/utils.py +2 -0
  65. agentscope_runtime/version.py +1 -1
  66. {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/METADATA +82 -11
  67. {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/RECORD +71 -36
  68. {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/entry_points.txt +1 -0
  69. {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/WHEEL +0 -0
  70. {agentscope_runtime-1.0.0b2.dist-info → agentscope_runtime-1.0.2.dist-info}/licenses/LICENSE +0 -0
  71. {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 package, ProjectInfo, DEFAULT_ENTRYPOINT_FILE
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
- build_root = Path(
79
- tempfile.mkdtemp(
80
- prefix="agentscope_runtime_detached_",
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
- # Auto-detect if not specified
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 _append_additional_requirements(
156
+ def append_project_requirements(
150
157
  extraction_dir: Path,
151
- additional_requirements: List[str],
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 should_use_local:
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 push_image(
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
- Push image to registry.
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
- str: Full image name that was pushed
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 = "/tmp/k8s_build"
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"""