agentscope-runtime 0.1.5b2__py3-none-any.whl → 0.1.6__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/engine/agents/agentscope_agent.py +447 -0
- agentscope_runtime/engine/agents/agno_agent.py +19 -18
- agentscope_runtime/engine/agents/autogen_agent.py +13 -8
- agentscope_runtime/engine/agents/utils.py +53 -0
- agentscope_runtime/engine/deployers/__init__.py +0 -13
- agentscope_runtime/engine/deployers/local_deployer.py +501 -356
- agentscope_runtime/engine/helpers/helper.py +60 -41
- agentscope_runtime/engine/runner.py +11 -36
- agentscope_runtime/engine/schemas/agent_schemas.py +2 -70
- agentscope_runtime/engine/services/sandbox_service.py +62 -70
- agentscope_runtime/engine/services/tablestore_memory_service.py +304 -0
- agentscope_runtime/engine/services/tablestore_rag_service.py +143 -0
- agentscope_runtime/engine/services/tablestore_session_history_service.py +293 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +352 -0
- agentscope_runtime/sandbox/__init__.py +2 -0
- agentscope_runtime/sandbox/box/base/__init__.py +4 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -3
- agentscope_runtime/sandbox/box/browser/__init__.py +4 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +8 -13
- agentscope_runtime/sandbox/box/dummy/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +8 -6
- agentscope_runtime/sandbox/box/gui/__init__.py +4 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +80 -0
- agentscope_runtime/sandbox/box/sandbox.py +5 -2
- agentscope_runtime/sandbox/box/shared/routers/generic.py +20 -1
- agentscope_runtime/sandbox/box/training_box/__init__.py +4 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +10 -15
- agentscope_runtime/sandbox/build.py +143 -58
- agentscope_runtime/sandbox/client/http_client.py +43 -49
- agentscope_runtime/sandbox/client/training_client.py +0 -1
- agentscope_runtime/sandbox/constant.py +24 -1
- agentscope_runtime/sandbox/custom/custom_sandbox.py +5 -5
- agentscope_runtime/sandbox/custom/example.py +2 -2
- agentscope_runtime/sandbox/enums.py +1 -0
- agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +11 -6
- agentscope_runtime/sandbox/manager/collections/redis_mapping.py +25 -9
- agentscope_runtime/sandbox/manager/container_clients/__init__.py +0 -10
- agentscope_runtime/sandbox/manager/container_clients/agentrun_client.py +1098 -0
- agentscope_runtime/sandbox/manager/container_clients/docker_client.py +33 -205
- agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +8 -555
- agentscope_runtime/sandbox/manager/sandbox_manager.py +187 -88
- agentscope_runtime/sandbox/manager/server/app.py +82 -14
- agentscope_runtime/sandbox/manager/server/config.py +50 -3
- agentscope_runtime/sandbox/model/container.py +6 -23
- agentscope_runtime/sandbox/model/manager_config.py +93 -5
- agentscope_runtime/sandbox/tools/gui/__init__.py +7 -0
- agentscope_runtime/sandbox/tools/gui/tool.py +77 -0
- agentscope_runtime/sandbox/tools/mcp_tool.py +6 -2
- agentscope_runtime/sandbox/utils.py +124 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/entry_points.txt +0 -1
- agentscope_runtime/engine/agents/agentscope_agent/__init__.py +0 -6
- agentscope_runtime/engine/agents/agentscope_agent/agent.py +0 -401
- agentscope_runtime/engine/agents/agentscope_agent/hooks.py +0 -169
- agentscope_runtime/engine/agents/llm_agent.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +0 -2886
- agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +0 -314
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +0 -184
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -677
- agentscope_runtime/engine/deployers/utils/deployment_modes.py +0 -14
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +0 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +0 -429
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +0 -240
- agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +0 -297
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -932
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -9
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +0 -504
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +0 -157
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +0 -268
- 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/deployers/utils/wheel_packager.py +0 -389
- agentscope_runtime/engine/helpers/agent_api_builder.py +0 -651
- agentscope_runtime/engine/llms/__init__.py +0 -3
- agentscope_runtime/engine/llms/base_llm.py +0 -60
- agentscope_runtime/engine/llms/qwen_llm.py +0 -47
- agentscope_runtime/engine/schemas/embedding.py +0 -37
- agentscope_runtime/engine/schemas/modelstudio_llm.py +0 -310
- agentscope_runtime/engine/schemas/oai_llm.py +0 -538
- agentscope_runtime/engine/schemas/realtime.py +0 -254
- /agentscope_runtime/engine/{deployers/adapter/responses → services/utils}/__init__.py +0 -0
- /agentscope_runtime/{engine/deployers/utils → sandbox/box/gui/box}/__init__.py +0 -0
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1098 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint: disable=line-too-long, arguments-renamed
|
|
3
|
+
import logging
|
|
4
|
+
import random
|
|
5
|
+
import string
|
|
6
|
+
import time
|
|
7
|
+
from http.client import HTTPS_PORT
|
|
8
|
+
from typing import List, Optional, Dict
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
|
|
11
|
+
from alibabacloud_agentrun20250910.models import (
|
|
12
|
+
ContainerConfiguration,
|
|
13
|
+
CreateAgentRuntimeRequest,
|
|
14
|
+
CreateAgentRuntimeInput,
|
|
15
|
+
CreateAgentRuntimeEndpointRequest,
|
|
16
|
+
CreateAgentRuntimeEndpointInput,
|
|
17
|
+
NetworkConfiguration,
|
|
18
|
+
LogConfiguration,
|
|
19
|
+
GetAgentRuntimeRequest,
|
|
20
|
+
HealthCheckConfiguration,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
from alibabacloud_agentrun20250910.client import Client
|
|
24
|
+
from alibabacloud_tea_openapi import models as open_api_models
|
|
25
|
+
|
|
26
|
+
from agentscope_runtime.sandbox.model import SandboxManagerEnvConfig
|
|
27
|
+
from .base_client import BaseClient
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AgentRunSessionManager:
|
|
33
|
+
"""
|
|
34
|
+
Manager for AgentRun sessions that handles creation, retrieval,
|
|
35
|
+
updating, and deletion of sessions.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
"""Initialize the session manager with an empty session dictionary."""
|
|
40
|
+
self.sessions = {}
|
|
41
|
+
logger.debug("AgentRunSessionManager initialized")
|
|
42
|
+
|
|
43
|
+
def create_session(self, session_id: str, session_data: Dict):
|
|
44
|
+
"""Create a new session with the given session_id and session_data.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
session_id (str): Unique identifier for the session.
|
|
48
|
+
session_data (Dict): Data to store in the session.
|
|
49
|
+
"""
|
|
50
|
+
self.sessions[session_id] = session_data
|
|
51
|
+
logger.info(f"Created AgentRun session: {session_id}")
|
|
52
|
+
|
|
53
|
+
def get_session(self, session_id: str) -> Optional[Dict]:
|
|
54
|
+
"""Retrieve session data by session_id.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
session_id (str): Unique identifier for the session.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Optional[Dict]: Session data if found, None otherwise.
|
|
61
|
+
"""
|
|
62
|
+
return self.sessions.get(session_id)
|
|
63
|
+
|
|
64
|
+
def update_session(self, session_id: str, updates: Dict):
|
|
65
|
+
"""Update an existing session with new data.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
session_id (str): Unique identifier for the session.
|
|
69
|
+
updates (Dict): Data to update in the session.
|
|
70
|
+
"""
|
|
71
|
+
if session_id in self.sessions:
|
|
72
|
+
self.sessions[session_id].update(updates)
|
|
73
|
+
logger.debug(f"Updated AgentRun session: {session_id}")
|
|
74
|
+
|
|
75
|
+
def delete_session(self, session_id: str):
|
|
76
|
+
"""Delete a session by session_id.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
session_id (str): Unique identifier for the session.
|
|
80
|
+
"""
|
|
81
|
+
if session_id in self.sessions:
|
|
82
|
+
del self.sessions[session_id]
|
|
83
|
+
logger.info(f"Deleted AgentRun session: {session_id}")
|
|
84
|
+
|
|
85
|
+
def list_sessions(self) -> List[str]:
|
|
86
|
+
"""List all session IDs.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
List[str]: List of all session IDs.
|
|
90
|
+
"""
|
|
91
|
+
return list(self.sessions.keys())
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class AgentRunClient(BaseClient):
|
|
95
|
+
"""
|
|
96
|
+
Client for managing AgentRun containers in the sandbox environment.
|
|
97
|
+
|
|
98
|
+
This client provides methods to create, start, stop, remove,
|
|
99
|
+
and inspect AgentRun sessions. It also handles the underlying AgentRun
|
|
100
|
+
API calls and status polling.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
# Global attempts and interval for status polling
|
|
104
|
+
GET_AGENT_RUNTIME_STATUS_MAX_ATTEMPTS = 60
|
|
105
|
+
GET_AGENT_RUNTIME_STATUS_INTERVAL = 1
|
|
106
|
+
|
|
107
|
+
DEFAULT_ENDPOINT_NAME = "default-endpoint"
|
|
108
|
+
|
|
109
|
+
HTTPS_PROTOCOL = "https"
|
|
110
|
+
|
|
111
|
+
def __init__(self, config: SandboxManagerEnvConfig):
|
|
112
|
+
"""Initialize the AgentRunClient with the provided configuration.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
config (SandboxManagerEnvConfig): Configuration object
|
|
116
|
+
containing AgentRun settings.
|
|
117
|
+
"""
|
|
118
|
+
self.config = config
|
|
119
|
+
self.client = self._create_agent_run_client()
|
|
120
|
+
self.session_manager = AgentRunSessionManager()
|
|
121
|
+
self.agent_run_prefix = config.agent_run_prefix or "agentscope-sandbox"
|
|
122
|
+
self._get_agent_runtime_status_max_attempts = (
|
|
123
|
+
self.GET_AGENT_RUNTIME_STATUS_MAX_ATTEMPTS
|
|
124
|
+
)
|
|
125
|
+
self._get_agent_runtime_status_interval = (
|
|
126
|
+
self.GET_AGENT_RUNTIME_STATUS_INTERVAL
|
|
127
|
+
)
|
|
128
|
+
logger.info(f"AgentRunClient initialized with config: {config}")
|
|
129
|
+
|
|
130
|
+
def create(
|
|
131
|
+
self,
|
|
132
|
+
image,
|
|
133
|
+
name=None,
|
|
134
|
+
ports=None,
|
|
135
|
+
volumes=None,
|
|
136
|
+
environment=None,
|
|
137
|
+
runtime_config=None,
|
|
138
|
+
):
|
|
139
|
+
"""Create a new AgentRun session with the specified parameters.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
image (str): The container image to use for the AgentRun session.
|
|
143
|
+
name (str, optional): The name for the session. If not provided,
|
|
144
|
+
a random name will be generated.
|
|
145
|
+
ports (list, optional): List of ports to expose.
|
|
146
|
+
volumes (list, optional): List of volumes to mount.
|
|
147
|
+
environment (dict, optional): Environment variables to set in
|
|
148
|
+
the container.
|
|
149
|
+
runtime_config (dict, optional): Additional runtime configuration.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
tuple: A tuple containing (session_id, None, endpoint_public_url).
|
|
153
|
+
|
|
154
|
+
Raises:
|
|
155
|
+
Exception: If the AgentRun session creation fails.
|
|
156
|
+
"""
|
|
157
|
+
logger.debug(f"Creating AgentRun session with image: {image}")
|
|
158
|
+
port = 80
|
|
159
|
+
if ports is not None and len(ports) > 0:
|
|
160
|
+
port = 80 if ports[0] == "80/tcp" else ports[0]
|
|
161
|
+
|
|
162
|
+
agent_run_image = self._replace_agent_runtime_images(image)
|
|
163
|
+
|
|
164
|
+
try:
|
|
165
|
+
session_id = name or self._generate_session_id()
|
|
166
|
+
logger.info(f"Created AgentRun session: {session_id}")
|
|
167
|
+
agent_runtime_name = f"{self.agent_run_prefix}-{session_id}"
|
|
168
|
+
|
|
169
|
+
# Prepare container configuration
|
|
170
|
+
container_config = ContainerConfiguration(
|
|
171
|
+
image=agent_run_image,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Create agentRuntime
|
|
175
|
+
|
|
176
|
+
# Prepare network configuration if needed
|
|
177
|
+
if (
|
|
178
|
+
self.config.agent_run_vpc_id
|
|
179
|
+
and self.config.agent_run_security_group_id
|
|
180
|
+
and self.config.agent_run_vswitch_ids
|
|
181
|
+
):
|
|
182
|
+
logger.info(
|
|
183
|
+
"Create agent runtime with PUBLIC_AND_PRIVATE network",
|
|
184
|
+
)
|
|
185
|
+
network_config = NetworkConfiguration(
|
|
186
|
+
network_mode="PUBLIC_AND_PRIVATE",
|
|
187
|
+
vpc_id=self.config.agent_run_vpc_id,
|
|
188
|
+
security_group_id=self.config.agent_run_security_group_id,
|
|
189
|
+
vswitch_ids=self.config.agent_run_vswitch_ids,
|
|
190
|
+
)
|
|
191
|
+
else:
|
|
192
|
+
logger.info("Create agent runtime with PUBLIC network")
|
|
193
|
+
network_config = NetworkConfiguration(
|
|
194
|
+
network_mode="PUBLIC",
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Prepare log configuration if needed
|
|
198
|
+
log_config = None
|
|
199
|
+
if (
|
|
200
|
+
self.config.agentrun_log_project
|
|
201
|
+
and self.config.agentrun_log_store
|
|
202
|
+
):
|
|
203
|
+
log_config = LogConfiguration(
|
|
204
|
+
project=self.config.agentrun_log_project,
|
|
205
|
+
logstore=self.config.agentrun_log_store,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
health_check_url = "/"
|
|
209
|
+
health_check_config = HealthCheckConfiguration(
|
|
210
|
+
http_get_url=health_check_url,
|
|
211
|
+
initial_delay_seconds=2,
|
|
212
|
+
period_seconds=1,
|
|
213
|
+
success_threshold=1,
|
|
214
|
+
failure_threshold=60,
|
|
215
|
+
timeout_seconds=1,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Create the input object with all provided parameters
|
|
219
|
+
input_data = CreateAgentRuntimeInput(
|
|
220
|
+
agent_runtime_name=agent_runtime_name,
|
|
221
|
+
artifact_type="Container",
|
|
222
|
+
cpu=self.config.agent_run_cpu,
|
|
223
|
+
memory=self.config.agent_run_memory,
|
|
224
|
+
port=port,
|
|
225
|
+
container_configuration=container_config,
|
|
226
|
+
environment_variables=environment or {},
|
|
227
|
+
network_configuration=network_config,
|
|
228
|
+
log_configuration=log_config,
|
|
229
|
+
health_check_configuration=health_check_config,
|
|
230
|
+
description=f"agentScope sandbox deploy for"
|
|
231
|
+
f" {agent_runtime_name}",
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
# Create and check agent runtime
|
|
235
|
+
agent_runtime_id = self._create_and_check_agent_runtime(input_data)
|
|
236
|
+
|
|
237
|
+
# Create and check agent runtime endpoint
|
|
238
|
+
(
|
|
239
|
+
agent_runtime_endpoint_id,
|
|
240
|
+
endpoint_public_url,
|
|
241
|
+
) = self._create_and_check_agent_runtime_endpoint(
|
|
242
|
+
agent_runtime_id,
|
|
243
|
+
agent_runtime_name,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# Store session information
|
|
247
|
+
session_data = {
|
|
248
|
+
"session_id": session_id,
|
|
249
|
+
"created_time": time.time(),
|
|
250
|
+
"agent_runtime_name": agent_runtime_name,
|
|
251
|
+
"agent_runtime_id": agent_runtime_id,
|
|
252
|
+
"agent_runtime_endpoint_id": agent_runtime_endpoint_id,
|
|
253
|
+
"endpoint_public_url": endpoint_public_url,
|
|
254
|
+
"status": "running",
|
|
255
|
+
"image": image,
|
|
256
|
+
"ports": ports,
|
|
257
|
+
"runtime_token": environment["SECRET_TOKEN"],
|
|
258
|
+
"environment": environment,
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
self.session_manager.create_session(session_id, session_data)
|
|
262
|
+
logger.info(
|
|
263
|
+
f"Success to create agent runtime with ID:"
|
|
264
|
+
f" {agent_runtime_id}, create session id: {session_id}",
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
logger.info(
|
|
268
|
+
f"endpoint_public_url: {endpoint_public_url}",
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
if not endpoint_public_url.endswith("/"):
|
|
272
|
+
endpoint_public_url = f"{endpoint_public_url}/"
|
|
273
|
+
|
|
274
|
+
parsed_url = urlparse(endpoint_public_url)
|
|
275
|
+
|
|
276
|
+
endpoint_public_url_domain = parsed_url.netloc
|
|
277
|
+
endpoint_public_url_path = parsed_url.path
|
|
278
|
+
|
|
279
|
+
# Agentrun should adapt for ip and port format
|
|
280
|
+
ports = [f"{HTTPS_PORT}{endpoint_public_url_path}"]
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
session_id,
|
|
284
|
+
ports,
|
|
285
|
+
endpoint_public_url_domain,
|
|
286
|
+
self.HTTPS_PROTOCOL,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
except Exception as e:
|
|
290
|
+
logger.error(f"Failed to create AgentRun session: {e}")
|
|
291
|
+
raise
|
|
292
|
+
|
|
293
|
+
def start(self, session_id):
|
|
294
|
+
"""Start an AgentRun session by setting its status to running.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
session_id (str): The ID of the session to start.
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
bool: True if the session was successfully started,
|
|
301
|
+
False otherwise.
|
|
302
|
+
"""
|
|
303
|
+
session = self.session_manager.get_session(session_id)
|
|
304
|
+
if not session:
|
|
305
|
+
logger.warning(f"AgentRun session id not found: {session_id}")
|
|
306
|
+
return False
|
|
307
|
+
agent_runtime_id = session["agent_runtime_id"]
|
|
308
|
+
try:
|
|
309
|
+
resp = self._get_agent_runtime_status(agent_runtime_id)
|
|
310
|
+
if resp.get("success"):
|
|
311
|
+
if resp.get("status") in ["READY"]:
|
|
312
|
+
self.session_manager.update_session(
|
|
313
|
+
session_id,
|
|
314
|
+
{"status": "running"},
|
|
315
|
+
)
|
|
316
|
+
logger.info(
|
|
317
|
+
f"set agentRun session status to running: {session_id}",
|
|
318
|
+
)
|
|
319
|
+
return True
|
|
320
|
+
except Exception as e:
|
|
321
|
+
logger.error(
|
|
322
|
+
f"failed to set agentRun session status to running:"
|
|
323
|
+
f" {session_id}: {e}",
|
|
324
|
+
)
|
|
325
|
+
return False
|
|
326
|
+
|
|
327
|
+
def stop(self, session_id, timeout=None):
|
|
328
|
+
"""Stop an AgentRun session by setting its status to stopped.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
session_id (str): The ID of the session to stop.
|
|
332
|
+
timeout (int, optional): Timeout for the stop operation (not
|
|
333
|
+
currently used).
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
bool: True if the session was successfully stopped,
|
|
337
|
+
False otherwise.
|
|
338
|
+
"""
|
|
339
|
+
session = self.session_manager.get_session(session_id)
|
|
340
|
+
if not session:
|
|
341
|
+
logger.warning(f"AgentRun session id not found: {session_id}")
|
|
342
|
+
return False
|
|
343
|
+
|
|
344
|
+
try:
|
|
345
|
+
self.session_manager.update_session(
|
|
346
|
+
session_id,
|
|
347
|
+
{"status": "stopped"},
|
|
348
|
+
)
|
|
349
|
+
logger.info(
|
|
350
|
+
f"set agentRun session status to stopped: {session_id}",
|
|
351
|
+
)
|
|
352
|
+
return True
|
|
353
|
+
|
|
354
|
+
except Exception as e:
|
|
355
|
+
logger.error(
|
|
356
|
+
f"failed to set agentRun session status to stopped:"
|
|
357
|
+
f" {session_id}: {e}",
|
|
358
|
+
)
|
|
359
|
+
return False
|
|
360
|
+
|
|
361
|
+
def remove(self, session_id, force=False):
|
|
362
|
+
"""Remove an AgentRun session by deleting the underlying agent runtime.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
session_id (str): The ID of the session to remove.
|
|
366
|
+
force (bool, optional): Whether to force removal (not currently
|
|
367
|
+
used).
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
dict: A dictionary containing the result of the removal operation.
|
|
371
|
+
"""
|
|
372
|
+
session = self.session_manager.get_session(session_id)
|
|
373
|
+
if not session:
|
|
374
|
+
logger.warning(f"AgentRun session id not found: {session_id}")
|
|
375
|
+
return False
|
|
376
|
+
agent_runtime_id = session["agent_runtime_id"]
|
|
377
|
+
try:
|
|
378
|
+
logger.info(f"Deleting agent runtime with ID: {agent_runtime_id}")
|
|
379
|
+
|
|
380
|
+
# Call the SDK method
|
|
381
|
+
response = self.client.delete_agent_runtime(agent_runtime_id)
|
|
382
|
+
# Check if the response is successful
|
|
383
|
+
if response.body and response.body.code == "SUCCESS":
|
|
384
|
+
logger.info(
|
|
385
|
+
f"Agent runtime deletion initiated successfully for ID:"
|
|
386
|
+
f" {agent_runtime_id}",
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
# Poll for status
|
|
390
|
+
status_result = None
|
|
391
|
+
status_reason = None
|
|
392
|
+
if agent_runtime_id:
|
|
393
|
+
logger.info(
|
|
394
|
+
f"Polling status for agent runtime deletion ID:"
|
|
395
|
+
f" {agent_runtime_id}",
|
|
396
|
+
)
|
|
397
|
+
poll_status = self._poll_agent_runtime_status(
|
|
398
|
+
agent_runtime_id,
|
|
399
|
+
)
|
|
400
|
+
if isinstance(poll_status, dict):
|
|
401
|
+
status_result = poll_status.get("status")
|
|
402
|
+
status_reason = poll_status.get("status_reason")
|
|
403
|
+
logger.info(
|
|
404
|
+
f"Agent runtime deletion status: {status_result}",
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
# Return a dictionary with relevant information from the
|
|
408
|
+
# response
|
|
409
|
+
return {
|
|
410
|
+
"success": True,
|
|
411
|
+
"message": "Agent runtime deletion initiated successfully",
|
|
412
|
+
"agent_runtime_id": agent_runtime_id,
|
|
413
|
+
"status": status_result,
|
|
414
|
+
"status_reason": status_reason,
|
|
415
|
+
"request_id": response.body.request_id,
|
|
416
|
+
}
|
|
417
|
+
else:
|
|
418
|
+
logger.error("Failed to delete agent runtime")
|
|
419
|
+
# Return error information if the request was not successful
|
|
420
|
+
return {
|
|
421
|
+
"success": False,
|
|
422
|
+
"code": response.body.code if response.body else None,
|
|
423
|
+
"message": "Failed to delete agent runtime",
|
|
424
|
+
"request_id": response.body.request_id
|
|
425
|
+
if response.body
|
|
426
|
+
else None,
|
|
427
|
+
}
|
|
428
|
+
except Exception as e:
|
|
429
|
+
logger.error(
|
|
430
|
+
f"Exception occurred while deleting agent runtime: {str(e)}",
|
|
431
|
+
)
|
|
432
|
+
# Return error information if an exception occurred
|
|
433
|
+
return {
|
|
434
|
+
"success": False,
|
|
435
|
+
"error": str(e),
|
|
436
|
+
"message": f"Exception occurred while deleting agent "
|
|
437
|
+
f"runtime: {str(e)}",
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
def inspect(self, session_id):
|
|
441
|
+
"""Inspect an AgentRun session and return detailed information.
|
|
442
|
+
|
|
443
|
+
Args:
|
|
444
|
+
session_id (str): The ID of the session to inspect.
|
|
445
|
+
|
|
446
|
+
Returns:
|
|
447
|
+
dict: A dictionary containing session information,
|
|
448
|
+
agent runtime info, and status.
|
|
449
|
+
"""
|
|
450
|
+
session = self.session_manager.get_session(session_id)
|
|
451
|
+
if not session:
|
|
452
|
+
logger.warning(f"AgentRun session id not found: {session_id}")
|
|
453
|
+
return False
|
|
454
|
+
agent_runtime_id = session["agent_runtime_id"]
|
|
455
|
+
|
|
456
|
+
# Get agent_runtime information
|
|
457
|
+
agent_runtime_info = {}
|
|
458
|
+
try:
|
|
459
|
+
if agent_runtime_id:
|
|
460
|
+
# Create the request object
|
|
461
|
+
request = GetAgentRuntimeRequest()
|
|
462
|
+
|
|
463
|
+
# Call the SDK method
|
|
464
|
+
response = self.client.get_agent_runtime(
|
|
465
|
+
agent_runtime_id,
|
|
466
|
+
request,
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Check if the response is successful
|
|
470
|
+
if (
|
|
471
|
+
response.body
|
|
472
|
+
and response.body.code == "SUCCESS"
|
|
473
|
+
and response.body.data
|
|
474
|
+
):
|
|
475
|
+
# Extract relevant information from the agent runtime data
|
|
476
|
+
agent_runtime = response.body.data
|
|
477
|
+
agent_runtime_info = {
|
|
478
|
+
"agent_runtime_id": agent_runtime.agent_runtime_id,
|
|
479
|
+
"agent_runtime_name": agent_runtime.agent_runtime_name,
|
|
480
|
+
"agent_runtime_arn": agent_runtime.agent_runtime_arn,
|
|
481
|
+
"status": agent_runtime.status,
|
|
482
|
+
"status_reason": agent_runtime.status_reason,
|
|
483
|
+
"artifact_type": agent_runtime.artifact_type,
|
|
484
|
+
"cpu": agent_runtime.cpu,
|
|
485
|
+
"memory": agent_runtime.memory,
|
|
486
|
+
"port": agent_runtime.port,
|
|
487
|
+
"created_at": agent_runtime.created_at,
|
|
488
|
+
"last_updated_at": agent_runtime.last_updated_at,
|
|
489
|
+
"description": agent_runtime.description,
|
|
490
|
+
"agent_runtime_version": agent_runtime.agent_runtime_version, # noqa: E501
|
|
491
|
+
"environment_variables": agent_runtime.environment_variables, # noqa: E501
|
|
492
|
+
"request_id": response.body.request_id,
|
|
493
|
+
}
|
|
494
|
+
else:
|
|
495
|
+
logger.warning(
|
|
496
|
+
f"Failed to get agent runtime info for ID:"
|
|
497
|
+
f" {agent_runtime_id}",
|
|
498
|
+
)
|
|
499
|
+
agent_runtime_info = {
|
|
500
|
+
"error": "Failed to get agent runtime info",
|
|
501
|
+
"agent_runtime_id": agent_runtime_id,
|
|
502
|
+
"code": response.body.code if response.body else None,
|
|
503
|
+
"message": "Failed to get agent runtime info"
|
|
504
|
+
if response.body
|
|
505
|
+
else None,
|
|
506
|
+
}
|
|
507
|
+
except Exception as e:
|
|
508
|
+
logger.error(
|
|
509
|
+
f"Exception occurred while getting agent runtime info:"
|
|
510
|
+
f" {str(e)}",
|
|
511
|
+
)
|
|
512
|
+
agent_runtime_info = {
|
|
513
|
+
"error": str(e),
|
|
514
|
+
"message": f"Exception occurred while getting agent runtime "
|
|
515
|
+
f"info: {str(e)}",
|
|
516
|
+
"agent_runtime_id": agent_runtime_id,
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return {
|
|
520
|
+
"session": session,
|
|
521
|
+
"agent_runtime_info": agent_runtime_info,
|
|
522
|
+
"runtime_token": session.get("runtime_token"),
|
|
523
|
+
"status": session.get("status", "unknown"),
|
|
524
|
+
"endpoint_url": session.get("endpoint_public_url"),
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
def get_status(self, session_id):
|
|
528
|
+
"""Get the status of an AgentRun session.
|
|
529
|
+
|
|
530
|
+
Args:
|
|
531
|
+
session_id (str): The ID of the session to get status for.
|
|
532
|
+
|
|
533
|
+
Returns:
|
|
534
|
+
str: The status of the session (running, exited, starting,
|
|
535
|
+
or unknown).
|
|
536
|
+
"""
|
|
537
|
+
session = self.session_manager.get_session(session_id)
|
|
538
|
+
if not session:
|
|
539
|
+
logger.warning(f"AgentRun session id not found: {session_id}")
|
|
540
|
+
return "unknown"
|
|
541
|
+
agent_runtime_id = session["agent_runtime_id"]
|
|
542
|
+
resp = self._get_agent_runtime_status(agent_runtime_id)
|
|
543
|
+
if resp.get("success"):
|
|
544
|
+
agent_run_status = resp.get("status")
|
|
545
|
+
if agent_run_status in ["READY", "ACTIVE"]:
|
|
546
|
+
return "running"
|
|
547
|
+
if agent_run_status in [
|
|
548
|
+
"CREATE_FAILED",
|
|
549
|
+
"UPDATE_FAILED",
|
|
550
|
+
"FAILED",
|
|
551
|
+
"DELETING",
|
|
552
|
+
]:
|
|
553
|
+
return "exited"
|
|
554
|
+
if agent_run_status in ["CREATING", "UPDATING"]:
|
|
555
|
+
return "starting"
|
|
556
|
+
return session.get("status", "unknown")
|
|
557
|
+
|
|
558
|
+
def _create_agent_run_client(self) -> Client:
|
|
559
|
+
"""Create and configure the AgentRun client.
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
Client: Configured AgentRun client instance.
|
|
563
|
+
"""
|
|
564
|
+
config = open_api_models.Config(
|
|
565
|
+
access_key_id=self.config.agent_run_access_key_id,
|
|
566
|
+
access_key_secret=self.config.agent_run_access_key_secret,
|
|
567
|
+
region_id=self.config.agent_run_region_id,
|
|
568
|
+
read_timeout=60 * 1000,
|
|
569
|
+
)
|
|
570
|
+
config.endpoint = (
|
|
571
|
+
f"agentrun.{self.config.agent_run_region_id}.aliyuncs.com"
|
|
572
|
+
)
|
|
573
|
+
return Client(config)
|
|
574
|
+
|
|
575
|
+
def _generate_session_id(self) -> str:
|
|
576
|
+
"""Generate a random session ID.
|
|
577
|
+
|
|
578
|
+
Returns:
|
|
579
|
+
str: A random 6-character session ID.
|
|
580
|
+
"""
|
|
581
|
+
return "".join(
|
|
582
|
+
random.choices(string.ascii_letters + string.digits, k=6),
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
def _create_and_check_agent_runtime(
|
|
586
|
+
self,
|
|
587
|
+
input_data: CreateAgentRuntimeInput,
|
|
588
|
+
) -> str:
|
|
589
|
+
"""Create an agent runtime and check its status until it's ready.
|
|
590
|
+
|
|
591
|
+
Args:
|
|
592
|
+
input_data (CreateAgentRuntimeInput): The input data for
|
|
593
|
+
creating the agent runtime.
|
|
594
|
+
|
|
595
|
+
Returns:
|
|
596
|
+
str: The agent runtime ID.
|
|
597
|
+
|
|
598
|
+
Raises:
|
|
599
|
+
Exception: If the agent runtime creation fails or the agent
|
|
600
|
+
runtime is not ready.
|
|
601
|
+
"""
|
|
602
|
+
# Create the request object
|
|
603
|
+
agent_runtime_id = None
|
|
604
|
+
try:
|
|
605
|
+
create_agent_runtime_req = CreateAgentRuntimeRequest(
|
|
606
|
+
body=input_data,
|
|
607
|
+
)
|
|
608
|
+
create_agent_runtime_res = self.client.create_agent_runtime(
|
|
609
|
+
create_agent_runtime_req,
|
|
610
|
+
)
|
|
611
|
+
|
|
612
|
+
# Extract agent_runtime_id from response
|
|
613
|
+
if (
|
|
614
|
+
create_agent_runtime_res.body
|
|
615
|
+
and create_agent_runtime_res.body.data
|
|
616
|
+
):
|
|
617
|
+
agent_runtime_id = (
|
|
618
|
+
create_agent_runtime_res.body.data.agent_runtime_id
|
|
619
|
+
)
|
|
620
|
+
except Exception as e:
|
|
621
|
+
logger.error(f"Failed to create agent runtime: {e}")
|
|
622
|
+
raise
|
|
623
|
+
|
|
624
|
+
# Poll and check agent runtime status
|
|
625
|
+
if agent_runtime_id:
|
|
626
|
+
status_response = self._poll_agent_runtime_status(agent_runtime_id)
|
|
627
|
+
if not status_response.get("success"):
|
|
628
|
+
logger.error(
|
|
629
|
+
f"Failed to get agent runtime status:"
|
|
630
|
+
f" {status_response.get('message')}",
|
|
631
|
+
)
|
|
632
|
+
raise RuntimeError(
|
|
633
|
+
f"Failed to get agent runtime status:"
|
|
634
|
+
f" {status_response.get('message')}",
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
if status_response.get("status") not in ["READY", "ACTIVE"]:
|
|
638
|
+
logger.error(
|
|
639
|
+
f"Agent runtime is not ready. Status:"
|
|
640
|
+
f" {status_response.get('status')}",
|
|
641
|
+
)
|
|
642
|
+
raise RuntimeError(
|
|
643
|
+
f"Agent runtime is not ready. Status:"
|
|
644
|
+
f" {status_response.get('status')}",
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
return agent_runtime_id
|
|
648
|
+
|
|
649
|
+
def _create_and_check_agent_runtime_endpoint(
|
|
650
|
+
self,
|
|
651
|
+
agent_runtime_id: str,
|
|
652
|
+
agent_runtime_name: str,
|
|
653
|
+
) -> tuple:
|
|
654
|
+
"""Create an agent runtime endpoint and check its status until it's
|
|
655
|
+
ready.
|
|
656
|
+
|
|
657
|
+
Args:
|
|
658
|
+
agent_runtime_id (str): The ID of the agent runtime.
|
|
659
|
+
agent_runtime_name (str): The name of the agent runtime.
|
|
660
|
+
|
|
661
|
+
Returns:
|
|
662
|
+
tuple: A tuple containing (agent_runtime_endpoint_id,
|
|
663
|
+
endpoint_public_url).
|
|
664
|
+
|
|
665
|
+
Raises:
|
|
666
|
+
Exception: If the agent runtime endpoint creation fails or the
|
|
667
|
+
endpoint is not ready.
|
|
668
|
+
"""
|
|
669
|
+
# Create agent runtime endpoint
|
|
670
|
+
agent_runtime_endpoint_id = None
|
|
671
|
+
endpoint_public_url = None
|
|
672
|
+
if agent_runtime_id:
|
|
673
|
+
# Prepare endpoint configuration
|
|
674
|
+
endpoint_input = CreateAgentRuntimeEndpointInput(
|
|
675
|
+
agent_runtime_endpoint_name=self.DEFAULT_ENDPOINT_NAME,
|
|
676
|
+
target_version="LATEST",
|
|
677
|
+
description=f"agentScope deploy auto-generated endpoint for"
|
|
678
|
+
f" {agent_runtime_name}",
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
endpoint_request = CreateAgentRuntimeEndpointRequest(
|
|
682
|
+
body=endpoint_input,
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
try:
|
|
686
|
+
endpoint_response = self.client.create_agent_runtime_endpoint(
|
|
687
|
+
agent_runtime_id,
|
|
688
|
+
endpoint_request,
|
|
689
|
+
)
|
|
690
|
+
if endpoint_response.body and endpoint_response.body.data:
|
|
691
|
+
agent_runtime_endpoint_id = (
|
|
692
|
+
endpoint_response.body.data.agent_runtime_endpoint_id
|
|
693
|
+
)
|
|
694
|
+
endpoint_public_url = (
|
|
695
|
+
endpoint_response.body.data.endpoint_public_url
|
|
696
|
+
)
|
|
697
|
+
except Exception as e:
|
|
698
|
+
logger.error(f"Failed to create agent runtime endpoint: {e}")
|
|
699
|
+
raise
|
|
700
|
+
|
|
701
|
+
# Poll and check agent runtime endpoint status
|
|
702
|
+
if agent_runtime_id and agent_runtime_endpoint_id:
|
|
703
|
+
endpoint_status_response = (
|
|
704
|
+
self._poll_agent_runtime_endpoint_status(
|
|
705
|
+
agent_runtime_id,
|
|
706
|
+
agent_runtime_endpoint_id,
|
|
707
|
+
)
|
|
708
|
+
)
|
|
709
|
+
if not endpoint_status_response.get("success"):
|
|
710
|
+
logger.error(
|
|
711
|
+
f"Failed to get agent runtime endpoint status:"
|
|
712
|
+
f" {endpoint_status_response.get('message')}",
|
|
713
|
+
)
|
|
714
|
+
raise RuntimeError(
|
|
715
|
+
f"Failed to get agent runtime endpoint status:"
|
|
716
|
+
f" {endpoint_status_response.get('message')}",
|
|
717
|
+
)
|
|
718
|
+
|
|
719
|
+
if endpoint_status_response.get("status") not in [
|
|
720
|
+
"READY",
|
|
721
|
+
"ACTIVE",
|
|
722
|
+
]:
|
|
723
|
+
logger.error(
|
|
724
|
+
f"Agent runtime endpoint is not ready. Status:"
|
|
725
|
+
f" {endpoint_status_response.get('status')}",
|
|
726
|
+
)
|
|
727
|
+
raise RuntimeError(
|
|
728
|
+
f"Agent runtime endpoint is not ready. Status:"
|
|
729
|
+
f" {endpoint_status_response.get('status')}",
|
|
730
|
+
)
|
|
731
|
+
|
|
732
|
+
return agent_runtime_endpoint_id, endpoint_public_url
|
|
733
|
+
|
|
734
|
+
def _poll_agent_runtime_endpoint_status(
|
|
735
|
+
self,
|
|
736
|
+
agent_runtime_id: str,
|
|
737
|
+
agent_runtime_endpoint_id: str,
|
|
738
|
+
):
|
|
739
|
+
"""
|
|
740
|
+
Poll agent runtime endpoint status until a terminal state is
|
|
741
|
+
reached or max attempts exceeded.
|
|
742
|
+
|
|
743
|
+
Args:
|
|
744
|
+
agent_runtime_id (str): The ID of the agent runtime.
|
|
745
|
+
agent_runtime_endpoint_id (str): The ID of the agent runtime
|
|
746
|
+
endpoint.
|
|
747
|
+
|
|
748
|
+
Returns:
|
|
749
|
+
Dict[str, Any]: A dictionary containing the final agent runtime
|
|
750
|
+
endpoint status or error information.
|
|
751
|
+
"""
|
|
752
|
+
# Terminal states that indicate the end of polling for endpoints
|
|
753
|
+
terminal_states = {
|
|
754
|
+
"CREATE_FAILED",
|
|
755
|
+
"UPDATE_FAILED",
|
|
756
|
+
"READY",
|
|
757
|
+
"ACTIVE",
|
|
758
|
+
"FAILED",
|
|
759
|
+
"DELETING",
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
# Polling configuration
|
|
763
|
+
max_attempts = self._get_agent_runtime_status_max_attempts
|
|
764
|
+
interval_seconds = self._get_agent_runtime_status_interval
|
|
765
|
+
|
|
766
|
+
logger.info(
|
|
767
|
+
f"Starting to poll agent runtime endpoint status for ID:"
|
|
768
|
+
f" {agent_runtime_endpoint_id}",
|
|
769
|
+
)
|
|
770
|
+
|
|
771
|
+
for attempt in range(1, max_attempts + 1):
|
|
772
|
+
# Get current status
|
|
773
|
+
status_response = self._get_agent_runtime_endpoint_status(
|
|
774
|
+
agent_runtime_id,
|
|
775
|
+
agent_runtime_endpoint_id,
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
# Check if the request was successful
|
|
779
|
+
if not status_response.get("success"):
|
|
780
|
+
logger.warning(
|
|
781
|
+
f"Attempt {attempt}/{max_attempts}: Failed "
|
|
782
|
+
f"to get status - {status_response.get('message')}",
|
|
783
|
+
)
|
|
784
|
+
# Wait before next attempt unless this is the last attempt
|
|
785
|
+
if attempt < max_attempts:
|
|
786
|
+
time.sleep(interval_seconds)
|
|
787
|
+
continue
|
|
788
|
+
|
|
789
|
+
# Extract status information
|
|
790
|
+
current_status = status_response.get("status")
|
|
791
|
+
status_reason = status_response.get("status_reason")
|
|
792
|
+
|
|
793
|
+
# Log current status
|
|
794
|
+
logger.info(
|
|
795
|
+
f"Attempt {attempt}/{max_attempts}: Status = {current_status}",
|
|
796
|
+
)
|
|
797
|
+
if status_reason:
|
|
798
|
+
logger.info(f" Status reason: {status_reason}")
|
|
799
|
+
|
|
800
|
+
# Check if we've reached a terminal state
|
|
801
|
+
if current_status in terminal_states:
|
|
802
|
+
logger.info(
|
|
803
|
+
f"Reached terminal state '{current_status}' after"
|
|
804
|
+
f" {attempt} attempts",
|
|
805
|
+
)
|
|
806
|
+
return status_response
|
|
807
|
+
|
|
808
|
+
# Wait before next attempt unless this is the last attempt
|
|
809
|
+
if attempt < max_attempts:
|
|
810
|
+
time.sleep(interval_seconds)
|
|
811
|
+
|
|
812
|
+
# If we've exhausted all attempts without reaching a terminal state
|
|
813
|
+
logger.warning(
|
|
814
|
+
f"Exceeded maximum attempts ({max_attempts}) without reaching a "
|
|
815
|
+
f"terminal state",
|
|
816
|
+
)
|
|
817
|
+
return self._get_agent_runtime_endpoint_status(
|
|
818
|
+
agent_runtime_id,
|
|
819
|
+
agent_runtime_endpoint_id,
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
def _get_agent_runtime_status(
|
|
823
|
+
self,
|
|
824
|
+
agent_runtime_id: str,
|
|
825
|
+
agent_runtime_version: str = None,
|
|
826
|
+
):
|
|
827
|
+
"""Get agent runtime status.
|
|
828
|
+
|
|
829
|
+
Args:
|
|
830
|
+
agent_runtime_id (str): The ID of the agent runtime.
|
|
831
|
+
agent_runtime_version (str, optional): The version of the agent
|
|
832
|
+
runtime.
|
|
833
|
+
|
|
834
|
+
Returns:
|
|
835
|
+
Dict[str, Any]: A dictionary containing the agent runtime
|
|
836
|
+
status or error information.
|
|
837
|
+
"""
|
|
838
|
+
try:
|
|
839
|
+
logger.debug(
|
|
840
|
+
f"Getting agent runtime status for ID: {agent_runtime_id}",
|
|
841
|
+
)
|
|
842
|
+
|
|
843
|
+
# Create the request object
|
|
844
|
+
request = GetAgentRuntimeRequest(
|
|
845
|
+
agent_runtime_version=agent_runtime_version,
|
|
846
|
+
)
|
|
847
|
+
|
|
848
|
+
# Call the SDK method
|
|
849
|
+
response = self.client.get_agent_runtime(agent_runtime_id, request)
|
|
850
|
+
|
|
851
|
+
# Check if the response is successful
|
|
852
|
+
if (
|
|
853
|
+
response.body
|
|
854
|
+
and response.body.code == "SUCCESS"
|
|
855
|
+
and response.body.data
|
|
856
|
+
):
|
|
857
|
+
status = (
|
|
858
|
+
response.body.data.status
|
|
859
|
+
if hasattr(response.body.data, "status")
|
|
860
|
+
else None
|
|
861
|
+
)
|
|
862
|
+
logger.debug(
|
|
863
|
+
f"Agent runtime status for ID {agent_runtime_id}:"
|
|
864
|
+
f" {status}",
|
|
865
|
+
)
|
|
866
|
+
# Return the status from the agent runtime data
|
|
867
|
+
return {
|
|
868
|
+
"success": True,
|
|
869
|
+
"status": status,
|
|
870
|
+
"status_reason": response.body.data.status_reason
|
|
871
|
+
if hasattr(
|
|
872
|
+
response.body.data,
|
|
873
|
+
"status_reason",
|
|
874
|
+
)
|
|
875
|
+
else None,
|
|
876
|
+
"request_id": response.body.request_id,
|
|
877
|
+
}
|
|
878
|
+
else:
|
|
879
|
+
logger.error("Failed to get agent runtime status")
|
|
880
|
+
# Return error information if the request was not successful
|
|
881
|
+
return {
|
|
882
|
+
"success": False,
|
|
883
|
+
"code": response.body.code if response.body else None,
|
|
884
|
+
"message": "Failed to get agent runtime status",
|
|
885
|
+
"request_id": response.body.request_id
|
|
886
|
+
if response.body
|
|
887
|
+
else None,
|
|
888
|
+
}
|
|
889
|
+
except Exception as e:
|
|
890
|
+
logger.error(
|
|
891
|
+
f"Exception occurred while getting agent runtime status:"
|
|
892
|
+
f" {str(e)}",
|
|
893
|
+
)
|
|
894
|
+
# Return error information if an exception occurred
|
|
895
|
+
return {
|
|
896
|
+
"success": False,
|
|
897
|
+
"error": str(e),
|
|
898
|
+
"message": f"Exception occurred while getting agent runtime "
|
|
899
|
+
f"status: {str(e)}",
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
def _get_agent_runtime_endpoint_status(
|
|
903
|
+
self,
|
|
904
|
+
agent_runtime_id: str,
|
|
905
|
+
agent_runtime_endpoint_id: str,
|
|
906
|
+
):
|
|
907
|
+
"""Get agent runtime endpoint status.
|
|
908
|
+
|
|
909
|
+
Args:
|
|
910
|
+
agent_runtime_id (str): The ID of the agent runtime.
|
|
911
|
+
agent_runtime_endpoint_id (str): The ID of the agent runtime
|
|
912
|
+
endpoint.
|
|
913
|
+
|
|
914
|
+
Returns:
|
|
915
|
+
Dict[str, str]: A dictionary containing the agent runtime
|
|
916
|
+
endpoint status or error information.
|
|
917
|
+
"""
|
|
918
|
+
try:
|
|
919
|
+
logger.debug(
|
|
920
|
+
f"Getting agent runtime endpoint status for ID:"
|
|
921
|
+
f" {agent_runtime_endpoint_id}",
|
|
922
|
+
)
|
|
923
|
+
|
|
924
|
+
# Call the SDK method
|
|
925
|
+
response = self.client.get_agent_runtime_endpoint(
|
|
926
|
+
agent_runtime_id,
|
|
927
|
+
agent_runtime_endpoint_id,
|
|
928
|
+
)
|
|
929
|
+
|
|
930
|
+
# Check if the response is successful
|
|
931
|
+
if (
|
|
932
|
+
response.body
|
|
933
|
+
and response.body.code == "SUCCESS"
|
|
934
|
+
and response.body.data
|
|
935
|
+
):
|
|
936
|
+
status = (
|
|
937
|
+
response.body.data.status
|
|
938
|
+
if hasattr(response.body.data, "status")
|
|
939
|
+
else None
|
|
940
|
+
)
|
|
941
|
+
logger.debug(
|
|
942
|
+
f"Agent runtime endpoint status for ID"
|
|
943
|
+
f" {agent_runtime_endpoint_id}: {status}",
|
|
944
|
+
)
|
|
945
|
+
# Return the status from the agent runtime endpoint data
|
|
946
|
+
return {
|
|
947
|
+
"success": True,
|
|
948
|
+
"status": status,
|
|
949
|
+
"status_reason": response.body.data.status_reason
|
|
950
|
+
if hasattr(
|
|
951
|
+
response.body.data,
|
|
952
|
+
"status_reason",
|
|
953
|
+
)
|
|
954
|
+
else None,
|
|
955
|
+
"request_id": response.body.request_id,
|
|
956
|
+
}
|
|
957
|
+
else:
|
|
958
|
+
logger.debug("Failed to get agent runtime endpoint status")
|
|
959
|
+
# Return error information if the request was not successful
|
|
960
|
+
return {
|
|
961
|
+
"success": False,
|
|
962
|
+
"code": response.body.code if response.body else None,
|
|
963
|
+
"message": "Failed to get agent runtime endpoint status",
|
|
964
|
+
"request_id": response.body.request_id
|
|
965
|
+
if response.body
|
|
966
|
+
else None,
|
|
967
|
+
}
|
|
968
|
+
except Exception as e:
|
|
969
|
+
logger.debug(
|
|
970
|
+
f"Exception occurred while getting agent runtime endpoint "
|
|
971
|
+
f"status: {str(e)}",
|
|
972
|
+
)
|
|
973
|
+
# Return error information if an exception occurred
|
|
974
|
+
return {
|
|
975
|
+
"success": False,
|
|
976
|
+
"error": str(e),
|
|
977
|
+
"message": f"Exception occurred while getting agent runtime "
|
|
978
|
+
f"endpoint status: {str(e)}",
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
def _poll_agent_runtime_status(
|
|
982
|
+
self,
|
|
983
|
+
agent_runtime_id: str,
|
|
984
|
+
agent_runtime_version: str = None,
|
|
985
|
+
):
|
|
986
|
+
"""
|
|
987
|
+
Poll agent runtime status until a terminal state is reached or
|
|
988
|
+
max attempts exceeded.
|
|
989
|
+
|
|
990
|
+
Args:
|
|
991
|
+
agent_runtime_id (str): The ID of the agent runtime.
|
|
992
|
+
agent_runtime_version (str, optional): The version of the agent
|
|
993
|
+
runtime.
|
|
994
|
+
|
|
995
|
+
Returns:
|
|
996
|
+
Dict[str, Any]: A dictionary containing the final agent runtime
|
|
997
|
+
status or error information.
|
|
998
|
+
"""
|
|
999
|
+
# Terminal states that indicate the end of polling for agent runtimes
|
|
1000
|
+
terminal_states = {
|
|
1001
|
+
"CREATE_FAILED",
|
|
1002
|
+
"UPDATE_FAILED",
|
|
1003
|
+
"READY",
|
|
1004
|
+
"ACTIVE",
|
|
1005
|
+
"FAILED",
|
|
1006
|
+
"DELETING",
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
# Polling configuration
|
|
1010
|
+
max_attempts = self._get_agent_runtime_status_max_attempts
|
|
1011
|
+
interval_seconds = self._get_agent_runtime_status_interval
|
|
1012
|
+
|
|
1013
|
+
logger.info(
|
|
1014
|
+
f"Starting to poll agent runtime status for ID:"
|
|
1015
|
+
f" {agent_runtime_id}",
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
for attempt in range(1, max_attempts + 1):
|
|
1019
|
+
# Get current status
|
|
1020
|
+
status_response = self._get_agent_runtime_status(
|
|
1021
|
+
agent_runtime_id,
|
|
1022
|
+
agent_runtime_version,
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
# Check if the request was successful
|
|
1026
|
+
if not status_response.get("success"):
|
|
1027
|
+
logger.warning(
|
|
1028
|
+
f"Attempt {attempt}/{max_attempts}: Failed to "
|
|
1029
|
+
f"get status - {status_response.get('message')}",
|
|
1030
|
+
)
|
|
1031
|
+
# Wait before next attempt unless this is the last attempt
|
|
1032
|
+
if attempt < max_attempts:
|
|
1033
|
+
time.sleep(interval_seconds)
|
|
1034
|
+
continue
|
|
1035
|
+
|
|
1036
|
+
# Extract status information
|
|
1037
|
+
current_status = status_response.get("status")
|
|
1038
|
+
status_reason = status_response.get("status_reason")
|
|
1039
|
+
|
|
1040
|
+
# Log current status
|
|
1041
|
+
logger.info(
|
|
1042
|
+
f"Attempt {attempt}/{max_attempts}: Status = {current_status}",
|
|
1043
|
+
)
|
|
1044
|
+
if status_reason:
|
|
1045
|
+
logger.info(f" Status reason: {status_reason}")
|
|
1046
|
+
|
|
1047
|
+
# Check if we've reached a terminal state
|
|
1048
|
+
if current_status in terminal_states:
|
|
1049
|
+
logger.info(
|
|
1050
|
+
f"Reached terminal state '{current_status}' after"
|
|
1051
|
+
f" {attempt} attempts",
|
|
1052
|
+
)
|
|
1053
|
+
return status_response
|
|
1054
|
+
|
|
1055
|
+
# Wait before next attempt unless this is the last attempt
|
|
1056
|
+
if attempt < max_attempts:
|
|
1057
|
+
time.sleep(interval_seconds)
|
|
1058
|
+
|
|
1059
|
+
# If we've exhausted all attempts without reaching a terminal state
|
|
1060
|
+
logger.warning(
|
|
1061
|
+
f"Exceeded maximum attempts ({max_attempts}) without reaching a "
|
|
1062
|
+
f"terminal state",
|
|
1063
|
+
)
|
|
1064
|
+
return self._get_agent_runtime_status(
|
|
1065
|
+
agent_runtime_id,
|
|
1066
|
+
agent_runtime_version,
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1069
|
+
def _replace_agent_runtime_images(self, image: str) -> str:
|
|
1070
|
+
"""
|
|
1071
|
+
Replace agent runtime images with their corresponding remote images.
|
|
1072
|
+
|
|
1073
|
+
Args:
|
|
1074
|
+
image (str): The original image name.
|
|
1075
|
+
|
|
1076
|
+
Returns:
|
|
1077
|
+
str: The replaced image name with remote registry path.
|
|
1078
|
+
"""
|
|
1079
|
+
replacement_map = {
|
|
1080
|
+
"agentscope/runtime-sandbox-base": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1081
|
+
"/agentscope_runtime-sandbox-base:20251027",
|
|
1082
|
+
"agentscope/runtime-sandbox-browser": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1083
|
+
"/agentscope_runtime-sandbox-browser:20251027",
|
|
1084
|
+
"agentscope/runtime-sandbox-filesystem": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1085
|
+
"/agentscope_runtime-sandbox-filesystem:20251027",
|
|
1086
|
+
"agentscope/runtime-sandbox-gui": "serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai" # noqa: E501
|
|
1087
|
+
"/agentscope_runtime-sandbox-gui:20251027",
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
if ":" in image:
|
|
1091
|
+
image_name, _ = image.split(":", 1)
|
|
1092
|
+
else:
|
|
1093
|
+
image_name = image
|
|
1094
|
+
|
|
1095
|
+
return replacement_map.get(image_name.strip(), image)
|
|
1096
|
+
|
|
1097
|
+
def _is_browser_image(self, image: str):
|
|
1098
|
+
return image.startswith("agentscope/runtime-sandbox-browser")
|