feat(sandbox): add islo sandbox client with first-class gateway profiles#3124
feat(sandbox): add islo sandbox client with first-class gateway profiles#3124AdamGold wants to merge 1 commit intoopenai:mainfrom
Conversation
Adds `provider: islo` (eighth hosted sandbox backend, alongside Blaxel, Cloudflare, Daytona, E2B, Modal, Runloop, Vercel) to the Sandbox Agents SDK introduced in openai#2889. Backed by github.com/islo-labs/python-sdk's AsyncIslo. Auth comes from ISLO_API_KEY (the SDK handles API-key -> JWT exchange and auto-refresh). Implements the full BaseSandboxClient + BaseSandboxSession surface required for sandbox agents: - create / delete / resume / deserialize_session_state - _exec_internal (POST /exec + poll GetExecResult, since Sandbox Agents only need the final ExecResult; SSE streaming is the right primitive for live UI but not for the agent loop) - read / write (single files via multipart over the SDK's authed httpx client; the auto-generated SDK stubs for these endpoints don't carry payloads so we bypass them while reusing auth) - persist_workspace / hydrate_workspace (tar archive over the same direct path) - running Differentiator: rule-level egress policy via gateway profiles. None of the other backends in this repo expose per-rule allow/deny/rate-limit egress today. options = IsloSandboxClientOptions( gateway_profile=IsloGatewayProfile( default_action="deny", internet_enabled=False, rules=( IsloGatewayRule(host_pattern="api.openai.com", action="allow", rate_limit_rpm=120), IsloGatewayRule(host_pattern="*.github.com", methods=("GET",), action="allow"), ), ), ) When `gateway_profile` is an `IsloGatewayProfile`, the client provisions the profile and rules before sandbox creation and tears them down on session.delete. Pre-existing profiles passed by name/id are not touched. Pyproject extra: `islo = ["islo>=0.2.1"]`. The package guards the sandbox import behind the optional dep the same way the other backends do, so users without the extra installed are unaffected. Tests: 13 unit tests using a mocked AsyncIslo namespace cover the gateway lifecycle (string vs inline, partial-rule failure, sandbox failure cleanup), exec poll loop (success, timeout, transport error), multipart file IO (read 200 / read 404 / write), running probe, archive persist, and reattach-on-resume. Live tests are gated on ISLO_API_KEY. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7c55039b4b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if state.gateway_profile_id is not None: | ||
| recreate_kwargs["gateway_profile"] = state.gateway_profile_id | ||
|
|
||
| sb = await _create_sandbox_with_retry(self._sdk, **recreate_kwargs) |
There was a problem hiding this comment.
Handle paused/stopped sandboxes before recreating on resume
When resume() sees an existing sandbox in paused/stopped, it falls through to create_sandbox with the same name instead of reusing, resuming, or deleting the old one first. In that state the original sandbox still owns the name, so this call can fail with SANDBOX_ALREADY_EXISTS, which means resume breaks for sandboxes that auto-stop or are manually paused. This path needs to either restart/reattach the existing sandbox or explicitly remove it before recreating.
Useful? React with 👍 / 👎.
Adds
provider: islo(eighth hosted sandbox backend, alongside Blaxel, Cloudflare, Daytona, E2B, Modal, Runloop, Vercel) to the Sandbox Agents SDK introduced in #2889.Backed by github.com/islo-labs/python-sdk's AsyncIslo. Auth comes from ISLO_API_KEY (the SDK handles API-key -> JWT exchange and auto-refresh).
Implements the full BaseSandboxClient + BaseSandboxSession surface required for sandbox agents:
Differentiator: rule-level egress policy via gateway profiles. None of the other backends in this repo expose per-rule allow/deny/rate-limit egress today.
When
gateway_profileis anIsloGatewayProfile, the client provisions the profile and rules before sandbox creation and tears them down on session.delete. Pre-existing profiles passed by name/id are not touched.Pyproject extra:
islo = ["islo>=0.2.1"]. The package guards the sandbox import behind the optional dep the same way the other backends do, so users without the extra installed are unaffected.Tests: 13 unit tests using a mocked AsyncIslo namespace cover the gateway lifecycle (string vs inline, partial-rule failure, sandbox failure cleanup), exec poll loop (success, timeout, transport error), multipart file IO (read 200 / read 404 / write), running probe, archive persist, and reattach-on-resume. Live tests are gated on ISLO_API_KEY.