agentscope-runtime 1.0.1__py3-none-any.whl → 1.0.3__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 (69) hide show
  1. agentscope_runtime/adapters/agentscope/message.py +32 -7
  2. agentscope_runtime/adapters/agentscope/stream.py +121 -91
  3. agentscope_runtime/adapters/agno/__init__.py +0 -0
  4. agentscope_runtime/adapters/agno/message.py +30 -0
  5. agentscope_runtime/adapters/agno/stream.py +122 -0
  6. agentscope_runtime/adapters/langgraph/__init__.py +12 -0
  7. agentscope_runtime/adapters/langgraph/message.py +257 -0
  8. agentscope_runtime/adapters/langgraph/stream.py +205 -0
  9. agentscope_runtime/cli/__init__.py +7 -0
  10. agentscope_runtime/cli/cli.py +63 -0
  11. agentscope_runtime/cli/commands/__init__.py +2 -0
  12. agentscope_runtime/cli/commands/chat.py +815 -0
  13. agentscope_runtime/cli/commands/deploy.py +1074 -0
  14. agentscope_runtime/cli/commands/invoke.py +58 -0
  15. agentscope_runtime/cli/commands/list_cmd.py +103 -0
  16. agentscope_runtime/cli/commands/run.py +176 -0
  17. agentscope_runtime/cli/commands/sandbox.py +128 -0
  18. agentscope_runtime/cli/commands/status.py +60 -0
  19. agentscope_runtime/cli/commands/stop.py +185 -0
  20. agentscope_runtime/cli/commands/web.py +166 -0
  21. agentscope_runtime/cli/loaders/__init__.py +6 -0
  22. agentscope_runtime/cli/loaders/agent_loader.py +295 -0
  23. agentscope_runtime/cli/state/__init__.py +10 -0
  24. agentscope_runtime/cli/utils/__init__.py +18 -0
  25. agentscope_runtime/cli/utils/console.py +378 -0
  26. agentscope_runtime/cli/utils/validators.py +118 -0
  27. agentscope_runtime/common/collections/redis_mapping.py +4 -1
  28. agentscope_runtime/engine/app/agent_app.py +55 -9
  29. agentscope_runtime/engine/deployers/__init__.py +1 -0
  30. agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +56 -1
  31. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +449 -41
  32. agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +273 -0
  33. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +640 -0
  34. agentscope_runtime/engine/deployers/agentrun_deployer.py +152 -22
  35. agentscope_runtime/engine/deployers/base.py +27 -2
  36. agentscope_runtime/engine/deployers/kubernetes_deployer.py +161 -31
  37. agentscope_runtime/engine/deployers/local_deployer.py +188 -25
  38. agentscope_runtime/engine/deployers/modelstudio_deployer.py +109 -18
  39. agentscope_runtime/engine/deployers/state/__init__.py +9 -0
  40. agentscope_runtime/engine/deployers/state/manager.py +388 -0
  41. agentscope_runtime/engine/deployers/state/schema.py +96 -0
  42. agentscope_runtime/engine/deployers/utils/build_cache.py +736 -0
  43. agentscope_runtime/engine/deployers/utils/detached_app.py +105 -30
  44. agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +31 -10
  45. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +23 -10
  46. agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +35 -2
  47. agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
  48. agentscope_runtime/engine/deployers/utils/net_utils.py +65 -0
  49. agentscope_runtime/engine/deployers/utils/package.py +56 -6
  50. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +16 -2
  51. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +155 -5
  52. agentscope_runtime/engine/deployers/utils/wheel_packager.py +107 -123
  53. agentscope_runtime/engine/runner.py +30 -9
  54. agentscope_runtime/engine/schemas/exception.py +604 -0
  55. agentscope_runtime/engine/services/agent_state/redis_state_service.py +61 -8
  56. agentscope_runtime/engine/services/agent_state/state_service_factory.py +2 -5
  57. agentscope_runtime/engine/services/memory/redis_memory_service.py +129 -25
  58. agentscope_runtime/engine/services/session_history/redis_session_history_service.py +160 -34
  59. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
  60. agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
  61. agentscope_runtime/sandbox/build.py +50 -57
  62. agentscope_runtime/sandbox/utils.py +2 -0
  63. agentscope_runtime/version.py +1 -1
  64. {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/METADATA +31 -8
  65. {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/RECORD +69 -36
  66. {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/entry_points.txt +1 -0
  67. {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/WHEEL +0 -0
  68. {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/licenses/LICENSE +0 -0
  69. {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,9 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import logging
3
- import os
3
+ import subprocess
4
4
  import platform
5
5
  from typing import Optional, List, Union
6
+ from urllib.parse import urlencode, urljoin
6
7
 
7
8
  from agentscope_runtime.sandbox.box.sandbox import Sandbox
8
9
 
@@ -14,8 +15,34 @@ from ...constant import TIMEOUT
14
15
  logger = logging.getLogger(__name__)
15
16
 
16
17
 
18
+ class MobileMixin:
19
+ @property
20
+ def mobile_url(self):
21
+ if not self.manager_api.check_health(identity=self.sandbox_id):
22
+ raise RuntimeError(f"Sandbox {self.sandbox_id} is not healthy")
23
+
24
+ info = self.get_info()
25
+ # 'path' and 'remote_path' are conceptually different:
26
+ # 'path' is used for local URLs,
27
+ # 'remote_path' for remote URLs. In this implementation,
28
+ # both point to "/websockify/".
29
+ # If the endpoints diverge in the future,
30
+ # update these values accordingly.
31
+ path = "/websockify/"
32
+ remote_path = "/websockify/"
33
+ params = {"password": info["runtime_token"]}
34
+
35
+ if self.base_url is None:
36
+ return urljoin(info["url"], path) + "?" + urlencode(params)
37
+
38
+ return (
39
+ f"{self.base_url}/desktop/{self.sandbox_id}{remote_path}"
40
+ f"?{urlencode(params)}"
41
+ )
42
+
43
+
17
44
  class HostPrerequisiteError(Exception):
18
- """Custom exception raised when host prerequisites
45
+ """Exception raised when host prerequisites
19
46
  for MobileSandbox are not met."""
20
47
 
21
48
 
@@ -27,7 +54,7 @@ class HostPrerequisiteError(Exception):
27
54
  description="Mobile Sandbox",
28
55
  runtime_config={"privileged": True},
29
56
  )
30
- class MobileSandbox(Sandbox):
57
+ class MobileSandbox(MobileMixin, Sandbox):
31
58
  _host_check_done = False
32
59
 
33
60
  def __init__( # pylint: disable=useless-parent-delegation
@@ -38,7 +65,7 @@ class MobileSandbox(Sandbox):
38
65
  bearer_token: Optional[str] = None,
39
66
  sandbox_type: SandboxType = SandboxType.MOBILE,
40
67
  ):
41
- if not self.__class__._host_check_done:
68
+ if base_url is None and not self.__class__._host_check_done:
42
69
  self._check_host_readiness()
43
70
  self.__class__._host_check_done = True
44
71
 
@@ -65,36 +92,80 @@ class MobileSandbox(Sandbox):
65
92
  "=========================================================",
66
93
  )
67
94
 
68
- if platform.system() == "Linux":
69
- required_devices = [
70
- "/dev/binder",
71
- "/dev/hwbinder",
72
- "/dev/vndbinder",
73
- "/dev/ashmem",
74
- ]
95
+ os_type = platform.system()
96
+ if os_type == "Linux":
97
+ try:
98
+ result = subprocess.run(
99
+ ["lsmod"],
100
+ capture_output=True,
101
+ text=True,
102
+ check=True,
103
+ )
104
+ loaded_modules = result.stdout
105
+ except (FileNotFoundError, subprocess.CalledProcessError):
106
+ loaded_modules = ""
107
+ logger.warning(
108
+ "Could not execute 'lsmod' to verify kernel modules.",
109
+ )
75
110
 
76
- missing_devices = [
77
- dev for dev in required_devices if not os.path.exists(dev)
78
- ]
111
+ if "binder_linux" not in loaded_modules:
112
+ error_message = (
113
+ "\n========== HOST PREREQUISITE FAILED ==========\n"
114
+ "MobileSandbox requires specific kernel modules"
115
+ " that appear to be missing or not loaded.\n\n"
116
+ "To fix this, please run the following commands"
117
+ " on your Linux host:\n\n"
118
+ "## Install required kernel modules\n"
119
+ "sudo apt update"
120
+ " && sudo apt install -y linux-modules-extra-`uname -r`\n"
121
+ "sudo modprobe binder_linux"
122
+ ' devices="binder,hwbinder,vndbinder"\n'
123
+ "## (Optional) Load the ashmem driver for older kernels\n"
124
+ "sudo modprobe ashmem_linux\n"
125
+ "=================================================="
126
+ )
127
+ raise HostPrerequisiteError(error_message)
79
128
 
80
- if missing_devices:
129
+ if os_type == "Windows":
130
+ try:
131
+ result = subprocess.run(
132
+ ["wsl", "lsmod"],
133
+ capture_output=True,
134
+ text=True,
135
+ check=True,
136
+ encoding="utf-8",
137
+ )
138
+ loaded_modules = result.stdout
139
+ except (FileNotFoundError, subprocess.CalledProcessError):
140
+ loaded_modules = ""
141
+ logger.warning(
142
+ "Could not execute 'wsl lsmod' to verify kernel modules.",
143
+ )
144
+
145
+ if "binder_linux" not in loaded_modules:
81
146
  error_message = (
82
- f"\n========== HOST PREREQUISITE FAILED ==========\n"
83
- f"MobileSandbox requires specific kernel \
84
- modules on the host machine.\n"
85
- f"The following required device files are missing:\n"
86
- f" - {', '.join(missing_devices)}\n\n"
87
- "To fix this, please run the following \
88
- commands on your Linux host:\n\n"
89
- "1. Install extra kernel modules:\n"
90
- " sudo apt update && \
91
- sudo apt install -y linux-modules-extra-`uname -r`\n\n"
92
- "2. Load modules and create device nodes:\n"
93
- ' sudo modprobe binder_linux devices=\
94
- "binder,hwbinder,vndbinder"\n'
95
- " sudo modprobe ashmem_linux\n\n"
96
- "After running these commands, verify with:\n"
97
- " ls -l /dev/binder* /dev/ashmem\n"
147
+ "\n========== HOST PREREQUISITE FAILED ==========\n"
148
+ "MobileSandbox on Windows requires Docker Desktop "
149
+ "with the WSL 2 backend.\n"
150
+ "The required kernel modules seem to be missing "
151
+ "in your WSL 2 environment.\n\n"
152
+ "To fix this, please follow these steps:\n\n"
153
+ "1. **Ensure Docker Desktop is using WSL 2**:\n"
154
+ " - Open Docker Desktop -> Settings -> General.\n"
155
+ " - Make sure 'Use the WSL 2 based engine' "
156
+ "is checked.\n\n"
157
+ "2. **Ensure WSL is installed and updated**:\n"
158
+ " - Open PowerShell or Command Prompt "
159
+ "as Administrator.\n"
160
+ " - Run: wsl --install\n"
161
+ " - Run: wsl --update\n"
162
+ " (An update usually installs a recent Linux kernel "
163
+ "with the required modules.)\n\n"
164
+ "3. **Verify manually (Optional)**:\n"
165
+ " - After updating, run 'wsl lsmod | findstr binder' "
166
+ "in your terminal.\n"
167
+ " - If it shows 'binder_linux', "
168
+ "the issue should be resolved.\n"
98
169
  "=================================================="
99
170
  )
100
171
  raise HostPrerequisiteError(error_message)
@@ -157,14 +228,17 @@ class MobileSandbox(Sandbox):
157
228
  """Get the screen resolution of the connected mobile device."""
158
229
  return self.call_tool("adb", {"action": "get_screen_resolution"})
159
230
 
160
- def mobile_tap(self, x: int, y: int):
231
+ def mobile_tap(self, coordinate: List[int]):
161
232
  """Tap a specific coordinate on the screen.
162
233
 
163
234
  Args:
164
- x (int): The x-coordinate in pixels from the left edge.
165
- y (int): The y-coordinate in pixels from the top edge.
235
+ coordinate (List[int]):
236
+ The screen coordinates for the tap location.
166
237
  """
167
- return self.call_tool("adb", {"action": "tap", "coordinate": [x, y]})
238
+ return self.call_tool(
239
+ "adb",
240
+ {"action": "tap", "coordinate": coordinate},
241
+ )
168
242
 
169
243
  def mobile_swipe(
170
244
  self,
@@ -177,11 +251,11 @@ class MobileSandbox(Sandbox):
177
251
  from a start point to an end point.
178
252
 
179
253
  Args:
180
- start (Optional[List[int]]):
254
+ start (List[int]):
181
255
  The starting coordinates [x, y] in pixels.
182
- end (Optional[List[int]]):
256
+ end (List[int]):
183
257
  The ending coordinates [x, y] in pixels.
184
- duration (int, optional):
258
+ duration (Optional[int]):
185
259
  The duration of the swipe in milliseconds.
186
260
  """
187
261
  return self.call_tool(
@@ -206,7 +280,7 @@ class MobileSandbox(Sandbox):
206
280
  """Send an Android key event to the device.
207
281
 
208
282
  Args:
209
- code (int | str): The key event code (e.g., 3 for HOME) or a
283
+ code (Union[int, str]): The key event code (e.g., 3 for HOME) or a
210
284
  string representation (e.g., 'HOME', 'BACK').
211
285
  """
212
286
  return self.call_tool("adb", {"action": "key_event", "code": code})
@@ -5,6 +5,7 @@ import os
5
5
  import shutil
6
6
  import traceback
7
7
  from contextlib import AsyncExitStack
8
+ from datetime import timedelta
8
9
  from typing import Any
9
10
 
10
11
  from mcp import ClientSession, StdioServerParameters
@@ -16,6 +17,18 @@ logging.basicConfig(level=logging.INFO)
16
17
  logger = logging.getLogger(__name__)
17
18
 
18
19
 
20
+ def _coerce_timedelta(value: Any, default: timedelta) -> timedelta:
21
+ """Normalize timeout values to timedelta for MCP client compatibility."""
22
+ if value is None:
23
+ return default
24
+ if isinstance(value, timedelta):
25
+ return value
26
+ try:
27
+ return timedelta(seconds=float(value))
28
+ except (TypeError, ValueError):
29
+ return default
30
+
31
+
19
32
  class MCPSessionHandler:
20
33
  """Manages MCP server connections and tool execution."""
21
34
 
@@ -57,10 +70,13 @@ class MCPSessionHandler:
57
70
  streamablehttp_client(
58
71
  url=self.config["url"],
59
72
  headers=self.config.get("headers"),
60
- timeout=self.config.get("timeout", 30),
61
- sse_read_timeout=self.config.get(
62
- "sse_read_timeout",
63
- 60 * 5,
73
+ timeout=_coerce_timedelta(
74
+ self.config.get("timeout"),
75
+ default=timedelta(seconds=30),
76
+ ),
77
+ sse_read_timeout=_coerce_timedelta(
78
+ self.config.get("sse_read_timeout"),
79
+ default=timedelta(seconds=60 * 5),
64
80
  ),
65
81
  ),
66
82
  )
@@ -70,9 +70,7 @@ def build_image(
70
70
  f" {DOCKER_PLATFORMS}"
71
71
  )
72
72
 
73
- platform_tag = ""
74
- if platform_choice == "linux/arm64":
75
- platform_tag = "-arm64"
73
+ auto_build = os.getenv("AUTO_BUILD", "false").lower() == "true"
76
74
 
77
75
  buildx_enable = platform_choice != get_platform()
78
76
 
@@ -93,7 +91,7 @@ def build_image(
93
91
  secret_token = "secret_token123"
94
92
 
95
93
  # Add platform tag
96
- image_name = SandboxRegistry.get_image_by_type(build_type) + platform_tag
94
+ image_name = SandboxRegistry.get_image_by_type(build_type)
97
95
 
98
96
  logger.info(f"Building Docker image {image_name}...")
99
97
 
@@ -108,10 +106,13 @@ def build_image(
108
106
 
109
107
  # Check if the image already exists
110
108
  if image_name in images or f"{image_name}dev" in images:
111
- choice = input(
112
- f"Image {image_name}dev|{image_name} already exists. Do "
113
- f"you want to overwrite it? (y/N): ",
114
- )
109
+ if auto_build:
110
+ choice = "y"
111
+ else:
112
+ choice = input(
113
+ f"Image {image_name}dev|{image_name} already exists. Do "
114
+ f"you want to overwrite it? (y/N): ",
115
+ )
115
116
  if choice.lower() != "y":
116
117
  logger.info("Exiting without overwriting the existing image.")
117
118
  return
@@ -156,34 +157,25 @@ def build_image(
156
157
 
157
158
  logger.info(f"Docker image {image_name}dev built successfully.")
158
159
 
159
- logger.info(f"Start to build image {image_name}.")
160
-
161
- # Run the container with port mapping and environment variable
162
- free_port = find_free_port(8080, 8090)
163
-
164
- if not buildx_enable:
165
- result = subprocess.run(
166
- [
167
- "docker",
168
- "run",
169
- "-d",
170
- "-p",
171
- f"{free_port}:80",
172
- "-e",
173
- f"SECRET_TOKEN={secret_token}",
174
- f"{image_name}dev",
175
- ],
176
- capture_output=True,
177
- text=True,
178
- check=False,
160
+ if buildx_enable:
161
+ logger.warning(
162
+ "Cross-platform build detected; "
163
+ "skipping health checks and tagging the final image directly.",
179
164
  )
165
+ subprocess.run(
166
+ ["docker", "tag", f"{image_name}dev", image_name],
167
+ check=True,
168
+ )
169
+ logger.info(f"Docker image {image_name} tagged successfully.")
180
170
  else:
171
+ logger.info(f"Start to build image {image_name}.")
172
+
173
+ # Run the container with port mapping and environment variable
174
+ free_port = find_free_port(8080, 8090)
181
175
  result = subprocess.run(
182
176
  [
183
177
  "docker",
184
178
  "run",
185
- "--platform",
186
- platform_choice,
187
179
  "-d",
188
180
  "-p",
189
181
  f"{free_port}:80",
@@ -195,34 +187,35 @@ def build_image(
195
187
  text=True,
196
188
  check=False,
197
189
  )
198
-
199
- container_id = result.stdout.strip()
200
- logger.info(f"Running container {container_id} on port {free_port}")
201
-
202
- # Check health endpoints
203
- fastapi_health_url = f"http://localhost:{free_port}/fastapi/healthz"
204
-
205
- # Check health for FASTAPI
206
- fastapi_healthy = check_health(fastapi_health_url, secret_token)
207
-
208
- if fastapi_healthy:
209
- logger.info("Health checks passed.")
210
- subprocess.run(
211
- ["docker", "commit", container_id, f"{image_name}"],
212
- check=True,
213
- )
214
- logger.info(
215
- f"Docker image {image_name} committed successfully.",
216
- )
217
- subprocess.run(["docker", "stop", container_id], check=True)
218
- subprocess.run(["docker", "rm", container_id], check=True)
190
+ container_id = result.stdout.strip()
191
+ logger.info(f"Running container {container_id} on port {free_port}")
192
+
193
+ # Check health endpoints
194
+ fastapi_health_url = f"http://localhost:{free_port}/fastapi/healthz"
195
+ fastapi_healthy = check_health(fastapi_health_url, secret_token)
196
+
197
+ if fastapi_healthy:
198
+ logger.info("Health checks passed.")
199
+ subprocess.run(
200
+ ["docker", "commit", container_id, f"{image_name}"],
201
+ check=True,
202
+ )
203
+ logger.info(
204
+ f"Docker image {image_name} committed successfully.",
205
+ )
206
+ subprocess.run(["docker", "stop", container_id], check=True)
207
+ subprocess.run(["docker", "rm", container_id], check=True)
208
+ else:
209
+ logger.error("Health checks failed.")
210
+ subprocess.run(["docker", "stop", container_id], check=True)
211
+
212
+ if auto_build:
213
+ choice = "y"
219
214
  else:
220
- logger.error("Health checks failed.")
221
- subprocess.run(["docker", "stop", container_id], check=True)
222
-
223
- choice = input(
224
- f"Do you want to delete the dev image {image_name}dev? (" f"y/N): ",
225
- )
215
+ choice = input(
216
+ f"Do you want to delete the dev image {image_name}dev? ("
217
+ f"y/N): ",
218
+ )
226
219
  if choice.lower() == "y":
227
220
  subprocess.run(
228
221
  ["docker", "rmi", "-f", f"{image_name}dev"],
@@ -75,6 +75,8 @@ def dynamic_import(ext: str):
75
75
  if os.path.isfile(ext):
76
76
  module_name = os.path.splitext(os.path.basename(ext))[0]
77
77
  spec = importlib.util.spec_from_file_location(module_name, ext)
78
+ if spec is None or spec.loader is None:
79
+ raise ImportError(f"Failed to import module from file: {ext}")
78
80
  module = importlib.util.module_from_spec(spec)
79
81
  spec.loader.exec_module(module)
80
82
  return module
@@ -1,2 +1,2 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "v1.0.1"
2
+ __version__ = "v1.0.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentscope-runtime
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: A production-ready runtime framework for agent applications, providing secure sandboxed execution environments and scalable deployment solutions with multi-framework support.
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -26,6 +26,8 @@ Requires-Dist: psutil
26
26
  Requires-Dist: dashscope>=1.25.0
27
27
  Requires-Dist: jsonref
28
28
  Requires-Dist: asgiref
29
+ Requires-Dist: click>=8.0.0
30
+ Requires-Dist: rich>=13.0.0
29
31
  Provides-Extra: dev
30
32
  Requires-Dist: pytest>=8.3.5; extra == "dev"
31
33
  Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
@@ -37,9 +39,11 @@ Requires-Dist: fakeredis>=2.31.0; extra == "dev"
37
39
  Requires-Dist: sphinx-autoapi>=3.6.0; extra == "dev"
38
40
  Requires-Dist: pytest-mock>=3.15.1; extra == "dev"
39
41
  Requires-Dist: sphinxcontrib-mermaid>=1.2.3; extra == "dev"
40
- Requires-Dist: langgraph>=0.4.0; extra == "dev"
41
- Requires-Dist: autogen-agentchat>=0.7.0; extra == "dev"
42
42
  Provides-Extra: ext
43
+ Requires-Dist: langchain>=1.1.3; extra == "ext"
44
+ Requires-Dist: langchain_openai>=1.0.1; extra == "ext"
45
+ Requires-Dist: langgraph>=1.0.4; extra == "ext"
46
+ Requires-Dist: autogen-agentchat>=0.7.0; extra == "ext"
43
47
  Requires-Dist: reme-ai>=0.2.0.2; extra == "ext"
44
48
  Requires-Dist: mem0ai>=0.1.117; extra == "ext"
45
49
  Requires-Dist: alibabacloud-agentrun20250910>=2.0.1; extra == "ext"
@@ -47,7 +51,7 @@ Requires-Dist: alibabacloud_tea_openapi>=0.4.0; extra == "ext"
47
51
  Requires-Dist: alibabacloud-fc20230330>=4.4.0; extra == "ext"
48
52
  Requires-Dist: tablestore-for-agent-memory>=1.1.0; extra == "ext"
49
53
  Requires-Dist: langchain-community>=0.3.27; extra == "ext"
50
- Requires-Dist: wuying-agentbay-sdk>=0.5.0; extra == "ext"
54
+ Requires-Dist: wuying-agentbay-sdk<0.13.0,>=0.5.0; extra == "ext"
51
55
  Requires-Dist: alipay-sdk-python; extra == "ext"
52
56
  Requires-Dist: cryptography; extra == "ext"
53
57
  Requires-Dist: gunicorn>=20.0.0; extra == "ext"
@@ -61,6 +65,8 @@ Requires-Dist: setuptools>=40.8.0; extra == "ext"
61
65
  Requires-Dist: wheel; extra == "ext"
62
66
  Requires-Dist: alibabacloud-credentials; extra == "ext"
63
67
  Requires-Dist: PyYAML; extra == "ext"
68
+ Requires-Dist: agno>=2.3.8; extra == "ext"
69
+ Requires-Dist: nacos-sdk-python>=3.0.0; extra == "ext"
64
70
  Dynamic: license-file
65
71
 
66
72
  <div align="center">
@@ -71,6 +77,7 @@ Dynamic: license-file
71
77
  [![PyPI](https://img.shields.io/pypi/v/agentscope-runtime?label=PyPI&color=brightgreen&logo=python)](https://pypi.org/project/agentscope-runtime/)
72
78
  [![Downloads](https://static.pepy.tech/badge/agentscope-runtime)](https://pepy.tech/project/agentscope-runtime)
73
79
  [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg?logo=python&label=Python)](https://python.org)
80
+ [![Last Commit](https://img.shields.io/github/last-commit/agentscope-ai/agentscope-runtime)](https://github.com/agentscope-ai/agentscope-runtime)
74
81
  [![License](https://img.shields.io/badge/license-Apache%202.0-red.svg?logo=apache&label=License)](LICENSE)
75
82
  [![Code Style](https://img.shields.io/badge/code%20style-black-black.svg?logo=python&label=CodeStyle)](https://github.com/psf/black)
76
83
  [![GitHub Stars](https://img.shields.io/github/stars/agentscope-ai/agentscope-runtime?style=flat&logo=github&color=yellow&label=Stars)](https://github.com/agentscope-ai/agentscope-runtime/stargazers)
@@ -114,7 +121,15 @@ Dynamic: license-file
114
121
 
115
122
  > [!NOTE]
116
123
  >
117
- > **About Framework-Agnostic**: Currently, AgentScope Runtime supports the **AgentScope** framework. We plan to extend compatibility to more agent development frameworks in the future.
124
+ > **About Framework-Agnostic**: Currently, AgentScope Runtime supports the **AgentScope** framework. We plan to extend compatibility to more agent development frameworks in the future. This table shows the current version’s adapter support for different frameworks. The level of support for each functionality varies across frameworks:
125
+ >
126
+ > | Framework/Feature | Message/Event | Tool | Service |
127
+ > | ------------------------------------------------------------ | ------------- | ---- | ------- |
128
+ > | AgentScope | ✅ | ✅ | ✅ |
129
+ > | [LangGraph](https://runtime.agentscope.io/en/langgraph_guidelines.html) | ✅ | 🚧 | 🚧 |
130
+ > | AutoGen | 🚧 | ✅ | 🚧 |
131
+ > | Microsoft Agent Framework | 🚧 | 🚧 | 🚧 |
132
+ > | [Agno](https://runtime.agentscope.io/en/agno_guidelines.html) | ✅ | ✅ | 🚧 |
118
133
 
119
134
  ---
120
135
 
@@ -124,7 +139,7 @@ Welcome to join our community on
124
139
 
125
140
  | [Discord](https://discord.gg/eYMpfnkG8h) | DingTalk |
126
141
  | ------------------------------------------------------------ | ------------------------------------------------------------ |
127
- | <img src="https://gw.alicdn.com/imgextra/i1/O1CN01hhD1mu1Dd3BWVUvxN_!!6000000000238-2-tps-400-400.png" width="100" height="100"> | <img src="https://img.alicdn.com/imgextra/i1/O1CN01LxzZha1thpIN2cc2E_!!6000000005934-2-tps-497-477.png" width="100" height="100"> |
142
+ | <img src="https://gw.alicdn.com/imgextra/i1/O1CN01hhD1mu1Dd3BWVUvxN_!!6000000000238-2-tps-400-400.png" width="100" height="100"> | <img src="https://img.alicdn.com/imgextra/i4/O1CN014mhqFq1ZlgNuYjxrz_!!6000000003235-2-tps-400-400.png" width="100" height="100"> |
128
143
 
129
144
  ---
130
145
 
@@ -389,6 +404,8 @@ with FilesystemSandbox() as box:
389
404
 
390
405
  Provides a **sandboxed Android emulator environment** that allows executing various mobile operations, such as tapping, swiping, inputting text, and taking screenshots.
391
406
 
407
+ <img src="https://img.alicdn.com/imgextra/i4/O1CN01yPnBC21vOi45fLy7V_!!6000000006163-2-tps-544-865.png" alt="Mobile Sandbox" height="500">
408
+
392
409
  ##### Prerequisites
393
410
 
394
411
  - **Linux Host**:
@@ -410,7 +427,7 @@ with MobileSandbox() as box:
410
427
  # By default, pulls 'agentscope/runtime-sandbox-mobile:latest' from DockerHub
411
428
  print(box.list_tools()) # List all available tools
412
429
  print(box.mobile_get_screen_resolution()) # Get the screen resolution
413
- print(box.mobile_tap(x=500, y=1000)) # Tap at coordinate (500, 1000)
430
+ print(box.mobile_tap([500, 1000])) # Tap at coordinate (500, 1000)
414
431
  print(box.mobile_input_text("Hello from AgentScope!")) # Input text
415
432
  print(box.mobile_key_event(3)) # Sends a HOME key event (KeyCode: 3)
416
433
  screenshot_result = box.mobile_get_screenshot() # Get the current screenshot
@@ -636,7 +653,7 @@ limitations under the License.
636
653
 
637
654
  ## Contributors ✨
638
655
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
639
- [![All Contributors](https://img.shields.io/badge/all_contributors-25-orange.svg?style=flat-square)](#contributors-)
656
+ [![All Contributors](https://img.shields.io/badge/all_contributors-29-orange.svg?style=flat-square)](#contributors-)
640
657
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
641
658
 
642
659
  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/emoji-key/)):
@@ -678,6 +695,12 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/e
678
695
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/XiuShenAl"><img src="https://avatars.githubusercontent.com/u/242360128?v=4?s=100" width="100px;" alt="XiuShenAl"/><br /><sub><b>XiuShenAl</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=XiuShenAl" title="Code">💻</a> <a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=XiuShenAl" title="Documentation">📖</a></td>
679
696
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/k-farruh"><img src="https://avatars.githubusercontent.com/u/33511681?v=4?s=100" width="100px;" alt="Farruh Kushnazarov"/><br /><sub><b>Farruh Kushnazarov</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=k-farruh" title="Documentation">📖</a></td>
680
697
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/fengxsong"><img src="https://avatars.githubusercontent.com/u/7008971?v=4?s=100" width="100px;" alt="fengxsong"/><br /><sub><b>fengxsong</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/issues?q=author%3Afengxsong" title="Bug reports">🐛</a></td>
698
+ <td align="center" valign="top" width="14.28%"><a href="https://m4n5ter.github.io"><img src="https://avatars.githubusercontent.com/u/68144809?v=4?s=100" width="100px;" alt="Wang"/><br /><sub><b>Wang</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=M4n5ter" title="Code">💻</a> <a href="https://github.com/agentscope-ai/agentscope-runtime/issues?q=author%3AM4n5ter" title="Bug reports">🐛</a></td>
699
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/qiacheng7"><img src="https://avatars.githubusercontent.com/u/223075252?v=4?s=100" width="100px;" alt="qiacheng7"/><br /><sub><b>qiacheng7</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=qiacheng7" title="Code">💻</a> <a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=qiacheng7" title="Documentation">📖</a></td>
700
+ <td align="center" valign="top" width="14.28%"><a href="https://xieyxclack.github.io/"><img src="https://avatars.githubusercontent.com/u/31954383?v=4?s=100" width="100px;" alt="Yuexiang XIE"/><br /><sub><b>Yuexiang XIE</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/pulls?q=is%3Apr+reviewed-by%3Axieyxclack" title="Reviewed Pull Requests">👀</a></td>
701
+ </tr>
702
+ <tr>
703
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/RTsama"><img src="https://avatars.githubusercontent.com/u/100779257?v=4?s=100" width="100px;" alt="RTsama"/><br /><sub><b>RTsama</b></sub></a><br /><a href="https://github.com/agentscope-ai/agentscope-runtime/issues?q=author%3ARTsama" title="Bug reports">🐛</a> <a href="https://github.com/agentscope-ai/agentscope-runtime/commits?author=RTsama" title="Code">💻</a></td>
681
704
  </tr>
682
705
  </tbody>
683
706
  <tfoot>