11"""Base sandbox manager interface."""
22
3+ import asyncio
34from abc import ABC , abstractmethod
4- from typing import TYPE_CHECKING , Any , Dict , List , Optional , Union
5-
6- from ..model import SandboxConfig , SandboxInfo , SandboxStatus , SandboxType , ToolResult
5+ from collections import deque
6+ from typing import TYPE_CHECKING , Any , Deque , Dict , List , Optional , Union
7+
8+ from ..model import (
9+ SandboxConfig ,
10+ SandboxInfo ,
11+ SandboxManagerConfig ,
12+ SandboxManagerType ,
13+ SandboxStatus ,
14+ SandboxType ,
15+ ToolResult ,
16+ )
717
818if TYPE_CHECKING :
919 from ..boxes import Sandbox
1222class SandboxManager (ABC ):
1323 """Abstract base class for sandbox managers."""
1424
15- def __init__ (self ):
16- """Initialize the sandbox manager."""
25+ def __init__ (self , config : Optional [SandboxManagerConfig ] = None , ** kwargs ):
26+ """Initialize the sandbox manager.
27+
28+ Args:
29+ config: Sandbox manager configuration
30+ """
31+ self .config = config or SandboxManagerConfig ()
1732 self ._running = False
1833 self ._sandboxes : Dict [str , 'Sandbox' ] = {}
34+ self ._sandbox_pool : Deque [str ] = deque ()
35+ self ._pool_lock = asyncio .Lock ()
36+ self ._pool_initialized = False
1937
2038 @abstractmethod
2139 async def start (self ) -> None :
@@ -144,6 +162,48 @@ async def cleanup_all_sandboxes(self) -> None:
144162 """Clean up all sandboxes."""
145163 pass
146164
165+ @abstractmethod
166+ async def initialize_pool (
167+ self ,
168+ pool_size : Optional [int ] = None ,
169+ sandbox_type : Optional [SandboxType ] = None ,
170+ config : Optional [Union [SandboxConfig , Dict ]] = None
171+ ) -> List [str ]:
172+ """Initialize sandbox pool.
173+
174+ Args:
175+ pool_size: Number of sandboxes in pool (uses config if not provided)
176+ sandbox_type: Type of sandbox to create
177+ config: Sandbox configuration (uses config.sandbox_config if not provided)
178+
179+ Returns:
180+ List of created sandbox IDs
181+ """
182+ pass
183+
184+ @abstractmethod
185+ async def execute_tool_in_pool (
186+ self , tool_name : str , parameters : Dict [str , Any ], timeout : Optional [float ] = None
187+ ) -> ToolResult :
188+ """Execute tool using an available sandbox from the pool.
189+
190+ Uses FIFO queue to get an idle sandbox, marks it as busy during execution,
191+ then returns it to the pool as idle.
192+
193+ Args:
194+ tool_name: Tool name to execute
195+ parameters: Tool parameters
196+ timeout: Optional timeout for waiting for available sandbox
197+
198+ Returns:
199+ Tool execution result
200+
201+ Raises:
202+ ValueError: If pool is empty or no sandbox available
203+ TimeoutError: If timeout waiting for available sandbox
204+ """
205+ pass
206+
147207 # Context manager support
148208 async def __aenter__ (self ):
149209 """Async context manager entry."""
@@ -153,3 +213,81 @@ async def __aenter__(self):
153213 async def __aexit__ (self , exc_type , exc_val , exc_tb ):
154214 """Async context manager exit."""
155215 await self .stop ()
216+
217+
218+ class SandboxManagerFactory :
219+ """Factory for creating sandbox managers."""
220+
221+ _registry : Dict [SandboxManagerType , type ] = {}
222+
223+ @classmethod
224+ def register (cls , manager_type : SandboxManagerType , manager_class : type ) -> None :
225+ """Register a sandbox manager class.
226+
227+ Args:
228+ manager_type: Manager type to register
229+ manager_class: Manager class to register
230+ """
231+ cls ._registry [manager_type ] = manager_class
232+
233+ @classmethod
234+ def create_manager (
235+ cls ,
236+ manager_type : Optional [SandboxManagerType ] = None ,
237+ config : Optional [SandboxManagerConfig ] = None ,
238+ ** kwargs
239+ ) -> SandboxManager :
240+ """Create a sandbox manager instance.
241+
242+ Args:
243+ manager_type: Type of manager to create
244+ config: Manager configuration
245+ **kwargs: Additional manager-specific parameters
246+
247+ Returns:
248+ Sandbox manager instance
249+
250+ Raises:
251+ ValueError: If manager type is not registered
252+ """
253+ if not manager_type :
254+ api_url = config .base_url if config else kwargs .get ('base_url' )
255+ if api_url :
256+ manager_type = SandboxManagerType .HTTP
257+ else :
258+ manager_type = SandboxManagerType .LOCAL
259+
260+ if manager_type not in cls ._registry :
261+ raise ValueError (
262+ f"Sandbox manager type '{ manager_type } ' not registered. "
263+ f'Available types: { list (cls ._registry .keys ())} '
264+ )
265+
266+ manager_class = cls ._registry [manager_type ]
267+ return manager_class (config = config , ** kwargs )
268+
269+ @classmethod
270+ def get_registered_types (cls ) -> List [SandboxManagerType ]:
271+ """Get list of registered manager types.
272+
273+ Returns:
274+ List of registered manager types
275+ """
276+ return list (cls ._registry .keys ())
277+
278+
279+ def register_manager (manager_type : SandboxManagerType ):
280+ """Decorator to register a sandbox manager class.
281+
282+ Args:
283+ manager_type: Manager type to register
284+
285+ Returns:
286+ Decorator function
287+ """
288+
289+ def decorator (manager_class : type ) -> type :
290+ SandboxManagerFactory .register (manager_type , manager_class )
291+ return manager_class
292+
293+ return decorator
0 commit comments