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.
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.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
  53. {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
  54. {agentscope_runtime-0.1.5b2.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 -184
  63. agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
  64. agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -677
  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.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
  89. {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
  90. {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/top_level.txt +0 -0
@@ -1,268 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # pylint:disable=consider-using-with
3
-
4
- import asyncio
5
- import os
6
- import subprocess
7
- from typing import Optional
8
-
9
- import psutil
10
-
11
-
12
- class ProcessManager:
13
- """Manager for detached process lifecycle."""
14
-
15
- def __init__(self, shutdown_timeout: int = 30):
16
- """Initialize process manager.
17
-
18
- Args:
19
- shutdown_timeout: Timeout in seconds for graceful shutdown
20
- """
21
- self.shutdown_timeout = shutdown_timeout
22
-
23
- async def start_detached_process(
24
- self,
25
- script_path: str,
26
- host: str = "127.0.0.1",
27
- port: int = 8000,
28
- env: Optional[dict] = None,
29
- ) -> int:
30
- """Start a detached process running the given script.
31
-
32
- Args:
33
- script_path: Path to the Python script to run
34
- host: Host to bind to
35
- port: Port to bind to
36
- env: Additional environment variables
37
-
38
- Returns:
39
- Process PID
40
-
41
- Raises:
42
- RuntimeError: If process creation fails
43
- """
44
- try:
45
- # Prepare environment
46
- process_env = os.environ.copy()
47
- if env:
48
- process_env.update(env)
49
-
50
- # Start detached process
51
- process = subprocess.Popen(
52
- [
53
- "python",
54
- script_path,
55
- "--host",
56
- host,
57
- "--port",
58
- str(port),
59
- ],
60
- stdout=subprocess.DEVNULL,
61
- stderr=subprocess.DEVNULL,
62
- stdin=subprocess.DEVNULL,
63
- start_new_session=True, # Create new process group
64
- env=process_env,
65
- cwd=os.path.dirname(script_path),
66
- )
67
-
68
- # Verify process started successfully
69
- await asyncio.sleep(0.1) # Give process time to start
70
- if process.poll() is not None:
71
- raise RuntimeError("Process failed to start")
72
-
73
- return process.pid
74
-
75
- except Exception as e:
76
- raise RuntimeError(f"Failed to start detached process: {e}") from e
77
-
78
- async def stop_process_gracefully(
79
- self,
80
- pid: int,
81
- timeout: Optional[int] = None,
82
- ) -> bool:
83
- """Stop a process gracefully.
84
-
85
- Args:
86
- pid: Process ID to stop
87
- timeout: Timeout for graceful shutdown (uses default if None)
88
-
89
- Returns:
90
- True if process was stopped successfully
91
-
92
- Raises:
93
- RuntimeError: If process termination fails
94
- """
95
- if timeout is None:
96
- timeout = self.shutdown_timeout
97
-
98
- try:
99
- # Check if process exists
100
- if not psutil.pid_exists(pid):
101
- return True # Already terminated
102
-
103
- process = psutil.Process(pid)
104
-
105
- # Send SIGTERM for graceful shutdown
106
- process.terminate()
107
-
108
- # Wait for process to terminate
109
- try:
110
- process.wait(timeout=timeout)
111
- return True
112
- except psutil.TimeoutExpired:
113
- # Force kill if graceful shutdown failed
114
- process.kill()
115
- process.wait(timeout=5) # Wait for kill to complete
116
- return True
117
-
118
- except psutil.NoSuchProcess:
119
- return True # Process already terminated
120
- except psutil.AccessDenied as e:
121
- raise RuntimeError(
122
- f"Access denied when terminating process {pid}: {e}",
123
- ) from e
124
- except Exception as e:
125
- raise RuntimeError(
126
- f"Failed to terminate process {pid}: {e}",
127
- ) from e
128
-
129
- def is_process_running(self, pid: int) -> bool:
130
- """Check if a process is running.
131
-
132
- Args:
133
- pid: Process ID to check
134
-
135
- Returns:
136
- True if process is running
137
- """
138
- try:
139
- return psutil.pid_exists(pid)
140
- except Exception:
141
- return False
142
-
143
- def create_pid_file(self, pid: int, file_path: str):
144
- """Create a PID file.
145
-
146
- Args:
147
- pid: Process ID
148
- file_path: Path to PID file
149
-
150
- Raises:
151
- OSError: If file creation fails
152
- """
153
- try:
154
- # Ensure directory exists
155
- os.makedirs(os.path.dirname(file_path), exist_ok=True)
156
-
157
- with open(file_path, "w", encoding="utf-8") as f:
158
- f.write(str(pid))
159
- except Exception as e:
160
- raise OSError(f"Failed to create PID file {file_path}: {e}") from e
161
-
162
- def read_pid_file(self, file_path: str) -> Optional[int]:
163
- """Read PID from file.
164
-
165
- Args:
166
- file_path: Path to PID file
167
-
168
- Returns:
169
- Process ID or None if file doesn't exist or is invalid
170
- """
171
- try:
172
- if not os.path.exists(file_path):
173
- return None
174
-
175
- with open(file_path, "r", encoding="utf-8") as f:
176
- return int(f.read().strip())
177
- except (ValueError, OSError):
178
- return None
179
-
180
- def cleanup_pid_file(self, file_path: str):
181
- """Remove PID file.
182
-
183
- Args:
184
- file_path: Path to PID file
185
- """
186
- try:
187
- if os.path.exists(file_path):
188
- os.remove(file_path)
189
- except OSError:
190
- pass # Ignore cleanup errors
191
-
192
- async def find_process_by_port(self, port: int) -> Optional[int]:
193
- """Find process listening on a specific port.
194
-
195
- Args:
196
- port: Port number
197
-
198
- Returns:
199
- Process ID or None if not found
200
- """
201
- try:
202
- for conn in psutil.net_connections(kind="inet"):
203
- if conn.laddr.port == port and conn.status == "LISTEN":
204
- if conn.pid:
205
- return conn.pid
206
- return None
207
- except Exception:
208
- return None
209
-
210
- def get_process_info(self, pid: int) -> Optional[dict]:
211
- """Get information about a process.
212
-
213
- Args:
214
- pid: Process ID
215
-
216
- Returns:
217
- Dictionary with process information or None if process not found
218
- """
219
- try:
220
- if not psutil.pid_exists(pid):
221
- return None
222
-
223
- process = psutil.Process(pid)
224
- return {
225
- "pid": pid,
226
- "name": process.name(),
227
- "status": process.status(),
228
- "cpu_percent": process.cpu_percent(),
229
- "memory_percent": process.memory_percent(),
230
- "create_time": process.create_time(),
231
- "cmdline": process.cmdline(),
232
- }
233
- except (psutil.NoSuchProcess, psutil.AccessDenied):
234
- return None
235
-
236
- async def wait_for_port(
237
- self,
238
- host: str,
239
- port: int,
240
- timeout: int = 30,
241
- ) -> bool:
242
- """Wait for a service to become available on a port.
243
-
244
- Args:
245
- host: Host to check
246
- port: Port to check
247
- timeout: Maximum time to wait
248
-
249
- Returns:
250
- True if service becomes available, False if timeout
251
- """
252
- import socket
253
-
254
- end_time = asyncio.get_event_loop().time() + timeout
255
-
256
- while asyncio.get_event_loop().time() < end_time:
257
- try:
258
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
259
- sock.settimeout(1)
260
- result = sock.connect_ex((host, port))
261
- if result == 0:
262
- return True
263
- except Exception:
264
- pass
265
-
266
- await asyncio.sleep(0.5)
267
-
268
- return False
@@ -1,75 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """Service configuration models for dynamic service loading."""
3
-
4
- from enum import Enum
5
- from typing import Dict, Any, Optional
6
-
7
- from pydantic import BaseModel
8
-
9
-
10
- class ServiceType(str, Enum):
11
- """Types of services that can be configured."""
12
-
13
- MEMORY = "memory"
14
- SESSION_HISTORY = "session_history"
15
- SANDBOX = "sandbox"
16
- RAG = "rag"
17
-
18
-
19
- class ServiceProvider(str, Enum):
20
- """Service implementation providers."""
21
-
22
- IN_MEMORY = "in_memory"
23
- REDIS = "redis"
24
- # Extensible for other providers
25
-
26
-
27
- class ServiceConfig(BaseModel):
28
- """Configuration for a single service."""
29
-
30
- provider: ServiceProvider
31
- config: Optional[Dict[str, Any]] = {}
32
-
33
-
34
- class ServicesConfig(BaseModel):
35
- """Configuration for all services."""
36
-
37
- memory: ServiceConfig = ServiceConfig(provider=ServiceProvider.IN_MEMORY)
38
- session_history: ServiceConfig = ServiceConfig(
39
- provider=ServiceProvider.IN_MEMORY,
40
- )
41
- sandbox: Optional[ServiceConfig] = None
42
- rag: Optional[ServiceConfig] = None
43
-
44
-
45
- # Default configuration
46
- DEFAULT_SERVICES_CONFIG = ServicesConfig()
47
-
48
-
49
- def create_redis_services_config(
50
- host: str = "localhost",
51
- port: int = 6379,
52
- memory_db: int = 0,
53
- session_db: int = 1,
54
- ) -> ServicesConfig:
55
- """Create a ServicesConfig with Redis providers.
56
-
57
- Args:
58
- host: Redis host
59
- port: Redis port
60
- memory_db: Redis database for memory service
61
- session_db: Redis database for session history service
62
-
63
- Returns:
64
- ServicesConfig: Configuration with Redis services
65
- """
66
- return ServicesConfig(
67
- memory=ServiceConfig(
68
- provider=ServiceProvider.REDIS,
69
- config={"host": host, "port": port, "db": memory_db},
70
- ),
71
- session_history=ServiceConfig(
72
- provider=ServiceProvider.REDIS,
73
- config={"host": host, "port": port, "db": session_db},
74
- ),
75
- )
@@ -1,220 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # pylint:disable=line-too-long
3
-
4
- from typing import Dict, Type, Any
5
- from .service_config import (
6
- ServiceType,
7
- ServiceProvider,
8
- ServiceConfig,
9
- ServicesConfig,
10
- )
11
-
12
-
13
- class ServiceFactory:
14
- """Factory for creating service instances based on configuration."""
15
-
16
- # Service registry mapping service types and providers to
17
- # implementation classes
18
- _service_registry: Dict[str, Dict[str, Type]] = {}
19
-
20
- @classmethod
21
- def _populate_registry(cls):
22
- """Populate the service registry with available implementations."""
23
- if cls._service_registry:
24
- return # Already populated
25
-
26
- try:
27
- # Import service implementations
28
- from agentscope_runtime.engine.services.memory_service import (
29
- InMemoryMemoryService,
30
- )
31
- from agentscope_runtime.engine.services.session_history_service import ( # noqa E501
32
- InMemorySessionHistoryService,
33
- )
34
-
35
- # Register memory services
36
- cls._service_registry[ServiceType.MEMORY] = {
37
- ServiceProvider.IN_MEMORY: InMemoryMemoryService,
38
- }
39
-
40
- # Register session history services
41
- cls._service_registry[ServiceType.SESSION_HISTORY] = {
42
- ServiceProvider.IN_MEMORY: InMemorySessionHistoryService,
43
- }
44
-
45
- # Try to register Redis services if available
46
-
47
- from agentscope_runtime.engine.services.redis_memory_service import ( # noqa E501
48
- RedisMemoryService,
49
- )
50
- from agentscope_runtime.engine.services.redis_session_history_service import ( # noqa E501
51
- RedisSessionHistoryService,
52
- )
53
-
54
- cls._service_registry[ServiceType.MEMORY][
55
- ServiceProvider.REDIS
56
- ] = RedisMemoryService
57
- cls._service_registry[ServiceType.SESSION_HISTORY][
58
- ServiceProvider.REDIS
59
- ] = RedisSessionHistoryService
60
-
61
- # Try to register other services if available
62
- from agentscope_runtime.engine.services.sandbox_service import (
63
- SandboxService,
64
- )
65
-
66
- # Assuming default implementation
67
- cls._service_registry[ServiceType.SANDBOX] = {
68
- ServiceProvider.IN_MEMORY: SandboxService,
69
- }
70
-
71
- from agentscope_runtime.engine.services.rag_service import (
72
- RAGService,
73
- )
74
-
75
- # Assuming default implementation
76
- cls._service_registry[ServiceType.RAG] = {
77
- ServiceProvider.IN_MEMORY: RAGService,
78
- }
79
-
80
- except ImportError as e:
81
- raise RuntimeError(
82
- f"Failed to import required service classes: {e}",
83
- ) from e
84
-
85
- @classmethod
86
- def create_service(
87
- cls,
88
- service_type: ServiceType,
89
- config: ServiceConfig,
90
- ) -> Any:
91
- """Create a service instance based on type and configuration.
92
-
93
- Args:
94
- service_type: Type of service to create
95
- config: Configuration for the service
96
-
97
- Returns:
98
- Service instance
99
-
100
- Raises:
101
- ValueError: If service type or provider is unknown
102
- RuntimeError: If service creation fails
103
- """
104
- cls._populate_registry()
105
-
106
- if service_type not in cls._service_registry:
107
- raise ValueError(f"Unknown service type: {service_type}")
108
-
109
- providers = cls._service_registry[service_type]
110
- if config.provider not in providers:
111
- available_providers = list(providers.keys())
112
- raise ValueError(
113
- f"Unknown provider '{config.provider}' for service '"
114
- f"{service_type}'. Available providers: {available_providers}",
115
- )
116
-
117
- service_class = providers[config.provider]
118
-
119
- try:
120
- # Create service instance with configuration parameters
121
- return service_class(**config.config)
122
- except Exception as e:
123
- raise RuntimeError(
124
- f"Failed to create {service_type} service with provider "
125
- f"'{config.provider}': {e}",
126
- ) from e
127
-
128
- @classmethod
129
- def register_service(
130
- cls,
131
- service_type: ServiceType,
132
- provider: ServiceProvider,
133
- service_class: Type,
134
- ):
135
- """Register a new service implementation.
136
-
137
- Args:
138
- service_type: Type of service
139
- provider: Service provider
140
- service_class: Implementation class
141
- """
142
- cls._populate_registry()
143
-
144
- if service_type not in cls._service_registry:
145
- cls._service_registry[service_type] = {}
146
-
147
- cls._service_registry[service_type][provider] = service_class
148
-
149
- @classmethod
150
- def create_services_from_config(
151
- cls,
152
- config: ServicesConfig,
153
- ) -> Dict[str, Any]:
154
- """Create all services from a services configuration.
155
-
156
- Args:
157
- config: Services configuration
158
-
159
- Returns:
160
- Dict mapping service names to service instances
161
-
162
- Raises:
163
- RuntimeError: If any required service creation fails
164
- """
165
- services = {}
166
-
167
- # Create required services
168
- try:
169
- services["memory"] = cls.create_service(
170
- ServiceType.MEMORY,
171
- config.memory,
172
- )
173
- services["session_history"] = cls.create_service(
174
- ServiceType.SESSION_HISTORY,
175
- config.session_history,
176
- )
177
- except Exception as e:
178
- raise RuntimeError(
179
- f"Failed to create required services: {e}",
180
- ) from e
181
-
182
- # Create optional services
183
- if config.sandbox:
184
- try:
185
- services["sandbox"] = cls.create_service(
186
- ServiceType.SANDBOX,
187
- config.sandbox,
188
- )
189
- except Exception as e:
190
- # Log warning but don't fail
191
- print(f"Warning: Failed to create sandbox service: {e}")
192
-
193
- if config.rag:
194
- try:
195
- services["rag"] = cls.create_service(
196
- ServiceType.RAG,
197
- config.rag,
198
- )
199
- except Exception as e:
200
- # Log warning but don't fail
201
- print(f"Warning: Failed to create RAG service: {e}")
202
-
203
- return services
204
-
205
- @classmethod
206
- def get_available_providers(cls, service_type: ServiceType) -> list:
207
- """Get list of available providers for a service type.
208
-
209
- Args:
210
- service_type: Type of service
211
-
212
- Returns:
213
- List of available provider names
214
- """
215
- cls._populate_registry()
216
-
217
- if service_type not in cls._service_registry:
218
- return []
219
-
220
- return list(cls._service_registry[service_type].keys())