agentscope-runtime 1.0.3__py3-none-any.whl → 1.0.4__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/stream.py +2 -9
- agentscope_runtime/adapters/ms_agent_framework/__init__.py +0 -0
- agentscope_runtime/adapters/ms_agent_framework/message.py +205 -0
- agentscope_runtime/adapters/ms_agent_framework/stream.py +418 -0
- agentscope_runtime/adapters/utils.py +6 -0
- agentscope_runtime/cli/commands/deploy.py +371 -0
- agentscope_runtime/common/container_clients/knative_client.py +466 -0
- agentscope_runtime/engine/__init__.py +4 -0
- agentscope_runtime/engine/constant.py +1 -0
- agentscope_runtime/engine/deployers/__init__.py +12 -0
- agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +26 -51
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +19 -10
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +4 -201
- agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +134 -25
- agentscope_runtime/engine/deployers/agentrun_deployer.py +2 -2
- agentscope_runtime/engine/deployers/fc_deployer.py +1506 -0
- agentscope_runtime/engine/deployers/knative_deployer.py +290 -0
- agentscope_runtime/engine/runner.py +12 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +2 -2
- agentscope_runtime/engine/services/memory/redis_memory_service.py +2 -2
- agentscope_runtime/engine/services/session_history/redis_session_history_service.py +2 -2
- agentscope_runtime/engine/tracing/wrapper.py +18 -4
- agentscope_runtime/sandbox/__init__.py +14 -6
- agentscope_runtime/sandbox/box/base/__init__.py +2 -2
- agentscope_runtime/sandbox/box/base/base_sandbox.py +51 -1
- agentscope_runtime/sandbox/box/browser/__init__.py +2 -2
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +198 -2
- agentscope_runtime/sandbox/box/filesystem/__init__.py +2 -2
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +99 -2
- agentscope_runtime/sandbox/box/gui/__init__.py +2 -2
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +117 -1
- agentscope_runtime/sandbox/box/mobile/__init__.py +2 -2
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +247 -100
- agentscope_runtime/sandbox/box/sandbox.py +98 -65
- agentscope_runtime/sandbox/box/shared/routers/generic.py +36 -29
- agentscope_runtime/sandbox/client/__init__.py +6 -1
- agentscope_runtime/sandbox/client/async_http_client.py +339 -0
- agentscope_runtime/sandbox/client/base.py +74 -0
- agentscope_runtime/sandbox/client/http_client.py +108 -329
- agentscope_runtime/sandbox/enums.py +7 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +264 -4
- agentscope_runtime/sandbox/manager/server/app.py +7 -1
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.3.dist-info → agentscope_runtime-1.0.4.dist-info}/METADATA +102 -28
- {agentscope_runtime-1.0.3.dist-info → agentscope_runtime-1.0.4.dist-info}/RECORD +49 -40
- {agentscope_runtime-1.0.3.dist-info → agentscope_runtime-1.0.4.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.3.dist-info → agentscope_runtime-1.0.4.dist-info}/entry_points.txt +0 -0
- {agentscope_runtime-1.0.3.dist-info → agentscope_runtime-1.0.4.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.3.dist-info → agentscope_runtime-1.0.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import Optional, Dict, List, Union, Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
from .utils.docker_image_utils import (
|
|
8
|
+
ImageFactory,
|
|
9
|
+
RegistryConfig,
|
|
10
|
+
)
|
|
11
|
+
from .adapter.protocol_adapter import ProtocolAdapter
|
|
12
|
+
from .base import DeployManager
|
|
13
|
+
from ...common.container_clients.knative_client import (
|
|
14
|
+
KnativeClient,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class K8sConfig(BaseModel):
|
|
21
|
+
# Kubernetes settings
|
|
22
|
+
k8s_namespace: Optional[str] = Field(
|
|
23
|
+
"agentscope-runtime",
|
|
24
|
+
description="Kubernetes namespace to deploy KService. ",
|
|
25
|
+
)
|
|
26
|
+
kubeconfig_path: Optional[str] = Field(
|
|
27
|
+
None,
|
|
28
|
+
description="Path to kubeconfig file. If not set, will try "
|
|
29
|
+
"in-cluster config or default kubeconfig.",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BuildConfig(BaseModel):
|
|
34
|
+
"""Build configuration"""
|
|
35
|
+
|
|
36
|
+
build_context_dir: str = "/tmp/k8s_build"
|
|
37
|
+
dockerfile_template: str = None
|
|
38
|
+
build_timeout: int = 600 # 10 minutes
|
|
39
|
+
push_timeout: int = 300 # 5 minutes
|
|
40
|
+
cleanup_after_build: bool = True
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class KnativeDeployManager(DeployManager):
|
|
44
|
+
"""
|
|
45
|
+
Deploy an AgentScope runner as a Knative Service.
|
|
46
|
+
Requires a Kubernetes cluster with Knative Serving installed.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
kube_config: K8sConfig = None,
|
|
52
|
+
registry_config: RegistryConfig = RegistryConfig(),
|
|
53
|
+
build_context_dir: str = "/tmp/k8s_build",
|
|
54
|
+
):
|
|
55
|
+
"""
|
|
56
|
+
Initialize the Knative deployer.
|
|
57
|
+
"""
|
|
58
|
+
super().__init__()
|
|
59
|
+
self.kubeconfig = kube_config
|
|
60
|
+
self.registry_config = registry_config
|
|
61
|
+
self.image_factory = ImageFactory()
|
|
62
|
+
self.build_context_dir = build_context_dir
|
|
63
|
+
self._deployed_resources = {}
|
|
64
|
+
self._built_images = {}
|
|
65
|
+
|
|
66
|
+
self.knative_client = KnativeClient(
|
|
67
|
+
config=self.kubeconfig,
|
|
68
|
+
image_registry=self.registry_config.get_full_url(),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
async def deploy(
|
|
72
|
+
self,
|
|
73
|
+
app=None,
|
|
74
|
+
runner=None,
|
|
75
|
+
stream: bool = True,
|
|
76
|
+
protocol_adapters: Optional[list[ProtocolAdapter]] = None,
|
|
77
|
+
requirements: Optional[Union[str, List[str]]] = None,
|
|
78
|
+
extra_packages: Optional[List[str]] = None,
|
|
79
|
+
base_image: str = "python:3.9-slim",
|
|
80
|
+
environment: Dict = None,
|
|
81
|
+
runtime_config: Dict = None,
|
|
82
|
+
annotations: Dict = None,
|
|
83
|
+
labels: Dict = None,
|
|
84
|
+
port: int = 8080,
|
|
85
|
+
mount_dir: str = None,
|
|
86
|
+
image_name: str = "agent_llm",
|
|
87
|
+
image_tag: str = "latest",
|
|
88
|
+
push_to_registry: bool = False,
|
|
89
|
+
**kwargs,
|
|
90
|
+
) -> Dict[str, Any]:
|
|
91
|
+
"""
|
|
92
|
+
Deploy the runner as a Knative Service.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
app: Agent app to be deployed
|
|
96
|
+
runner: Complete Runner object with agent, environment_manager,
|
|
97
|
+
context_manager
|
|
98
|
+
stream: Enable streaming responses
|
|
99
|
+
protocol_adapters: protocol adapters
|
|
100
|
+
requirements: PyPI dependencies (following _agent_engines.py
|
|
101
|
+
pattern)
|
|
102
|
+
extra_packages: User code directory/file path
|
|
103
|
+
base_image: Docker base image
|
|
104
|
+
port: Container port
|
|
105
|
+
environment: Environment variables dict
|
|
106
|
+
mount_dir: Mount directory
|
|
107
|
+
runtime_config: K8s runtime configuration
|
|
108
|
+
annotations: knative service annotations
|
|
109
|
+
labels: knative service labels
|
|
110
|
+
# Backward compatibility
|
|
111
|
+
image_name: Image name
|
|
112
|
+
image_tag: Image tag
|
|
113
|
+
push_to_registry: Push to registry
|
|
114
|
+
**kwargs: Additional arguments
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Dict containing deploy_id, url, resource_name
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
RuntimeError: If kservice fails
|
|
121
|
+
|
|
122
|
+
"""
|
|
123
|
+
created_resources = []
|
|
124
|
+
deploy_id = self.deploy_id
|
|
125
|
+
try:
|
|
126
|
+
logger.info(f"Starting Knative Service {deploy_id}")
|
|
127
|
+
|
|
128
|
+
# Step 1: Build image with proper error handling
|
|
129
|
+
logger.info("Building runner image...")
|
|
130
|
+
try:
|
|
131
|
+
built_image_name = self.image_factory.build_image(
|
|
132
|
+
app=app,
|
|
133
|
+
runner=runner,
|
|
134
|
+
base_image=base_image,
|
|
135
|
+
build_context_dir=self.build_context_dir,
|
|
136
|
+
registry_config=self.registry_config,
|
|
137
|
+
image_name=image_name,
|
|
138
|
+
image_tag=image_tag,
|
|
139
|
+
push_to_registry=push_to_registry,
|
|
140
|
+
port=port,
|
|
141
|
+
protocol_adapters=protocol_adapters,
|
|
142
|
+
**kwargs,
|
|
143
|
+
)
|
|
144
|
+
if not built_image_name:
|
|
145
|
+
raise RuntimeError(
|
|
146
|
+
"Image build failed - no image name returned",
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
created_resources.append(f"image:{built_image_name}")
|
|
150
|
+
self._built_images[deploy_id] = built_image_name
|
|
151
|
+
logger.info(f"Image built successfully: {built_image_name}")
|
|
152
|
+
except Exception as e:
|
|
153
|
+
logger.error(f"Image build failed: {e}")
|
|
154
|
+
raise RuntimeError(f"Failed to build image: {e}") from e
|
|
155
|
+
|
|
156
|
+
if mount_dir:
|
|
157
|
+
if not os.path.isabs(mount_dir):
|
|
158
|
+
mount_dir = os.path.abspath(mount_dir)
|
|
159
|
+
|
|
160
|
+
volume_bindings = {
|
|
161
|
+
mount_dir: {
|
|
162
|
+
"bind": mount_dir,
|
|
163
|
+
"mode": "rw",
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
else:
|
|
167
|
+
volume_bindings = {}
|
|
168
|
+
|
|
169
|
+
resource_name = self.get_resource_name(deploy_id)
|
|
170
|
+
|
|
171
|
+
logger.info(f"Building Knative Service for {deploy_id}")
|
|
172
|
+
|
|
173
|
+
# Create Knative Service
|
|
174
|
+
name, url = self.knative_client.create_kservice(
|
|
175
|
+
name=resource_name,
|
|
176
|
+
image=built_image_name,
|
|
177
|
+
ports=[port],
|
|
178
|
+
volumes=volume_bindings,
|
|
179
|
+
environment=environment,
|
|
180
|
+
runtime_config=runtime_config or {},
|
|
181
|
+
annotations=annotations or {},
|
|
182
|
+
labels=labels or {},
|
|
183
|
+
)
|
|
184
|
+
if not url:
|
|
185
|
+
import traceback
|
|
186
|
+
|
|
187
|
+
raise RuntimeError(
|
|
188
|
+
f"Failed to create resource: "
|
|
189
|
+
f"{resource_name}, {traceback.format_exc()}",
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
logger.info(f"Knative Service url {url} successful")
|
|
193
|
+
self._deployed_resources[deploy_id] = {
|
|
194
|
+
"resource_name": name,
|
|
195
|
+
"config": {
|
|
196
|
+
"runner": runner.__class__.__name__,
|
|
197
|
+
"extra_packages": extra_packages,
|
|
198
|
+
"requirements": requirements, # New format
|
|
199
|
+
"base_image": base_image,
|
|
200
|
+
"port": port,
|
|
201
|
+
"environment": environment,
|
|
202
|
+
"runtime_config": runtime_config,
|
|
203
|
+
"stream": stream,
|
|
204
|
+
"protocol_adapters": protocol_adapters,
|
|
205
|
+
**kwargs,
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
"deploy_id": deploy_id,
|
|
210
|
+
"resource_name": resource_name,
|
|
211
|
+
"url": url,
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
except Exception as e:
|
|
215
|
+
import traceback
|
|
216
|
+
|
|
217
|
+
logger.error(f"Knative Service {deploy_id} failed: {e}")
|
|
218
|
+
# Enhanced rollback with better error handling
|
|
219
|
+
raise RuntimeError(
|
|
220
|
+
f"Knative Service failed: {e}, {traceback.format_exc()}",
|
|
221
|
+
) from e
|
|
222
|
+
|
|
223
|
+
@staticmethod
|
|
224
|
+
def get_resource_name(deploy_id: str) -> str:
|
|
225
|
+
return f"agent-{deploy_id[:8]}"
|
|
226
|
+
|
|
227
|
+
async def stop(
|
|
228
|
+
self,
|
|
229
|
+
deploy_id: str,
|
|
230
|
+
**kwargs,
|
|
231
|
+
) -> Dict[str, Any]:
|
|
232
|
+
"""Stop Knative Service.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
deploy_id: Deployment identifier
|
|
236
|
+
**kwargs: Additional parameters
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Dict with success status, message, and details
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
|
+
resource_name = self.get_resource_name(deploy_id)
|
|
243
|
+
try:
|
|
244
|
+
# Try to remove the KService
|
|
245
|
+
success = self.knative_client.delete_kservice(resource_name)
|
|
246
|
+
|
|
247
|
+
if success:
|
|
248
|
+
return {
|
|
249
|
+
"success": True,
|
|
250
|
+
"message": f"Knative deployment {resource_name} "
|
|
251
|
+
f"removed",
|
|
252
|
+
"details": {
|
|
253
|
+
"deploy_id": deploy_id,
|
|
254
|
+
"resource_name": resource_name,
|
|
255
|
+
},
|
|
256
|
+
}
|
|
257
|
+
else:
|
|
258
|
+
return {
|
|
259
|
+
"success": False,
|
|
260
|
+
"message": f"Knative deployment {resource_name} not "
|
|
261
|
+
f"found (may already be deleted), Please check the "
|
|
262
|
+
f"detail in cluster",
|
|
263
|
+
"details": {
|
|
264
|
+
"deploy_id": deploy_id,
|
|
265
|
+
"resource_name": resource_name,
|
|
266
|
+
},
|
|
267
|
+
}
|
|
268
|
+
except Exception as e:
|
|
269
|
+
logger.error(
|
|
270
|
+
f"Failed to remove Knative service {resource_name}: {e}",
|
|
271
|
+
)
|
|
272
|
+
return {
|
|
273
|
+
"success": False,
|
|
274
|
+
"message": f"Failed to remove Knative service: {e}",
|
|
275
|
+
"details": {
|
|
276
|
+
"deploy_id": deploy_id,
|
|
277
|
+
"resource_name": resource_name,
|
|
278
|
+
"error": str(e),
|
|
279
|
+
},
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
def get_status(self) -> str:
|
|
283
|
+
"""Get KService status"""
|
|
284
|
+
if self.deploy_id not in self._deployed_resources:
|
|
285
|
+
return "not_found"
|
|
286
|
+
|
|
287
|
+
resources = self._deployed_resources[self.deploy_id]
|
|
288
|
+
kservice_name = resources["resource_name"]
|
|
289
|
+
|
|
290
|
+
return self.knative_client.get_kservice_status(kservice_name)
|
|
@@ -272,6 +272,18 @@ class Runner:
|
|
|
272
272
|
kwargs.update(
|
|
273
273
|
{"msgs": await message_to_agno_message(request.input)},
|
|
274
274
|
)
|
|
275
|
+
elif self.framework_type == "ms_agent_framework":
|
|
276
|
+
from ..adapters.ms_agent_framework.stream import (
|
|
277
|
+
adapt_ms_agent_framework_message_stream,
|
|
278
|
+
)
|
|
279
|
+
from ..adapters.ms_agent_framework.message import (
|
|
280
|
+
message_to_ms_agent_framework_message,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
stream_adapter = adapt_ms_agent_framework_message_stream
|
|
284
|
+
kwargs.update(
|
|
285
|
+
{"msgs": message_to_ms_agent_framework_message(request.input)},
|
|
286
|
+
)
|
|
275
287
|
# TODO: support other frameworks
|
|
276
288
|
else:
|
|
277
289
|
|
|
@@ -23,7 +23,7 @@ class RedisStateService(StateService):
|
|
|
23
23
|
redis_client: Optional[aioredis.Redis] = None,
|
|
24
24
|
socket_timeout: Optional[float] = 5.0,
|
|
25
25
|
socket_connect_timeout: Optional[float] = 5.0,
|
|
26
|
-
max_connections: Optional[int] =
|
|
26
|
+
max_connections: Optional[int] = None,
|
|
27
27
|
retry_on_timeout: bool = True,
|
|
28
28
|
ttl_seconds: Optional[int] = 3600, # 1 hour in seconds
|
|
29
29
|
health_check_interval: Optional[float] = 30.0,
|
|
@@ -39,7 +39,7 @@ class RedisStateService(StateService):
|
|
|
39
39
|
socket_connect_timeout: Socket connect timeout in seconds
|
|
40
40
|
(default: 5.0)
|
|
41
41
|
max_connections: Maximum number of connections in the pool
|
|
42
|
-
(default:
|
|
42
|
+
(default: None)
|
|
43
43
|
retry_on_timeout: Whether to retry on timeout (default: True)
|
|
44
44
|
ttl_seconds: Time-to-live in seconds for state data. If None,
|
|
45
45
|
data never expires (default: 3600, i.e., 1 hour)
|
|
@@ -19,7 +19,7 @@ class RedisMemoryService(MemoryService):
|
|
|
19
19
|
redis_client: Optional[aioredis.Redis] = None,
|
|
20
20
|
socket_timeout: Optional[float] = 5.0,
|
|
21
21
|
socket_connect_timeout: Optional[float] = 5.0,
|
|
22
|
-
max_connections: Optional[int] =
|
|
22
|
+
max_connections: Optional[int] = None,
|
|
23
23
|
retry_on_timeout: bool = True,
|
|
24
24
|
ttl_seconds: Optional[int] = 3600, # 1 hour in seconds
|
|
25
25
|
max_messages_per_session: Optional[int] = None,
|
|
@@ -36,7 +36,7 @@ class RedisMemoryService(MemoryService):
|
|
|
36
36
|
socket_connect_timeout: Socket connect timeout in seconds
|
|
37
37
|
(default: 5.0)
|
|
38
38
|
max_connections: Maximum number of connections in the pool
|
|
39
|
-
(default:
|
|
39
|
+
(default: None)
|
|
40
40
|
retry_on_timeout: Whether to retry on timeout (default: True)
|
|
41
41
|
ttl_seconds: Time-to-live in seconds for memory data.
|
|
42
42
|
If None, data never expires (default: 3600, i.e., 1 hour)
|
|
@@ -17,7 +17,7 @@ class RedisSessionHistoryService(SessionHistoryService):
|
|
|
17
17
|
redis_client: Optional[aioredis.Redis] = None,
|
|
18
18
|
socket_timeout: Optional[float] = 5.0,
|
|
19
19
|
socket_connect_timeout: Optional[float] = 5.0,
|
|
20
|
-
max_connections: Optional[int] =
|
|
20
|
+
max_connections: Optional[int] = None,
|
|
21
21
|
retry_on_timeout: bool = True,
|
|
22
22
|
ttl_seconds: Optional[int] = 3600, # 1 hour in seconds
|
|
23
23
|
max_messages_per_session: Optional[int] = None,
|
|
@@ -34,7 +34,7 @@ class RedisSessionHistoryService(SessionHistoryService):
|
|
|
34
34
|
socket_connect_timeout: Socket connect timeout in seconds
|
|
35
35
|
(default: 5.0)
|
|
36
36
|
max_connections: Maximum number of connections in the pool
|
|
37
|
-
(default:
|
|
37
|
+
(default: None)
|
|
38
38
|
retry_on_timeout: Whether to retry on timeout (default: True)
|
|
39
39
|
ttl_seconds: Time-to-live in seconds for session data.
|
|
40
40
|
If None, data never expires (default: 3600, i.e., 1 hour)
|
|
@@ -26,7 +26,11 @@ from typing import (
|
|
|
26
26
|
from pydantic import BaseModel
|
|
27
27
|
from opentelemetry.propagate import extract
|
|
28
28
|
from opentelemetry.context import attach
|
|
29
|
-
from opentelemetry.trace import
|
|
29
|
+
from opentelemetry.trace import (
|
|
30
|
+
ProxyTracerProvider,
|
|
31
|
+
StatusCode,
|
|
32
|
+
NoOpTracerProvider,
|
|
33
|
+
)
|
|
30
34
|
from opentelemetry import trace as ot_trace
|
|
31
35
|
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
|
|
32
36
|
OTLPSpanExporter as OTLPSpanGrpcExporter,
|
|
@@ -917,12 +921,22 @@ def _get_ot_tracer() -> ot_trace.Tracer:
|
|
|
917
921
|
ot_trace.Tracer: The OpenTelemetry tracer instance.
|
|
918
922
|
"""
|
|
919
923
|
|
|
920
|
-
def
|
|
924
|
+
def _has_existing_trace_provider() -> bool:
|
|
925
|
+
from opentelemetry.trace import _TRACER_PROVIDER
|
|
926
|
+
|
|
921
927
|
existing_provider = ot_trace.get_tracer_provider()
|
|
928
|
+
if isinstance(existing_provider, NoOpTracerProvider):
|
|
929
|
+
return False
|
|
930
|
+
elif isinstance(existing_provider, ProxyTracerProvider):
|
|
931
|
+
# ProxyTracerProvider will use the _TRACER_PROVIDER as real tracer
|
|
932
|
+
# provider to get the tracer
|
|
933
|
+
return bool(_TRACER_PROVIDER)
|
|
922
934
|
|
|
923
|
-
|
|
924
|
-
return ot_trace.get_tracer("agentscope_runtime")
|
|
935
|
+
return True
|
|
925
936
|
|
|
937
|
+
def _get_ot_tracer_inner() -> ot_trace.Tracer:
|
|
938
|
+
if _has_existing_trace_provider():
|
|
939
|
+
return ot_trace.get_tracer("agentscope_runtime")
|
|
926
940
|
resource = Resource(
|
|
927
941
|
attributes={
|
|
928
942
|
SERVICE_NAME: _get_service_name(),
|
|
@@ -3,22 +3,30 @@
|
|
|
3
3
|
# This ensures SandboxRegistry.register() runs at import time.
|
|
4
4
|
# Without this, lazy loading delays module import and types may not be
|
|
5
5
|
# registered.
|
|
6
|
-
from .box.base.base_sandbox import BaseSandbox
|
|
7
|
-
from .box.browser.browser_sandbox import BrowserSandbox
|
|
8
|
-
from .box.filesystem.filesystem_sandbox import
|
|
9
|
-
|
|
6
|
+
from .box.base.base_sandbox import BaseSandbox, BaseSandboxAsync
|
|
7
|
+
from .box.browser.browser_sandbox import BrowserSandbox, BrowserSandboxAsync
|
|
8
|
+
from .box.filesystem.filesystem_sandbox import (
|
|
9
|
+
FilesystemSandbox,
|
|
10
|
+
FilesystemSandboxAsync,
|
|
11
|
+
)
|
|
12
|
+
from .box.gui.gui_sandbox import GuiSandbox, GuiSandboxAsync
|
|
13
|
+
from .box.mobile.mobile_sandbox import MobileSandbox, MobileSandboxAsync
|
|
10
14
|
from .box.training_box.training_box import TrainingSandbox
|
|
11
15
|
from .box.cloud.cloud_sandbox import CloudSandbox
|
|
12
|
-
from .box.mobile.mobile_sandbox import MobileSandbox
|
|
13
16
|
from .box.agentbay.agentbay_sandbox import AgentbaySandbox
|
|
14
17
|
|
|
15
18
|
__all__ = [
|
|
16
19
|
"BaseSandbox",
|
|
20
|
+
"BaseSandboxAsync",
|
|
17
21
|
"BrowserSandbox",
|
|
22
|
+
"BrowserSandboxAsync",
|
|
18
23
|
"FilesystemSandbox",
|
|
24
|
+
"FilesystemSandboxAsync",
|
|
19
25
|
"GuiSandbox",
|
|
26
|
+
"GuiSandboxAsync",
|
|
27
|
+
"MobileSandbox",
|
|
28
|
+
"MobileSandboxAsync",
|
|
20
29
|
"TrainingSandbox",
|
|
21
30
|
"CloudSandbox",
|
|
22
|
-
"MobileSandbox",
|
|
23
31
|
"AgentbaySandbox",
|
|
24
32
|
]
|
|
@@ -4,7 +4,7 @@ from typing import Optional
|
|
|
4
4
|
from ...utils import build_image_uri
|
|
5
5
|
from ...registry import SandboxRegistry
|
|
6
6
|
from ...enums import SandboxType
|
|
7
|
-
from ...box.sandbox import Sandbox
|
|
7
|
+
from ...box.sandbox import Sandbox, SandboxAsync
|
|
8
8
|
from ...constant import TIMEOUT
|
|
9
9
|
|
|
10
10
|
|
|
@@ -49,3 +49,53 @@ class BaseSandbox(Sandbox):
|
|
|
49
49
|
command (str): Shell command to execute.
|
|
50
50
|
"""
|
|
51
51
|
return self.call_tool("run_shell_command", {"command": command})
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@SandboxRegistry.register(
|
|
55
|
+
build_image_uri("runtime-sandbox-base"),
|
|
56
|
+
sandbox_type=SandboxType.BASE_ASYNC,
|
|
57
|
+
security_level="medium",
|
|
58
|
+
timeout=TIMEOUT,
|
|
59
|
+
description="Base Sandbox (Async)",
|
|
60
|
+
)
|
|
61
|
+
class BaseSandboxAsync(SandboxAsync):
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
sandbox_id: Optional[str] = None,
|
|
65
|
+
timeout: int = 3000,
|
|
66
|
+
base_url: Optional[str] = None,
|
|
67
|
+
bearer_token: Optional[str] = None,
|
|
68
|
+
sandbox_type: SandboxType = SandboxType.BASE_ASYNC,
|
|
69
|
+
):
|
|
70
|
+
super().__init__(
|
|
71
|
+
sandbox_id,
|
|
72
|
+
timeout,
|
|
73
|
+
base_url,
|
|
74
|
+
bearer_token,
|
|
75
|
+
sandbox_type,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
async def run_ipython_cell(self, code: str):
|
|
79
|
+
"""
|
|
80
|
+
Run an IPython cell asynchronously.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
code (str): IPython code to execute.
|
|
84
|
+
Returns:
|
|
85
|
+
Any: Response from sandbox execution
|
|
86
|
+
"""
|
|
87
|
+
return await self.call_tool_async("run_ipython_cell", {"code": code})
|
|
88
|
+
|
|
89
|
+
async def run_shell_command(self, command: str):
|
|
90
|
+
"""
|
|
91
|
+
Run a shell command asynchronously.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
command (str): Shell command to execute.
|
|
95
|
+
Returns:
|
|
96
|
+
Any: Response from sandbox execution
|
|
97
|
+
"""
|
|
98
|
+
return await self.call_tool_async(
|
|
99
|
+
"run_shell_command",
|
|
100
|
+
{"command": command},
|
|
101
|
+
)
|