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.
- 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 +1074 -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/common/collections/redis_mapping.py +4 -1
- agentscope_runtime/engine/app/agent_app.py +55 -9
- agentscope_runtime/engine/deployers/__init__.py +1 -0
- agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +56 -1
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +449 -41
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +273 -0
- agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +640 -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 +161 -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 +23 -10
- agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +35 -2
- agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
- agentscope_runtime/engine/deployers/utils/net_utils.py +65 -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 +30 -9
- agentscope_runtime/engine/schemas/exception.py +604 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +61 -8
- agentscope_runtime/engine/services/agent_state/state_service_factory.py +2 -5
- agentscope_runtime/engine/services/memory/redis_memory_service.py +129 -25
- agentscope_runtime/engine/services/session_history/redis_session_history_service.py +160 -34
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
- agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
- agentscope_runtime/sandbox/build.py +50 -57
- agentscope_runtime/sandbox/utils.py +2 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/METADATA +31 -8
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/RECORD +69 -36
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/entry_points.txt +1 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/licenses/LICENSE +0 -0
- {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
|
|
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
|
-
"""
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
77
|
-
|
|
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
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"To fix this, please
|
|
88
|
-
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
"2.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
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,
|
|
231
|
+
def mobile_tap(self, coordinate: List[int]):
|
|
161
232
|
"""Tap a specific coordinate on the screen.
|
|
162
233
|
|
|
163
234
|
Args:
|
|
164
|
-
|
|
165
|
-
|
|
235
|
+
coordinate (List[int]):
|
|
236
|
+
The screen coordinates for the tap location.
|
|
166
237
|
"""
|
|
167
|
-
return self.call_tool(
|
|
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 (
|
|
254
|
+
start (List[int]):
|
|
181
255
|
The starting coordinates [x, y] in pixels.
|
|
182
|
-
end (
|
|
256
|
+
end (List[int]):
|
|
183
257
|
The ending coordinates [x, y] in pixels.
|
|
184
|
-
duration (int
|
|
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
|
|
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=
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
agentscope_runtime/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
__version__ = "v1.0.
|
|
2
|
+
__version__ = "v1.0.3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentscope-runtime
|
|
3
|
-
Version: 1.0.
|
|
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
|
|
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
|
[](https://pypi.org/project/agentscope-runtime/)
|
|
72
78
|
[](https://pepy.tech/project/agentscope-runtime)
|
|
73
79
|
[](https://python.org)
|
|
80
|
+
[](https://github.com/agentscope-ai/agentscope-runtime)
|
|
74
81
|
[](LICENSE)
|
|
75
82
|
[](https://github.com/psf/black)
|
|
76
83
|
[](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/
|
|
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(
|
|
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
|
-
[](#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>
|