agentscope-runtime 0.2.0b2__py3-none-any.whl → 1.0.0b1__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/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +258 -0
- agentscope_runtime/adapters/agentscope/memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +152 -0
- agentscope_runtime/adapters/agentscope/message.py +535 -0
- agentscope_runtime/adapters/agentscope/stream.py +474 -0
- agentscope_runtime/adapters/agentscope/tool/__init__.py +9 -0
- agentscope_runtime/adapters/agentscope/tool/sandbox_tool.py +69 -0
- agentscope_runtime/adapters/agentscope/tool/tool.py +233 -0
- agentscope_runtime/adapters/autogen/__init__.py +0 -0
- agentscope_runtime/adapters/autogen/tool/__init__.py +7 -0
- agentscope_runtime/adapters/autogen/tool/tool.py +211 -0
- agentscope_runtime/adapters/text/__init__.py +0 -0
- agentscope_runtime/adapters/text/stream.py +29 -0
- agentscope_runtime/common/collections/redis_mapping.py +4 -1
- agentscope_runtime/common/container_clients/fc_client.py +855 -0
- agentscope_runtime/common/utils/__init__.py +0 -0
- agentscope_runtime/common/utils/lazy_loader.py +57 -0
- agentscope_runtime/engine/__init__.py +25 -18
- agentscope_runtime/engine/app/agent_app.py +161 -91
- agentscope_runtime/engine/app/base_app.py +4 -118
- agentscope_runtime/engine/constant.py +8 -0
- agentscope_runtime/engine/deployers/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
- agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
- agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
- agentscope_runtime/engine/deployers/local_deployer.py +47 -74
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
- agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
- agentscope_runtime/engine/deployers/utils/package.py +693 -0
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +256 -282
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
- agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
- agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
- agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
- agentscope_runtime/engine/helpers/runner.py +40 -0
- agentscope_runtime/engine/runner.py +170 -130
- agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
- agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
- agentscope_runtime/engine/schemas/oai_llm.py +23 -23
- agentscope_runtime/engine/schemas/response_api.py +65 -0
- agentscope_runtime/engine/schemas/session.py +24 -0
- agentscope_runtime/engine/services/__init__.py +0 -9
- agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
- agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
- agentscope_runtime/engine/services/memory/__init__.py +24 -0
- agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
- agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
- agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
- agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
- agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
- agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +12 -18
- agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
- agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
- agentscope_runtime/engine/services/session_history/__init__.py +23 -0
- agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
- agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
- agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
- agentscope_runtime/engine/tracing/base.py +10 -9
- agentscope_runtime/engine/tracing/message_util.py +1 -1
- agentscope_runtime/engine/tracing/tracing_util.py +7 -2
- agentscope_runtime/sandbox/__init__.py +10 -2
- agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
- agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
- agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
- agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
- agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
- agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +2 -2
- agentscope_runtime/sandbox/client/http_client.py +1 -0
- agentscope_runtime/sandbox/enums.py +2 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +18 -2
- agentscope_runtime/sandbox/manager/server/app.py +12 -0
- agentscope_runtime/sandbox/manager/server/config.py +19 -0
- agentscope_runtime/sandbox/model/manager_config.py +79 -2
- agentscope_runtime/sandbox/utils.py +0 -18
- agentscope_runtime/tools/RAGs/__init__.py +0 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
- agentscope_runtime/tools/__init__.py +119 -0
- agentscope_runtime/tools/_constants.py +18 -0
- agentscope_runtime/tools/alipay/__init__.py +4 -0
- agentscope_runtime/tools/alipay/base.py +334 -0
- agentscope_runtime/tools/alipay/payment.py +835 -0
- agentscope_runtime/tools/alipay/subscribe.py +551 -0
- agentscope_runtime/tools/base.py +264 -0
- agentscope_runtime/tools/cli/__init__.py +0 -0
- agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
- agentscope_runtime/tools/generations/__init__.py +75 -0
- agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
- agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
- agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
- agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
- agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
- agentscope_runtime/tools/generations/image_edit.py +208 -0
- agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
- agentscope_runtime/tools/generations/image_generation.py +202 -0
- agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
- agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
- agentscope_runtime/tools/generations/image_to_video.py +233 -0
- agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
- agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
- agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
- agentscope_runtime/tools/generations/speech_to_text.py +260 -0
- agentscope_runtime/tools/generations/speech_to_video.py +314 -0
- agentscope_runtime/tools/generations/text_to_video.py +221 -0
- agentscope_runtime/tools/mcp_wrapper.py +215 -0
- agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
- agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
- agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
- agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
- agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
- agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
- agentscope_runtime/tools/searches/__init__.py +3 -0
- agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
- agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
- agentscope_runtime/tools/utils/__init__.py +0 -0
- agentscope_runtime/tools/utils/api_key_util.py +45 -0
- agentscope_runtime/tools/utils/crypto_utils.py +99 -0
- agentscope_runtime/tools/utils/mcp_util.py +35 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/METADATA +234 -165
- agentscope_runtime-1.0.0b1.dist-info/RECORD +240 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/entry_points.txt +1 -0
- agentscope_runtime/engine/agents/__init__.py +0 -2
- agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
- agentscope_runtime/engine/agents/agno_agent.py +0 -220
- agentscope_runtime/engine/agents/autogen_agent.py +0 -250
- agentscope_runtime/engine/agents/base_agent.py +0 -29
- agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
- agentscope_runtime/engine/agents/utils.py +0 -53
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
- agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
- agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
- agentscope_runtime/engine/helpers/helper.py +0 -179
- agentscope_runtime/engine/schemas/context.py +0 -54
- agentscope_runtime/engine/services/context_manager.py +0 -164
- agentscope_runtime/engine/services/environment_manager.py +0 -50
- agentscope_runtime/engine/services/manager.py +0 -174
- agentscope_runtime/engine/services/rag_service.py +0 -195
- agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
- agentscope_runtime/sandbox/tools/__init__.py +0 -12
- agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
- agentscope_runtime/sandbox/tools/base/tool.py +0 -52
- agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
- agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
- agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
- agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
- agentscope_runtime/sandbox/tools/function_tool.py +0 -321
- agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
- agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
- agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
- agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
- agentscope_runtime/sandbox/tools/tool.py +0 -238
- agentscope_runtime/sandbox/tools/utils.py +0 -68
- agentscope_runtime-0.2.0b2.dist-info/RECORD +0 -183
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
from typing import Optional, List, Union
|
|
6
|
+
|
|
7
|
+
from agentscope_runtime.sandbox.box.sandbox import Sandbox
|
|
8
|
+
|
|
9
|
+
from ...utils import build_image_uri
|
|
10
|
+
from ...registry import SandboxRegistry
|
|
11
|
+
from ...enums import SandboxType
|
|
12
|
+
from ...constant import TIMEOUT
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HostPrerequisiteError(Exception):
|
|
18
|
+
"""Custom exception raised when host prerequisites
|
|
19
|
+
for MobileSandbox are not met."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@SandboxRegistry.register(
|
|
23
|
+
build_image_uri("runtime-sandbox-mobile"),
|
|
24
|
+
sandbox_type=SandboxType.MOBILE,
|
|
25
|
+
security_level="high",
|
|
26
|
+
timeout=TIMEOUT,
|
|
27
|
+
description="Mobile Sandbox",
|
|
28
|
+
runtime_config={"privileged": True},
|
|
29
|
+
)
|
|
30
|
+
class MobileSandbox(Sandbox):
|
|
31
|
+
_host_check_done = False
|
|
32
|
+
|
|
33
|
+
def __init__( # pylint: disable=useless-parent-delegation
|
|
34
|
+
self,
|
|
35
|
+
sandbox_id: Optional[str] = None,
|
|
36
|
+
timeout: int = 3000,
|
|
37
|
+
base_url: Optional[str] = None,
|
|
38
|
+
bearer_token: Optional[str] = None,
|
|
39
|
+
sandbox_type: SandboxType = SandboxType.MOBILE,
|
|
40
|
+
):
|
|
41
|
+
if not self.__class__._host_check_done:
|
|
42
|
+
self._check_host_readiness()
|
|
43
|
+
self.__class__._host_check_done = True
|
|
44
|
+
|
|
45
|
+
super().__init__(
|
|
46
|
+
sandbox_id,
|
|
47
|
+
timeout,
|
|
48
|
+
base_url,
|
|
49
|
+
bearer_token,
|
|
50
|
+
sandbox_type,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def _check_host_readiness(self) -> None:
|
|
54
|
+
logger.info(
|
|
55
|
+
"Performing one-time host environment check for MobileSandbox...",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
architecture = platform.machine().lower()
|
|
59
|
+
if architecture in ("aarch64", "arm64"):
|
|
60
|
+
logger.warning(
|
|
61
|
+
"\n======================== WARNING ========================\n"
|
|
62
|
+
"ARM64/aarch64 architecture detected (e.g., Apple M-series).\n"
|
|
63
|
+
"Running this mobile sandbox on a non-x86_64 host may lead \n"
|
|
64
|
+
" to unexpected compatibility or performance issues.\n"
|
|
65
|
+
"=========================================================",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if platform.system() == "Linux":
|
|
69
|
+
required_devices = [
|
|
70
|
+
"/dev/binder",
|
|
71
|
+
"/dev/hwbinder",
|
|
72
|
+
"/dev/vndbinder",
|
|
73
|
+
"/dev/ashmem",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
missing_devices = [
|
|
77
|
+
dev for dev in required_devices if not os.path.exists(dev)
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
if missing_devices:
|
|
81
|
+
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"
|
|
98
|
+
"=================================================="
|
|
99
|
+
)
|
|
100
|
+
raise HostPrerequisiteError(error_message)
|
|
101
|
+
|
|
102
|
+
logger.info("Host environment check passed.")
|
|
103
|
+
|
|
104
|
+
def adb_use(
|
|
105
|
+
self,
|
|
106
|
+
action: str,
|
|
107
|
+
coordinate: Optional[List[int]] = None,
|
|
108
|
+
start: Optional[List[int]] = None,
|
|
109
|
+
end: Optional[List[int]] = None,
|
|
110
|
+
duration: Optional[int] = None,
|
|
111
|
+
code: Optional[Union[int, str]] = None,
|
|
112
|
+
text: Optional[str] = None,
|
|
113
|
+
):
|
|
114
|
+
"""A general-purpose method to execute various ADB actions.
|
|
115
|
+
|
|
116
|
+
This function acts as a low-level dispatcher for
|
|
117
|
+
different ADB commands. Only the parameters relevant
|
|
118
|
+
to the specified `action` should be provided.
|
|
119
|
+
For actions involving coordinates, the values are absolute
|
|
120
|
+
pixels, with the origin (0, 0) at the top-left of the screen.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
action (str): The specific ADB action to perform.
|
|
124
|
+
Examples: 'tap', 'swipe', 'input_text', 'key_event',
|
|
125
|
+
'get_screenshot', 'get_screen_resolution'.
|
|
126
|
+
coordinate (Optional[List[int]]):
|
|
127
|
+
The [x, y] coordinates for a 'tap' action.
|
|
128
|
+
start (Optional[List[int]]):
|
|
129
|
+
The starting [x, y] coordinates for a 'swipe' action.
|
|
130
|
+
end (Optional[List[int]]):
|
|
131
|
+
The ending [x, y] coordinates for a 'swipe' action.
|
|
132
|
+
duration (int, optional):
|
|
133
|
+
The duration of a 'swipe' gesture in milliseconds.
|
|
134
|
+
code (int | str, optional):
|
|
135
|
+
The key event code (e.g., 3) or name
|
|
136
|
+
(e.g., 'HOME') for the 'key_event' action.
|
|
137
|
+
text (Optional[str]):
|
|
138
|
+
The text string to be entered for the 'input_text' action.
|
|
139
|
+
"""
|
|
140
|
+
payload = {"action": action}
|
|
141
|
+
if coordinate is not None:
|
|
142
|
+
payload["coordinate"] = coordinate
|
|
143
|
+
if start is not None:
|
|
144
|
+
payload["start"] = start
|
|
145
|
+
if end is not None:
|
|
146
|
+
payload["end"] = end
|
|
147
|
+
if duration is not None:
|
|
148
|
+
payload["duration"] = duration
|
|
149
|
+
if code is not None:
|
|
150
|
+
payload["code"] = code
|
|
151
|
+
if text is not None:
|
|
152
|
+
payload["text"] = text
|
|
153
|
+
|
|
154
|
+
return self.call_tool("adb", payload)
|
|
155
|
+
|
|
156
|
+
def mobile_get_screen_resolution(self):
|
|
157
|
+
"""Get the screen resolution of the connected mobile device."""
|
|
158
|
+
return self.call_tool("adb", {"action": "get_screen_resolution"})
|
|
159
|
+
|
|
160
|
+
def mobile_tap(self, x: int, y: int):
|
|
161
|
+
"""Tap a specific coordinate on the screen.
|
|
162
|
+
|
|
163
|
+
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.
|
|
166
|
+
"""
|
|
167
|
+
return self.call_tool("adb", {"action": "tap", "coordinate": [x, y]})
|
|
168
|
+
|
|
169
|
+
def mobile_swipe(
|
|
170
|
+
self,
|
|
171
|
+
start: List[int],
|
|
172
|
+
end: List[int],
|
|
173
|
+
duration: Optional[int] = None,
|
|
174
|
+
):
|
|
175
|
+
"""
|
|
176
|
+
Perform a swipe gesture on the screen
|
|
177
|
+
from a start point to an end point.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
start (Optional[List[int]]):
|
|
181
|
+
The starting coordinates [x, y] in pixels.
|
|
182
|
+
end (Optional[List[int]]):
|
|
183
|
+
The ending coordinates [x, y] in pixels.
|
|
184
|
+
duration (int, optional):
|
|
185
|
+
The duration of the swipe in milliseconds.
|
|
186
|
+
"""
|
|
187
|
+
return self.call_tool(
|
|
188
|
+
"adb",
|
|
189
|
+
{
|
|
190
|
+
"action": "swipe",
|
|
191
|
+
"start": start,
|
|
192
|
+
"end": end,
|
|
193
|
+
**({} if duration is None else {"duration": duration}),
|
|
194
|
+
},
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def mobile_input_text(self, text: str):
|
|
198
|
+
"""Input a text string into the currently focused UI element.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
text (str): The string to be inputted.
|
|
202
|
+
"""
|
|
203
|
+
return self.call_tool("adb", {"action": "input_text", "text": text})
|
|
204
|
+
|
|
205
|
+
def mobile_key_event(self, code: Union[int, str]):
|
|
206
|
+
"""Send an Android key event to the device.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
code (int | str): The key event code (e.g., 3 for HOME) or a
|
|
210
|
+
string representation (e.g., 'HOME', 'BACK').
|
|
211
|
+
"""
|
|
212
|
+
return self.call_tool("adb", {"action": "key_event", "code": code})
|
|
213
|
+
|
|
214
|
+
def mobile_get_screenshot(self):
|
|
215
|
+
"""Take a screenshot of the current device screen."""
|
|
216
|
+
return self.call_tool("adb", {"action": "get_screenshot"})
|
|
@@ -206,7 +206,7 @@ class TrainingSandbox(Sandbox):
|
|
|
206
206
|
|
|
207
207
|
|
|
208
208
|
@SandboxRegistry.register(
|
|
209
|
-
build_image_uri("runtime-sandbox-appworld"
|
|
209
|
+
build_image_uri("runtime-sandbox-appworld"),
|
|
210
210
|
sandbox_type=SandboxType.APPWORLD,
|
|
211
211
|
runtime_config={"shm_size": "5.06gb"},
|
|
212
212
|
security_level="medium",
|
|
@@ -251,7 +251,7 @@ DATASET_SUB_TYPE = os.environ.get("DATASET_SUB_TYPE", "multi_turn")
|
|
|
251
251
|
|
|
252
252
|
|
|
253
253
|
@SandboxRegistry.register(
|
|
254
|
-
build_image_uri("runtime-sandbox-bfcl"
|
|
254
|
+
build_image_uri("runtime-sandbox-bfcl"),
|
|
255
255
|
sandbox_type=SandboxType.BFCL,
|
|
256
256
|
runtime_config={"shm_size": "8.06gb"},
|
|
257
257
|
security_level="medium",
|
|
@@ -96,6 +96,7 @@ class SandboxHttpClient:
|
|
|
96
96
|
headers = {
|
|
97
97
|
"Content-Type": "application/json",
|
|
98
98
|
"x-agentrun-session-id": "s" + self.session_id,
|
|
99
|
+
"x-agentscope-runtime-session-id": "s" + self.session_id,
|
|
99
100
|
}
|
|
100
101
|
if self.secret:
|
|
101
102
|
headers["Authorization"] = f"Bearer {self.secret}"
|
|
@@ -188,6 +188,10 @@ class SandboxManager:
|
|
|
188
188
|
)
|
|
189
189
|
|
|
190
190
|
self.client = AgentRunClient(config=self.config)
|
|
191
|
+
elif self.container_deployment == "fc":
|
|
192
|
+
from ...common.container_clients.fc_client import FCClient
|
|
193
|
+
|
|
194
|
+
self.client = FCClient(config=self.config)
|
|
191
195
|
else:
|
|
192
196
|
raise NotImplementedError("Not implemented")
|
|
193
197
|
else:
|
|
@@ -456,6 +460,9 @@ class SandboxManager:
|
|
|
456
460
|
|
|
457
461
|
config = SandboxRegistry.get_config_by_type(target_sandbox_type)
|
|
458
462
|
|
|
463
|
+
print(target_sandbox_type)
|
|
464
|
+
print(config)
|
|
465
|
+
|
|
459
466
|
if not config:
|
|
460
467
|
logger.warning(
|
|
461
468
|
f"Not found sandbox {target_sandbox_type}, " f"using default",
|
|
@@ -486,7 +493,11 @@ class SandboxManager:
|
|
|
486
493
|
mount_dir = os.path.join(self.default_mount_dir, session_id)
|
|
487
494
|
os.makedirs(mount_dir, exist_ok=True)
|
|
488
495
|
|
|
489
|
-
if
|
|
496
|
+
if (
|
|
497
|
+
mount_dir
|
|
498
|
+
and self.container_deployment != "agentrun"
|
|
499
|
+
and self.container_deployment != "fc"
|
|
500
|
+
):
|
|
490
501
|
if not os.path.isabs(mount_dir):
|
|
491
502
|
mount_dir = os.path.abspath(mount_dir)
|
|
492
503
|
|
|
@@ -501,6 +512,7 @@ class SandboxManager:
|
|
|
501
512
|
mount_dir
|
|
502
513
|
and storage_path
|
|
503
514
|
and self.container_deployment != "agentrun"
|
|
515
|
+
and self.container_deployment != "fc"
|
|
504
516
|
):
|
|
505
517
|
self.storage.download_folder(storage_path, mount_dir)
|
|
506
518
|
|
|
@@ -516,7 +528,11 @@ class SandboxManager:
|
|
|
516
528
|
runtime_token = secrets.token_hex(16)
|
|
517
529
|
|
|
518
530
|
# Prepare volume bindings if a mount directory is provided
|
|
519
|
-
if
|
|
531
|
+
if (
|
|
532
|
+
mount_dir
|
|
533
|
+
and self.container_deployment != "agentrun"
|
|
534
|
+
and self.container_deployment != "fc"
|
|
535
|
+
):
|
|
520
536
|
volume_bindings = {
|
|
521
537
|
mount_dir: {
|
|
522
538
|
"bind": self.workdir,
|
|
@@ -93,6 +93,18 @@ def get_config() -> SandboxManagerEnvConfig:
|
|
|
93
93
|
agent_run_prefix=settings.AGENT_RUN_PREFIX,
|
|
94
94
|
agentrun_log_project=settings.AGENT_RUN_LOG_PROJECT,
|
|
95
95
|
agentrun_log_store=settings.AGENT_RUN_LOG_STORE,
|
|
96
|
+
fc_access_key_id=settings.FC_ACCESS_KEY_ID,
|
|
97
|
+
fc_access_key_secret=settings.FC_ACCESS_KEY_SECRET,
|
|
98
|
+
fc_account_id=settings.FC_ACCOUNT_ID,
|
|
99
|
+
fc_region_id=settings.FC_REGION_ID,
|
|
100
|
+
fc_cpu=settings.FC_CPU,
|
|
101
|
+
fc_memory=settings.FC_MEMORY,
|
|
102
|
+
fc_vpc_id=settings.FC_VPC_ID,
|
|
103
|
+
fc_vswitch_ids=settings.FC_VSWITCH_IDS,
|
|
104
|
+
fc_security_group_id=settings.FC_SECURITY_GROUP_ID,
|
|
105
|
+
fc_prefix=settings.FC_PREFIX,
|
|
106
|
+
fc_log_project=settings.FC_LOG_PROJECT,
|
|
107
|
+
fc_log_store=settings.FC_LOG_STORE,
|
|
96
108
|
)
|
|
97
109
|
return _config
|
|
98
110
|
|
|
@@ -28,6 +28,7 @@ class Settings(BaseSettings):
|
|
|
28
28
|
"cloud",
|
|
29
29
|
"k8s",
|
|
30
30
|
"agentrun",
|
|
31
|
+
"fc",
|
|
31
32
|
] = "docker"
|
|
32
33
|
DEFAULT_MOUNT_DIR: str = "sessions_mount_dir"
|
|
33
34
|
# Read-only mounts (host_path -> container_path)
|
|
@@ -77,6 +78,24 @@ class Settings(BaseSettings):
|
|
|
77
78
|
AGENT_RUN_LOG_PROJECT: Optional[str] = None
|
|
78
79
|
AGENT_RUN_LOG_STORE: Optional[str] = None
|
|
79
80
|
|
|
81
|
+
# FC settings
|
|
82
|
+
FC_ACCOUNT_ID: Optional[str] = None
|
|
83
|
+
FC_ACCESS_KEY_ID: Optional[str] = None
|
|
84
|
+
FC_ACCESS_KEY_SECRET: Optional[str] = None
|
|
85
|
+
FC_REGION_ID: str = "cn-hangzhou"
|
|
86
|
+
|
|
87
|
+
FC_CPU: float = 2.0
|
|
88
|
+
FC_MEMORY: int = 2048
|
|
89
|
+
|
|
90
|
+
FC_VPC_ID: Optional[str] = None
|
|
91
|
+
FC_VSWITCH_IDS: Optional[list[str]] = None
|
|
92
|
+
FC_SECURITY_GROUP_ID: Optional[str] = None
|
|
93
|
+
|
|
94
|
+
FC_PREFIX: str = "agentscope-sandbox"
|
|
95
|
+
|
|
96
|
+
FC_LOG_PROJECT: Optional[str] = None
|
|
97
|
+
FC_LOG_STORE: Optional[str] = None
|
|
98
|
+
|
|
80
99
|
model_config = ConfigDict(
|
|
81
100
|
case_sensitive=True,
|
|
82
101
|
extra="allow",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
# pylint: disable=no-self-argument
|
|
2
|
+
# pylint: disable=no-self-argument, too-many-branches
|
|
3
3
|
import os
|
|
4
4
|
from typing import Optional, Literal, Tuple, Dict
|
|
5
5
|
from pydantic import BaseModel, Field, model_validator
|
|
@@ -32,10 +32,11 @@ class SandboxManagerEnvConfig(BaseModel):
|
|
|
32
32
|
"cloud",
|
|
33
33
|
"k8s",
|
|
34
34
|
"agentrun",
|
|
35
|
+
"fc",
|
|
35
36
|
] = Field(
|
|
36
37
|
...,
|
|
37
38
|
description="Container deployment backend: 'docker', 'cloud', 'k8s'"
|
|
38
|
-
"
|
|
39
|
+
" 'agentrun' or 'fc'.",
|
|
39
40
|
)
|
|
40
41
|
|
|
41
42
|
default_mount_dir: Optional[str] = Field(
|
|
@@ -180,6 +181,62 @@ class SandboxManagerEnvConfig(BaseModel):
|
|
|
180
181
|
description="Log store for AgentRun.",
|
|
181
182
|
)
|
|
182
183
|
|
|
184
|
+
# FC settings
|
|
185
|
+
fc_access_key_id: Optional[str] = Field(
|
|
186
|
+
None,
|
|
187
|
+
description="Access key ID for FC. Required if "
|
|
188
|
+
"container_deployment is 'fc'.",
|
|
189
|
+
)
|
|
190
|
+
fc_access_key_secret: Optional[str] = Field(
|
|
191
|
+
None,
|
|
192
|
+
description="Access key secret for FC. "
|
|
193
|
+
"Required if container_deployment is 'fc'.",
|
|
194
|
+
)
|
|
195
|
+
fc_account_id: Optional[str] = Field(
|
|
196
|
+
None,
|
|
197
|
+
description="Account ID for FC. Required if "
|
|
198
|
+
"container_deployment is 'fc'.",
|
|
199
|
+
)
|
|
200
|
+
fc_region_id: str = Field(
|
|
201
|
+
"cn-hangzhou",
|
|
202
|
+
description="Region ID for FC.",
|
|
203
|
+
)
|
|
204
|
+
fc_cpu: float = Field(
|
|
205
|
+
2.0,
|
|
206
|
+
description="CPU allocation for FC containers.",
|
|
207
|
+
)
|
|
208
|
+
fc_memory: int = Field(
|
|
209
|
+
2048,
|
|
210
|
+
description="Memory allocation for FC containers in MB.",
|
|
211
|
+
)
|
|
212
|
+
fc_vpc_id: Optional[str] = Field(
|
|
213
|
+
None,
|
|
214
|
+
description="VPC ID for FC. Required if container_deployment "
|
|
215
|
+
"is 'FC'.",
|
|
216
|
+
)
|
|
217
|
+
fc_vswitch_ids: Optional[list[str]] = Field(
|
|
218
|
+
None,
|
|
219
|
+
description="VSwitch IDs for FC. Required if "
|
|
220
|
+
"container_deployment is 'FC'.",
|
|
221
|
+
)
|
|
222
|
+
fc_security_group_id: Optional[str] = Field(
|
|
223
|
+
None,
|
|
224
|
+
description="Security group ID for FC. "
|
|
225
|
+
"Required if container_deployment is 'FC'.",
|
|
226
|
+
)
|
|
227
|
+
fc_prefix: str = Field(
|
|
228
|
+
"agentscope-sandbox_",
|
|
229
|
+
description="Prefix for FC resources.",
|
|
230
|
+
)
|
|
231
|
+
fc_log_project: Optional[str] = Field(
|
|
232
|
+
None,
|
|
233
|
+
description="Log project for FC.",
|
|
234
|
+
)
|
|
235
|
+
fc_log_store: Optional[str] = Field(
|
|
236
|
+
None,
|
|
237
|
+
description="Log store for FC.",
|
|
238
|
+
)
|
|
239
|
+
|
|
183
240
|
@model_validator(mode="after")
|
|
184
241
|
def check_settings(self):
|
|
185
242
|
if self.default_mount_dir:
|
|
@@ -249,4 +306,24 @@ class SandboxManagerEnvConfig(BaseModel):
|
|
|
249
306
|
f"container_deployment is 'agentrun'",
|
|
250
307
|
)
|
|
251
308
|
|
|
309
|
+
if self.container_deployment == "fc":
|
|
310
|
+
required_fc_fields = [
|
|
311
|
+
self.fc_access_key_id,
|
|
312
|
+
self.fc_access_key_secret,
|
|
313
|
+
self.fc_account_id,
|
|
314
|
+
]
|
|
315
|
+
for field_name, field_value in zip(
|
|
316
|
+
[
|
|
317
|
+
"fc_access_key_id",
|
|
318
|
+
"fc_access_key_secret",
|
|
319
|
+
"fc_account_id",
|
|
320
|
+
],
|
|
321
|
+
required_fc_fields,
|
|
322
|
+
):
|
|
323
|
+
if not field_value:
|
|
324
|
+
raise ValueError(
|
|
325
|
+
f"{field_name} must be set when "
|
|
326
|
+
f"container_deployment is 'fc'",
|
|
327
|
+
)
|
|
328
|
+
|
|
252
329
|
return self
|
|
@@ -13,7 +13,6 @@ def build_image_uri(
|
|
|
13
13
|
tag: str = None,
|
|
14
14
|
registry: str = None,
|
|
15
15
|
namespace: str = None,
|
|
16
|
-
arm64_compatible: bool = True,
|
|
17
16
|
) -> str:
|
|
18
17
|
"""
|
|
19
18
|
Build a fully qualified Docker image URI.
|
|
@@ -30,12 +29,6 @@ def build_image_uri(
|
|
|
30
29
|
If empty or whitespace, registry prefix will be omitted.
|
|
31
30
|
namespace : str, optional
|
|
32
31
|
Docker image namespace. Defaults to the global ``IMAGE_NAMESPACE``.
|
|
33
|
-
arm64_compatible : bool, optional
|
|
34
|
-
Whether the image is ARM64-compatible without special tagging.
|
|
35
|
-
If ``True`` (default), the tag is returned unchanged.
|
|
36
|
-
If ``False``, the function will detect the current machine
|
|
37
|
-
architecture and append ``-arm64`` to the tag if running on ARM64 (
|
|
38
|
-
e.g., ``arm64``, ``aarch64``).
|
|
39
32
|
|
|
40
33
|
Returns
|
|
41
34
|
-------
|
|
@@ -55,10 +48,6 @@ def build_image_uri(
|
|
|
55
48
|
>>> build_image_uri("runtime-sandbox-base", registry="")
|
|
56
49
|
'agentscope/runtime-sandbox-base:latest'
|
|
57
50
|
|
|
58
|
-
>>> build_image_uri("runtime-sandbox-base", arm64_compatible=False)
|
|
59
|
-
'agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime
|
|
60
|
-
-sandbox-base:latest-arm64'
|
|
61
|
-
# (Above example assumes running on ARM64 machine)
|
|
62
51
|
"""
|
|
63
52
|
reg = registry if registry is not None else REGISTRY
|
|
64
53
|
reg = "" if reg.strip() == "" else f"{reg.strip()}/"
|
|
@@ -66,13 +55,6 @@ def build_image_uri(
|
|
|
66
55
|
final_namespace = namespace if namespace is not None else IMAGE_NAMESPACE
|
|
67
56
|
final_tag = tag or IMAGE_TAG
|
|
68
57
|
|
|
69
|
-
# TODO: make manifest compatible and remove this
|
|
70
|
-
# Adjust tag based on ARM64 compatibility
|
|
71
|
-
if not arm64_compatible:
|
|
72
|
-
machine = platform.machine().lower()
|
|
73
|
-
if "arm" in machine or "aarch64" in machine:
|
|
74
|
-
final_tag = f"{final_tag}-arm64"
|
|
75
|
-
|
|
76
58
|
return f"{reg}{final_namespace}/{image_name}:{final_tag}"
|
|
77
59
|
|
|
78
60
|
|
|
File without changes
|