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
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import traceback
|
|
3
3
|
import logging
|
|
4
|
-
import platform
|
|
5
4
|
import socket
|
|
6
|
-
import subprocess
|
|
7
5
|
|
|
8
6
|
import docker
|
|
9
7
|
|
|
10
8
|
from .base_client import BaseClient
|
|
11
|
-
from ..collections import
|
|
9
|
+
from ..collections import (
|
|
10
|
+
RedisSetCollection,
|
|
11
|
+
InMemorySetCollection,
|
|
12
|
+
RedisMapping,
|
|
13
|
+
InMemoryMapping,
|
|
14
|
+
)
|
|
12
15
|
|
|
13
16
|
|
|
14
17
|
logger = logging.getLogger(__name__)
|
|
@@ -34,138 +37,6 @@ def is_port_available(port):
|
|
|
34
37
|
return False
|
|
35
38
|
|
|
36
39
|
|
|
37
|
-
def sweep_port(port):
|
|
38
|
-
"""Sweep all processes found listening on a given port.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
port (int): The port number.
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
bool: True if successful, False if failed.
|
|
45
|
-
"""
|
|
46
|
-
try:
|
|
47
|
-
system = platform.system().lower()
|
|
48
|
-
if system == "windows":
|
|
49
|
-
return _sweep_port_windows(port)
|
|
50
|
-
else:
|
|
51
|
-
return _sweep_port_unix(port)
|
|
52
|
-
except Exception as e:
|
|
53
|
-
logger.error(
|
|
54
|
-
f"An error occurred while killing processes on port {port}: {e}",
|
|
55
|
-
)
|
|
56
|
-
return False
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _sweep_port_unix(port):
|
|
60
|
-
"""
|
|
61
|
-
Sweep all processes found listening on a given port.
|
|
62
|
-
|
|
63
|
-
Args:
|
|
64
|
-
port (int): The port number.
|
|
65
|
-
|
|
66
|
-
Returns:
|
|
67
|
-
int: Number of processes swept (terminated).
|
|
68
|
-
"""
|
|
69
|
-
try:
|
|
70
|
-
# Use lsof to find the processes using the port
|
|
71
|
-
# TODO: support windows
|
|
72
|
-
result = subprocess.run(
|
|
73
|
-
["lsof", "-i", f":{port}"],
|
|
74
|
-
capture_output=True,
|
|
75
|
-
text=True,
|
|
76
|
-
check=True,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
# Parse the output
|
|
80
|
-
lines = result.stdout.strip().split("\n")
|
|
81
|
-
if len(lines) <= 1:
|
|
82
|
-
# No process is using the port
|
|
83
|
-
return True
|
|
84
|
-
|
|
85
|
-
# Iterate over each line (excluding the header) and kill each process
|
|
86
|
-
killed_count = 0
|
|
87
|
-
for line in lines[1:]:
|
|
88
|
-
parts = line.split()
|
|
89
|
-
if len(parts) > 1:
|
|
90
|
-
pid = parts[1]
|
|
91
|
-
|
|
92
|
-
# Kill the process using the PID
|
|
93
|
-
subprocess.run(["kill", "-9", pid], check=False)
|
|
94
|
-
killed_count += 1
|
|
95
|
-
|
|
96
|
-
if not is_port_available(port):
|
|
97
|
-
logger.warning(
|
|
98
|
-
f"Port {port} is still in use after killing processes.",
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
return True
|
|
102
|
-
|
|
103
|
-
except Exception as e:
|
|
104
|
-
logger.error(
|
|
105
|
-
f"An error occurred while killing processes on port {port}: {e}",
|
|
106
|
-
)
|
|
107
|
-
return False
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def _sweep_port_windows(port):
|
|
111
|
-
"""
|
|
112
|
-
Windows implementation using netstat and taskkill
|
|
113
|
-
"""
|
|
114
|
-
try:
|
|
115
|
-
# Use netstat to find the processes using the port
|
|
116
|
-
result = subprocess.run(
|
|
117
|
-
["netstat", "-ano"],
|
|
118
|
-
capture_output=True,
|
|
119
|
-
text=True,
|
|
120
|
-
check=True,
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
# Parse the output to find processes using the specific port
|
|
124
|
-
lines = result.stdout.strip().split("\n")
|
|
125
|
-
pids_to_kill = set()
|
|
126
|
-
|
|
127
|
-
for line in lines:
|
|
128
|
-
if f":{port}" in line and "LISTENING" in line:
|
|
129
|
-
parts = line.split()
|
|
130
|
-
if len(parts) >= 5:
|
|
131
|
-
pid = parts[-1] # PID is usually the last column
|
|
132
|
-
if pid.isdigit(): # Ensure it's a valid PID
|
|
133
|
-
pids_to_kill.add(pid)
|
|
134
|
-
|
|
135
|
-
if not pids_to_kill:
|
|
136
|
-
return True
|
|
137
|
-
|
|
138
|
-
# Kill the processes
|
|
139
|
-
killed_count = 0
|
|
140
|
-
for pid in pids_to_kill:
|
|
141
|
-
try:
|
|
142
|
-
result = subprocess.run(
|
|
143
|
-
["taskkill", "/PID", pid, "/F"],
|
|
144
|
-
capture_output=True,
|
|
145
|
-
text=True,
|
|
146
|
-
check=False,
|
|
147
|
-
)
|
|
148
|
-
if result.returncode == 0:
|
|
149
|
-
killed_count += 1
|
|
150
|
-
except Exception as e:
|
|
151
|
-
logger.debug(f"Failed to kill process {pid}: {e}")
|
|
152
|
-
continue
|
|
153
|
-
|
|
154
|
-
if not is_port_available(port):
|
|
155
|
-
logger.warning(
|
|
156
|
-
f"Port {port} is still in use after killing processes.",
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
return True
|
|
160
|
-
|
|
161
|
-
except subprocess.CalledProcessError as e:
|
|
162
|
-
logger.error(f"netstat command failed: {e}")
|
|
163
|
-
return False
|
|
164
|
-
except Exception as e:
|
|
165
|
-
logger.error(f"Error in Windows port sweep: {e}")
|
|
166
|
-
return False
|
|
167
|
-
|
|
168
|
-
|
|
169
40
|
class DockerClient(BaseClient):
|
|
170
41
|
def __init__(self, config=None):
|
|
171
42
|
self.config = config
|
|
@@ -193,8 +64,13 @@ class DockerClient(BaseClient):
|
|
|
193
64
|
redis_client,
|
|
194
65
|
set_name=self.config.redis_port_key,
|
|
195
66
|
)
|
|
67
|
+
self.ports_cache = RedisMapping(
|
|
68
|
+
redis_client,
|
|
69
|
+
prefix=self.config.redis_port_key,
|
|
70
|
+
)
|
|
196
71
|
else:
|
|
197
72
|
self.port_set = InMemorySetCollection()
|
|
73
|
+
self.ports_cache = InMemoryMapping()
|
|
198
74
|
|
|
199
75
|
try:
|
|
200
76
|
self.client = docker.from_env()
|
|
@@ -208,40 +84,6 @@ class DockerClient(BaseClient):
|
|
|
208
84
|
"export DOCKER_HOST=unix://$HOME/.colima/docker.sock",
|
|
209
85
|
) from e
|
|
210
86
|
|
|
211
|
-
def _try_pull_from_acr(self, image):
|
|
212
|
-
"""
|
|
213
|
-
Attempt to pull the image from the Alibaba Cloud Container Registry
|
|
214
|
-
(ACR) and retag it.
|
|
215
|
-
"""
|
|
216
|
-
try:
|
|
217
|
-
acr_registry = "agentscope-registry.ap-southeast-1.cr.aliyuncs.com"
|
|
218
|
-
acr_image = f"{acr_registry}/{image}"
|
|
219
|
-
|
|
220
|
-
logger.info(
|
|
221
|
-
f"Attempting to pull from ACR: {acr_image}, it might take "
|
|
222
|
-
f"several minutes.",
|
|
223
|
-
)
|
|
224
|
-
self.client.images.pull(acr_image)
|
|
225
|
-
logger.info(f"Successfully pulled image from ACR: {acr_image}")
|
|
226
|
-
|
|
227
|
-
# Retag the image
|
|
228
|
-
acr_img_obj = self.client.images.get(acr_image)
|
|
229
|
-
acr_img_obj.tag(image)
|
|
230
|
-
logger.debug(f"Successfully tagged image as: {image}")
|
|
231
|
-
|
|
232
|
-
# Optionally remove the original tag to save space
|
|
233
|
-
try:
|
|
234
|
-
self.client.images.remove(acr_image)
|
|
235
|
-
logger.debug(f"Removed original tag: {acr_image}")
|
|
236
|
-
except Exception as e:
|
|
237
|
-
logger.debug(f"Failed to remove original tag: {e}")
|
|
238
|
-
return True
|
|
239
|
-
except Exception as e:
|
|
240
|
-
logger.error(
|
|
241
|
-
f"Failed to pull from ACR: {e}, {traceback.format_exc()}",
|
|
242
|
-
)
|
|
243
|
-
return False
|
|
244
|
-
|
|
245
87
|
def create(
|
|
246
88
|
self,
|
|
247
89
|
image,
|
|
@@ -279,22 +121,11 @@ class DockerClient(BaseClient):
|
|
|
279
121
|
)
|
|
280
122
|
self.client.images.pull(image)
|
|
281
123
|
logger.debug(
|
|
282
|
-
f"Image '{image}' successfully pulled
|
|
283
|
-
f"registry.",
|
|
284
|
-
)
|
|
285
|
-
pull_success = True
|
|
286
|
-
except docker.errors.APIError as e:
|
|
287
|
-
logger.warning(
|
|
288
|
-
f"Failed to pull from default registry: {e}",
|
|
124
|
+
f"Image '{image}' successfully pulled.",
|
|
289
125
|
)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
pull_success = self._try_pull_from_acr(image)
|
|
293
|
-
|
|
294
|
-
if not pull_success:
|
|
126
|
+
except Exception as e:
|
|
295
127
|
logger.error(
|
|
296
|
-
f"Failed to pull image '{image}'
|
|
297
|
-
f"default and ACR",
|
|
128
|
+
f"Failed to pull image '{image}': {str(e)}",
|
|
298
129
|
)
|
|
299
130
|
return None, None, None
|
|
300
131
|
|
|
@@ -314,9 +145,13 @@ class DockerClient(BaseClient):
|
|
|
314
145
|
)
|
|
315
146
|
container.reload()
|
|
316
147
|
_id = container.id
|
|
148
|
+
|
|
149
|
+
self.ports_cache.set(_id, list(port_mapping.values()))
|
|
150
|
+
|
|
317
151
|
return _id, list(port_mapping.values()), "localhost"
|
|
318
152
|
except Exception as e:
|
|
319
|
-
logger.
|
|
153
|
+
logger.warning(f"An error occurred: {e}")
|
|
154
|
+
logger.debug(f"{traceback.format_exc()}")
|
|
320
155
|
return None, None, None
|
|
321
156
|
|
|
322
157
|
def start(self, container_id):
|
|
@@ -326,20 +161,11 @@ class DockerClient(BaseClient):
|
|
|
326
161
|
container_id,
|
|
327
162
|
)
|
|
328
163
|
|
|
329
|
-
# Check whether the ports are occupied by other processes
|
|
330
|
-
port_mapping = container.attrs["NetworkSettings"]["Ports"]
|
|
331
|
-
for _, mappings in port_mapping.items():
|
|
332
|
-
if mappings is not None:
|
|
333
|
-
for mapping in mappings:
|
|
334
|
-
host_port = int(mapping["HostPort"])
|
|
335
|
-
if is_port_available(host_port):
|
|
336
|
-
continue
|
|
337
|
-
sweep_port(host_port["HostPort"])
|
|
338
|
-
|
|
339
164
|
container.start()
|
|
340
165
|
return True
|
|
341
166
|
except Exception as e:
|
|
342
|
-
logger.
|
|
167
|
+
logger.warning(f"An error occurred: {e}")
|
|
168
|
+
logger.debug(f"{traceback.format_exc()}")
|
|
343
169
|
return False
|
|
344
170
|
|
|
345
171
|
def stop(self, container_id, timeout=None):
|
|
@@ -351,7 +177,8 @@ class DockerClient(BaseClient):
|
|
|
351
177
|
container.stop(timeout=timeout)
|
|
352
178
|
return True
|
|
353
179
|
except Exception as e:
|
|
354
|
-
logger.
|
|
180
|
+
logger.warning(f"An error occurred: {e}")
|
|
181
|
+
logger.debug(f"{traceback.format_exc()}")
|
|
355
182
|
return False
|
|
356
183
|
|
|
357
184
|
def remove(self, container_id, force=False):
|
|
@@ -360,20 +187,21 @@ class DockerClient(BaseClient):
|
|
|
360
187
|
container = self.client.containers.get(
|
|
361
188
|
container_id,
|
|
362
189
|
)
|
|
363
|
-
|
|
364
|
-
|
|
190
|
+
ports = self.ports_cache.get(container_id)
|
|
191
|
+
self.ports_cache.delete(container_id)
|
|
192
|
+
|
|
193
|
+
# Remove container
|
|
365
194
|
container.remove(force=force)
|
|
366
195
|
|
|
367
|
-
#
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
host_port = int(mapping["HostPort"])
|
|
372
|
-
self.port_set.remove(host_port)
|
|
196
|
+
# Remove ports
|
|
197
|
+
if ports:
|
|
198
|
+
for host_port in ports:
|
|
199
|
+
self.port_set.remove(host_port)
|
|
373
200
|
|
|
374
201
|
return True
|
|
375
202
|
except Exception as e:
|
|
376
|
-
logger.
|
|
203
|
+
logger.warning(f"An error occurred: {e}")
|
|
204
|
+
logger.debug(f"{traceback.format_exc()}")
|
|
377
205
|
return False
|
|
378
206
|
|
|
379
207
|
def inspect(self, container_id):
|