agentscope-runtime 0.1.5b1__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.
Files changed (90) hide show
  1. agentscope_runtime/engine/agents/agentscope_agent.py +447 -0
  2. agentscope_runtime/engine/agents/agno_agent.py +19 -18
  3. agentscope_runtime/engine/agents/autogen_agent.py +13 -8
  4. agentscope_runtime/engine/agents/utils.py +53 -0
  5. agentscope_runtime/engine/deployers/__init__.py +0 -13
  6. agentscope_runtime/engine/deployers/local_deployer.py +501 -356
  7. agentscope_runtime/engine/helpers/helper.py +60 -41
  8. agentscope_runtime/engine/runner.py +11 -36
  9. agentscope_runtime/engine/schemas/agent_schemas.py +2 -70
  10. agentscope_runtime/engine/services/sandbox_service.py +62 -70
  11. agentscope_runtime/engine/services/tablestore_memory_service.py +304 -0
  12. agentscope_runtime/engine/services/tablestore_rag_service.py +143 -0
  13. agentscope_runtime/engine/services/tablestore_session_history_service.py +293 -0
  14. agentscope_runtime/engine/services/utils/tablestore_service_utils.py +352 -0
  15. agentscope_runtime/sandbox/__init__.py +2 -0
  16. agentscope_runtime/sandbox/box/base/__init__.py +4 -0
  17. agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -3
  18. agentscope_runtime/sandbox/box/browser/__init__.py +4 -0
  19. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +8 -13
  20. agentscope_runtime/sandbox/box/dummy/__init__.py +4 -0
  21. agentscope_runtime/sandbox/box/filesystem/__init__.py +4 -0
  22. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +8 -6
  23. agentscope_runtime/sandbox/box/gui/__init__.py +4 -0
  24. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +80 -0
  25. agentscope_runtime/sandbox/box/sandbox.py +5 -2
  26. agentscope_runtime/sandbox/box/shared/routers/generic.py +20 -1
  27. agentscope_runtime/sandbox/box/training_box/__init__.py +4 -0
  28. agentscope_runtime/sandbox/box/training_box/training_box.py +10 -15
  29. agentscope_runtime/sandbox/build.py +143 -58
  30. agentscope_runtime/sandbox/client/http_client.py +43 -49
  31. agentscope_runtime/sandbox/client/training_client.py +0 -1
  32. agentscope_runtime/sandbox/constant.py +24 -1
  33. agentscope_runtime/sandbox/custom/custom_sandbox.py +5 -5
  34. agentscope_runtime/sandbox/custom/example.py +2 -2
  35. agentscope_runtime/sandbox/enums.py +1 -0
  36. agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +11 -6
  37. agentscope_runtime/sandbox/manager/collections/redis_mapping.py +25 -9
  38. agentscope_runtime/sandbox/manager/container_clients/__init__.py +0 -10
  39. agentscope_runtime/sandbox/manager/container_clients/agentrun_client.py +1098 -0
  40. agentscope_runtime/sandbox/manager/container_clients/docker_client.py +33 -205
  41. agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +8 -555
  42. agentscope_runtime/sandbox/manager/sandbox_manager.py +187 -88
  43. agentscope_runtime/sandbox/manager/server/app.py +82 -14
  44. agentscope_runtime/sandbox/manager/server/config.py +50 -3
  45. agentscope_runtime/sandbox/model/container.py +6 -23
  46. agentscope_runtime/sandbox/model/manager_config.py +93 -5
  47. agentscope_runtime/sandbox/tools/gui/__init__.py +7 -0
  48. agentscope_runtime/sandbox/tools/gui/tool.py +77 -0
  49. agentscope_runtime/sandbox/tools/mcp_tool.py +6 -2
  50. agentscope_runtime/sandbox/utils.py +124 -0
  51. agentscope_runtime/version.py +1 -1
  52. {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
  53. {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
  54. {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/entry_points.txt +0 -1
  55. agentscope_runtime/engine/agents/agentscope_agent/__init__.py +0 -6
  56. agentscope_runtime/engine/agents/agentscope_agent/agent.py +0 -401
  57. agentscope_runtime/engine/agents/agentscope_agent/hooks.py +0 -169
  58. agentscope_runtime/engine/agents/llm_agent.py +0 -51
  59. agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +0 -2886
  60. agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +0 -51
  61. agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +0 -314
  62. agentscope_runtime/engine/deployers/cli_fc_deploy.py +0 -143
  63. agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
  64. agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -626
  65. agentscope_runtime/engine/deployers/utils/deployment_modes.py +0 -14
  66. agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +0 -8
  67. agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +0 -429
  68. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +0 -240
  69. agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +0 -297
  70. agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -932
  71. agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -9
  72. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +0 -504
  73. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +0 -157
  74. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +0 -268
  75. agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
  76. agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
  77. agentscope_runtime/engine/deployers/utils/wheel_packager.py +0 -389
  78. agentscope_runtime/engine/helpers/agent_api_builder.py +0 -651
  79. agentscope_runtime/engine/llms/__init__.py +0 -3
  80. agentscope_runtime/engine/llms/base_llm.py +0 -60
  81. agentscope_runtime/engine/llms/qwen_llm.py +0 -47
  82. agentscope_runtime/engine/schemas/embedding.py +0 -37
  83. agentscope_runtime/engine/schemas/modelstudio_llm.py +0 -310
  84. agentscope_runtime/engine/schemas/oai_llm.py +0 -538
  85. agentscope_runtime/engine/schemas/realtime.py +0 -254
  86. /agentscope_runtime/engine/{deployers/adapter/responses → services/utils}/__init__.py +0 -0
  87. /agentscope_runtime/{engine/deployers/utils → sandbox/box/gui/box}/__init__.py +0 -0
  88. {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
  89. {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
  90. {agentscope_runtime-0.1.5b1.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 RedisSetCollection, InMemorySetCollection
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 from default "
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
- logger.warning("Trying to pull from ACR fallback...")
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}' from both "
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.error(f"An error occurred: {e}, {traceback.format_exc()}")
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.error(f"An error occurred: {e}, {traceback.format_exc()}")
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.error(f"An error occurred: {e}, {traceback.format_exc()}")
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
- # Remove ports
364
- port_mapping = container.attrs["NetworkSettings"]["Ports"]
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
- # Iterate over each port and its mappings
368
- for _, mappings in port_mapping.items():
369
- if mappings is not None:
370
- for mapping in mappings:
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.error(f"An error occurred: {e}, {traceback.format_exc()}")
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):