Duibonduil commited on
Commit
6c4f72f
·
verified ·
1 Parent(s): 5b52232

Upload 3 files

Browse files
aworld/sandbox/implementations/kubernetes_sandbox.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import asyncio
3
+ import uuid
4
+ from typing import Dict, List, Any, Optional
5
+
6
+ from aworld.sandbox.common import BaseSandbox
7
+ from aworld.sandbox.api.kubernetes.sandbox_api import KubernetesSandboxApi
8
+ from aworld.sandbox.models import SandboxStatus, SandboxEnvType, SandboxInfo
9
+ from aworld.sandbox.run.mcp_servers import McpServers
10
+
11
+
12
+ class KubernetesSandbox(BaseSandbox, KubernetesSandboxApi):
13
+ """
14
+ Kubernetes sandbox implementation that runs in a Kubernetes cluster.
15
+ """
16
+
17
+ def __init__(
18
+ self,
19
+ sandbox_id: Optional[str] = None,
20
+ metadata: Optional[Dict[str, str]] = None,
21
+ timeout: Optional[int] = None,
22
+ mcp_servers: Optional[List[str]] = None,
23
+ mcp_config: Optional[Any] = None,
24
+ **kwargs
25
+ ):
26
+ """
27
+ Initialize a new KubernetesSandbox instance.
28
+
29
+ Args:
30
+ sandbox_id: Unique identifier for the sandbox. If None, one will be generated.
31
+ metadata: Additional metadata for the sandbox.
32
+ timeout: Timeout for sandbox operations.
33
+ mcp_servers: List of MCP servers to use.
34
+ mcp_config: Configuration for MCP servers.
35
+ **kwargs: Additional parameters for specific sandbox types.
36
+ """
37
+ super().__init__(
38
+ sandbox_id=sandbox_id,
39
+ env_type=SandboxEnvType.K8S,
40
+ metadata=metadata,
41
+ timeout=timeout,
42
+ mcp_servers=mcp_servers,
43
+ mcp_config=mcp_config
44
+ )
45
+
46
+ if sandbox_id:
47
+ if not self._metadata:
48
+ return self
49
+ else:
50
+ raise ValueError("sandbox_id is not exist")
51
+
52
+ # Initialize properties
53
+ self._status = SandboxStatus.INIT
54
+ self._timeout = timeout or self.default_sandbox_timeout
55
+ self._metadata = metadata or {}
56
+ self._env_type = SandboxEnvType.K8S
57
+ self._mcp_servers = mcp_servers
58
+ self._mcp_config = mcp_config
59
+
60
+ # Ensure sandbox_id has a value in all cases
61
+ self._sandbox_id = sandbox_id or str(uuid.uuid4())
62
+
63
+ # If no sandbox_id provided, create a new sandbox
64
+ if not sandbox_id:
65
+ response = self._create_sandbox(
66
+ env_type=self._env_type,
67
+ env_config=None,
68
+ mcp_servers=mcp_servers,
69
+ mcp_config=mcp_config,
70
+ )
71
+
72
+ if not response:
73
+ self._status = SandboxStatus.ERROR
74
+ # If creation fails, keep the generated UUID as the ID
75
+ logging.warning(f"Failed to create K8s sandbox, using generated ID: {self._sandbox_id}")
76
+ else:
77
+ self._sandbox_id = response.sandbox_id
78
+ self._status = SandboxStatus.RUNNING
79
+ self._metadata = {
80
+ "pod_name": getattr(response, 'pod_name', None),
81
+ "service_name": getattr(response, 'service_name', None),
82
+ "status": getattr(response, 'status', None),
83
+ "cluster_ip": getattr(response, 'cluster_ip', None),
84
+ "host": getattr(response, 'host', None),
85
+ "mcp_config": getattr(response, 'mcp_config', None),
86
+ "env_type": getattr(response, 'env_type', None),
87
+ }
88
+ self._mcp_config = getattr(response, 'mcp_config', None)
89
+
90
+ # Initialize McpServers
91
+ self._mcpservers = McpServers(
92
+ mcp_servers,
93
+ self._mcp_config,
94
+ sandbox=self
95
+ )
96
+
97
+ async def remove(self) -> None:
98
+ """
99
+ Remove sandbox.
100
+ """
101
+ await self._remove_sandbox(
102
+ sandbox_id=self.sandbox_id,
103
+ metadata=self._metadata,
104
+ env_type=self._env_type
105
+ )
106
+
107
+ async def cleanup(self) -> None:
108
+ """
109
+ Clean up Sandbox resources, including MCP server connections
110
+ """
111
+ try:
112
+ if hasattr(self, '_mcpservers') and self._mcpservers:
113
+ await self._mcpservers.cleanup()
114
+ logging.info(f"Cleaned up MCP servers for sandbox {self.sandbox_id}")
115
+ except Exception as e:
116
+ logging.warning(f"Failed to cleanup MCP servers: {e}")
117
+
118
+ # Call the original remove method
119
+ try:
120
+ await self.remove()
121
+ except Exception as e:
122
+ logging.warning(f"Failed to remove sandbox: {e}")
123
+
124
+ def __del__(self):
125
+ """
126
+ Ensure resources are cleaned up when the object is garbage collected
127
+ """
128
+ try:
129
+ # Handle the case where an event loop already exists
130
+ try:
131
+ loop = asyncio.get_running_loop()
132
+ logging.warning("Cannot clean up sandbox in __del__ when event loop is already running")
133
+ return
134
+ except RuntimeError:
135
+ # No running event loop, create a new one
136
+ loop = asyncio.new_event_loop()
137
+ asyncio.set_event_loop(loop)
138
+ loop.run_until_complete(self.cleanup())
139
+ loop.close()
140
+ except Exception as e:
141
+ logging.warning(f"Failed to cleanup sandbox resources during garbage collection: {e}")
aworld/sandbox/implementations/local_sandbox.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import asyncio
3
+ import uuid
4
+ from typing import Dict, List, Any, Optional
5
+
6
+ from aworld.sandbox.api.local.sandbox_api import LocalSandboxApi
7
+ from aworld.sandbox.models import SandboxStatus, SandboxEnvType, SandboxInfo
8
+ from aworld.sandbox.run.mcp_servers import McpServers
9
+ from aworld.sandbox.common import BaseSandbox
10
+
11
+
12
+ class LocalSandbox(BaseSandbox, LocalSandboxApi):
13
+ """
14
+ Local sandbox implementation that runs in the local environment.
15
+ This sandbox runs processes and MCP servers directly on the local machine.
16
+ """
17
+
18
+ def __init__(
19
+ self,
20
+ sandbox_id: Optional[str] = None,
21
+ metadata: Optional[Dict[str, str]] = None,
22
+ timeout: Optional[int] = None,
23
+ mcp_servers: Optional[List[str]] = None,
24
+ mcp_config: Optional[Any] = None,
25
+ **kwargs
26
+ ):
27
+ """
28
+ Initialize a new LocalSandbox instance.
29
+
30
+ Args:
31
+ sandbox_id: Unique identifier for the sandbox. If None, one will be generated.
32
+ metadata: Additional metadata for the sandbox.
33
+ timeout: Timeout for sandbox operations.
34
+ mcp_servers: List of MCP servers to use.
35
+ mcp_config: Configuration for MCP servers.
36
+ **kwargs: Additional parameters for specific sandbox types.
37
+ """
38
+ super().__init__(
39
+ sandbox_id=sandbox_id,
40
+ env_type=SandboxEnvType.LOCAL,
41
+ metadata=metadata,
42
+ timeout=timeout,
43
+ mcp_servers=mcp_servers,
44
+ mcp_config=mcp_config
45
+ )
46
+
47
+ if sandbox_id:
48
+ if not self._metadata:
49
+ return self
50
+ else:
51
+ raise ValueError("sandbox_id is not exist")
52
+
53
+ # Initialize properties
54
+ self._status = SandboxStatus.INIT
55
+ self._timeout = timeout or self.default_sandbox_timeout
56
+ self._metadata = metadata or {}
57
+ self._env_type = SandboxEnvType.LOCAL
58
+ self._mcp_servers = mcp_servers
59
+ self._mcp_config = mcp_config
60
+
61
+ # Ensure sandbox_id has a value in all cases
62
+ self._sandbox_id = sandbox_id or str(uuid.uuid4())
63
+
64
+ # If no sandbox_id provided, create a new sandbox
65
+ if not sandbox_id:
66
+ response = self._create_sandbox(
67
+ env_type=self._env_type,
68
+ env_config=None,
69
+ mcp_servers=mcp_servers,
70
+ mcp_config=mcp_config,
71
+ )
72
+
73
+ if not response:
74
+ self._status = SandboxStatus.ERROR
75
+ # If creation fails, keep the generated UUID as the ID
76
+ logging.warning(f"Failed to create sandbox, using generated ID: {self._sandbox_id}")
77
+ else:
78
+ self._sandbox_id = response.sandbox_id
79
+ self._status = SandboxStatus.RUNNING
80
+ self._metadata = {
81
+ "status": getattr(response, 'status', None),
82
+ "mcp_config": getattr(response, 'mcp_config', None),
83
+ "env_type": getattr(response, 'env_type', None),
84
+ }
85
+ self._mcp_config = getattr(response, 'mcp_config', None)
86
+
87
+ # Initialize McpServers with a reference to this sandbox instance
88
+ self._mcpservers = McpServers(
89
+ mcp_servers,
90
+ self._mcp_config,
91
+ sandbox=self
92
+ )
93
+
94
+ async def remove(self) -> None:
95
+ """
96
+ Remove sandbox.
97
+ """
98
+ await self._remove_sandbox(
99
+ sandbox_id=self.sandbox_id,
100
+ metadata=self._metadata,
101
+ env_type=self._env_type
102
+ )
103
+
104
+ async def cleanup(self) -> None:
105
+ """
106
+ Clean up Sandbox resources, including MCP server connections
107
+ """
108
+ try:
109
+ if hasattr(self, '_mcpservers') and self._mcpservers:
110
+ await self._mcpservers.cleanup()
111
+ logging.info(f"Cleaned up MCP servers for sandbox {self.sandbox_id}")
112
+ except Exception as e:
113
+ logging.warning(f"Failed to cleanup MCP servers: {e}")
114
+
115
+ # Call the original remove method
116
+ try:
117
+ await self.remove()
118
+ except Exception as e:
119
+ logging.warning(f"Failed to remove sandbox: {e}")
120
+
121
+ def __del__(self):
122
+ """
123
+ Ensure resources are cleaned up when the object is garbage collected
124
+ """
125
+ try:
126
+ # Handle the case where an event loop already exists
127
+ try:
128
+ loop = asyncio.get_running_loop()
129
+ logging.warning("Cannot clean up sandbox in __del__ when event loop is already running")
130
+ return
131
+ except RuntimeError:
132
+ # No running event loop, create a new one
133
+ loop = asyncio.new_event_loop()
134
+ asyncio.set_event_loop(loop)
135
+ loop.run_until_complete(self.cleanup())
136
+ loop.close()
137
+ except Exception as e:
138
+ logging.warning(f"Failed to cleanup sandbox resources during garbage collection: {e}")
aworld/sandbox/implementations/super_sandbox.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import asyncio
3
+ import uuid
4
+ from typing import Dict, List, Any, Optional
5
+
6
+ from aworld.sandbox.common import BaseSandbox
7
+ from aworld.sandbox.api.super.sandbox_api import SuperSandboxApi
8
+ from aworld.sandbox.models import SandboxStatus, SandboxEnvType, SandboxInfo
9
+ from aworld.sandbox.run.mcp_servers import McpServers
10
+
11
+
12
+ class SuperSandbox(BaseSandbox, SuperSandboxApi):
13
+ """
14
+ Supercomputer sandbox implementation that runs on a supercomputer environment.
15
+ """
16
+
17
+ def __init__(
18
+ self,
19
+ sandbox_id: Optional[str] = None,
20
+ metadata: Optional[Dict[str, str]] = None,
21
+ timeout: Optional[int] = None,
22
+ mcp_servers: Optional[List[str]] = None,
23
+ mcp_config: Optional[Any] = None,
24
+ **kwargs
25
+ ):
26
+ """
27
+ Initialize a new SuperSandbox instance.
28
+
29
+ Args:
30
+ sandbox_id: Unique identifier for the sandbox. If None, one will be generated.
31
+ metadata: Additional metadata for the sandbox.
32
+ timeout: Timeout for sandbox operations.
33
+ mcp_servers: List of MCP servers to use.
34
+ mcp_config: Configuration for MCP servers.
35
+ **kwargs: Additional parameters for specific sandbox types.
36
+ """
37
+ super().__init__(
38
+ sandbox_id=sandbox_id,
39
+ env_type=SandboxEnvType.SUPERCOMPUTER,
40
+ metadata=metadata,
41
+ timeout=timeout,
42
+ mcp_servers=mcp_servers,
43
+ mcp_config=mcp_config
44
+ )
45
+
46
+ if sandbox_id:
47
+ if not self._metadata:
48
+ return self
49
+ else:
50
+ raise ValueError("sandbox_id is not exist")
51
+
52
+ # Initialize properties
53
+ self._status = SandboxStatus.INIT
54
+ self._timeout = timeout or self.default_sandbox_timeout
55
+ self._metadata = metadata or {}
56
+ self._env_type = SandboxEnvType.SUPERCOMPUTER
57
+ self._mcp_servers = mcp_servers
58
+ self._mcp_config = mcp_config
59
+
60
+ # Ensure sandbox_id has a value in all cases
61
+ self._sandbox_id = sandbox_id or str(uuid.uuid4())
62
+
63
+ # If no sandbox_id provided, create a new sandbox
64
+ if not sandbox_id:
65
+ response = self._create_sandbox(
66
+ env_type=self._env_type,
67
+ env_config=None,
68
+ mcp_servers=mcp_servers,
69
+ mcp_config=mcp_config,
70
+ )
71
+
72
+ if not response:
73
+ self._status = SandboxStatus.ERROR
74
+ # If creation fails, keep the generated UUID as the ID
75
+ logging.warning(f"Failed to create super sandbox, using generated ID: {self._sandbox_id}")
76
+ else:
77
+ self._sandbox_id = response.sandbox_id
78
+ self._status = SandboxStatus.RUNNING
79
+ self._metadata = {
80
+ "status": getattr(response, 'status', None),
81
+ "host": getattr(response, 'host', None),
82
+ "mcp_config": getattr(response, 'mcp_config', None),
83
+ "env_type": getattr(response, 'env_type', None),
84
+ }
85
+ self._mcp_config = getattr(response, 'mcp_config', None)
86
+
87
+ # Initialize McpServers
88
+ self._mcpservers = McpServers(
89
+ mcp_servers,
90
+ self._mcp_config,
91
+ sandbox=self
92
+ )
93
+
94
+ async def remove(self) -> None:
95
+ """
96
+ Remove sandbox.
97
+ """
98
+ await self._remove_sandbox(
99
+ sandbox_id=self.sandbox_id,
100
+ metadata=self._metadata,
101
+ env_type=self._env_type
102
+ )
103
+
104
+ async def cleanup(self) -> None:
105
+ """
106
+ Clean up Sandbox resources, including MCP server connections
107
+ """
108
+ try:
109
+ if hasattr(self, '_mcpservers') and self._mcpservers:
110
+ await self._mcpservers.cleanup()
111
+ logging.info(f"Cleaned up MCP servers for sandbox {self.sandbox_id}")
112
+ except Exception as e:
113
+ logging.warning(f"Failed to cleanup MCP servers: {e}")
114
+
115
+ # Call the original remove method
116
+ try:
117
+ await self.remove()
118
+ except Exception as e:
119
+ logging.warning(f"Failed to remove sandbox: {e}")
120
+
121
+ def __del__(self):
122
+ """
123
+ Ensure resources are cleaned up when the object is garbage collected
124
+ """
125
+ try:
126
+ # Handle the case where an event loop already exists
127
+ try:
128
+ loop = asyncio.get_running_loop()
129
+ logging.warning("Cannot clean up sandbox in __del__ when event loop is already running")
130
+ return
131
+ except RuntimeError:
132
+ # No running event loop, create a new one
133
+ loop = asyncio.new_event_loop()
134
+ asyncio.set_event_loop(loop)
135
+ loop.run_until_complete(self.cleanup())
136
+ loop.close()
137
+ except Exception as e:
138
+ logging.warning(f"Failed to cleanup sandbox resources during garbage collection: {e}")