Prerequisites
Background / Description
Problem
Two production requirements that the OpenSandbox workspace classes currently don't support:
1. Cross-network access (use_server_proxy)
When the client and the OpenSandbox server run on different machines, the SDK defaults to direct connections to sandbox containers on their dynamically allocated ports (40000–60000). These ports are unreachable — only the API server port (16399) is exposed. The SDK's ConnectionConfig already has use_server_proxy: bool to route all execd traffic through the API server, but OpenSandboxWorkspace._connection_config() doesn't expose it.
2. Persistent storage (volumes)
Sandboxes have a timeout_seconds lifetime. When a sandbox expires, all files inside /workspace are lost. The SDK's Sandbox.create() accepts volumes: list[Volume] (host bind-mount, PVC, OSSFS), but OpenSandboxWorkspace._create_sandbox() doesn't pass it.
Proposed change
Add two optional keyword parameters to both OpenSandboxWorkspace.__init__ and OpenSandboxWorkspaceManager.__init__:
| Parameter |
Type |
Default |
SDK field |
use_server_proxy |
bool |
False |
ConnectionConfig.use_server_proxy |
volumes |
list[Volume] | None |
None |
Sandbox.create(volumes=...) |
OpenSandboxWorkspace._connection_config() — add use_server_proxy:
def _connection_config(self) -> ConnectionConfig:
kwargs: dict = {"protocol": self.protocol}
if self.api_key:
kwargs["api_key"] = self.api_key
if self.domain:
kwargs["domain"] = self.domain
if self.request_timeout_seconds is not None:
kwargs["request_timeout"] = timedelta(seconds=self.request_timeout_seconds)
kwargs["use_server_proxy"] = self.use_server_proxy # <-- new
return ConnectionConfig(**kwargs)
OpenSandboxWorkspace._create_sandbox() — add volumes:
async def _create_sandbox(self) -> Sandbox:
kwargs = { ... }
# ... existing env / resource / entrypoint / network_policy handling ...
if self.volumes:
kwargs["volumes"] = self.volumes # <-- new
return await Sandbox.create(**kwargs)
Environment
- agentscope 2.0.5
- OpenSandbox server 0.2.0
Error Messages
2026/07/29 13:59:22 | MainProcess[33364]:MainThread[26284] | [_trace.py:87 - _trace]-[DEBUG] - connect_tcp.started host='172.xx.x.xx' port=58525 local_address=None timeout=600.0 socket_options=None
2026/07/29 13:59:24 | MainProcess[33364]:MainThread[26284] | [_trace.py:87 - _trace]-[DEBUG] - connect_tcp.failed exception=ConnectError(OSError('All connection attempts failed'))
2026/07/29 13:59:24 | MainProcess[33364]:MainThread[26284] | [filesystem_adapter.py:271 - filesystem_adapter]-[ERROR] - Failed to write 1 files
Steps to Reproduce
Setup: OpenSandbox server runs on 172.xx.x.xx:16399. Client runs on a different machine (separate network segment).
Server config (sandbox.toml):
[server]
host = "0.0.0.0"
port = 16399
api_key = "sk-example"
[runtime]
type = "docker"
[ingress]
mode = "direct"
Client code:
import asyncio
from agentscope.app.workspace_manager import OpenSandboxWorkspaceManager
async def main():
manager = OpenSandboxWorkspaceManager(
api_key="sk-example",
domain="172.xx.x.xx:16399",
)
ws = await manager.get_workspace(
user_id="user-1",
agent_id="agent-1",
session_id="session-1",
)
print(f"sandbox_id={ws.sandbox_id}")
# The next tool call (e.g. Bash) triggers filesystem write via execd
# → httpx.ConnectError to port 58525
asyncio.run(main())
Output:
INFO | Initialize workspace (id=...) from OpenSandboxWorkspace ...
DEBUG | connect_tcp.started host='172.xx.x.xx' port=16399 # API server: OK
DEBUG | connect_tcp.started host='172.xx.x.xx' port=58525 # execd direct: FAIL
DEBUG | connect_tcp.failed exception=ConnectError('All connection attempts failed')
ERROR | filesystem_adapter.py:271 - Failed to write 1 files
httpx.ConnectError: All connection attempts failed
Expected: use_server_proxy=True would route the execd request through port 16399 instead of connecting directly to 58525.
Environment
- AgentScope Version:2.0.5
- Python Version:3.12.0
- OS:ubuntu 22.04
Prerequisites
Background / Description
Problem
Two production requirements that the OpenSandbox workspace classes currently don't support:
1. Cross-network access (
use_server_proxy)When the client and the OpenSandbox server run on different machines, the SDK defaults to direct connections to sandbox containers on their dynamically allocated ports (40000–60000). These ports are unreachable — only the API server port (16399) is exposed. The SDK's
ConnectionConfigalready hasuse_server_proxy: boolto route all execd traffic through the API server, butOpenSandboxWorkspace._connection_config()doesn't expose it.2. Persistent storage (
volumes)Sandboxes have a
timeout_secondslifetime. When a sandbox expires, all files inside/workspaceare lost. The SDK'sSandbox.create()acceptsvolumes: list[Volume](host bind-mount, PVC, OSSFS), butOpenSandboxWorkspace._create_sandbox()doesn't pass it.Proposed change
Add two optional keyword parameters to both
OpenSandboxWorkspace.__init__andOpenSandboxWorkspaceManager.__init__:use_server_proxyboolFalseConnectionConfig.use_server_proxyvolumeslist[Volume] | NoneNoneSandbox.create(volumes=...)OpenSandboxWorkspace._connection_config()— adduse_server_proxy:OpenSandboxWorkspace._create_sandbox()— addvolumes:Environment
Error Messages
Steps to Reproduce
Setup: OpenSandbox server runs on
172.xx.x.xx:16399. Client runs on a different machine (separate network segment).Server config (
sandbox.toml):Client code:
Output:
Expected:
use_server_proxy=Truewould route the execd request through port 16399 instead of connecting directly to 58525.Environment