Skip to content

Commit 8768979

Browse files
committed
Revert: rename SDK abstraction back to Sprites
Reviewer feedback: the Fly framing introduces more confusion than it removes (Fly is the vendor brand for many products; Sprites is the specific sandbox product the SDK actually exposes). Rolling back the ``7a652c04`` rename and keeping the original ``Sprites*`` names so the public surface matches what users authenticate against. Reverted at the SDK abstraction layer: - ``agents.extensions.sandbox.flyio/`` → ``agents.extensions.sandbox.sprites/`` - ``FlySandbox*`` classes → ``SpritesSandbox*`` - ``Fly{PlatformContext,UrlAccess,Checkpoints}`` → ``Sprites*`` - ``FlyCloudBucketMountStrategy`` → ``SpritesCloudBucketMountStrategy`` - ``DEFAULT_FLY_SANDBOX_*`` constants → ``DEFAULT_SPRITES_*`` - Polymorphic discriminators: ``"fly"`` → ``"sprites"`` (session), ``"fly_cloud_bucket"`` → ``"sprites_cloud_bucket"``, ``"fly_platform_context"`` / ``"fly_url_access"`` / ``"fly_checkpoints"`` → ``"sprites_*"`` - Internal sentinels: ``__FLY_PRESENT__`` / ``__FLY_MISSING__`` / ``__FLY_MOUNTED__`` / ``__FLY_NOT_MOUNTED__`` → ``__SPRITES_*__`` - Test file: ``test_sandbox_fly.py`` → ``test_sandbox_sprites.py`` - Example runner: ``fly_runner.py`` → ``sprites_runner.py`` - Docs ref dir: ``docs/ref/extensions/sandbox/flyio/`` → ``sprites/`` - Backend identifier and error contexts: ``"fly"`` → ``"sprites"`` Unchanged (real-platform layer, never renamed in the first place): - ``sprites-py`` PyPI dependency - ``[sprites]`` optional extra - ``SPRITES_API_TOKEN`` / ``SPRITES_API_URL`` env vars - ``import sprites`` statements - ``/.sprite/llm.txt`` literal path - ``sprite-env`` CLI references - Internal ``_SPRITE_*`` constants describing platform behavior Compat-guard parametrize entries restored to the Sprites names and discriminator strings. 143 unit tests pass; mypy + ruff clean repo-wide; live-tested against a real sprite + Tigris bucket (SpritesCloudBucketMountStrategy still installs rclone, mounts the bucket, and the dir cache warmup still races correctly).
1 parent f44bf6e commit 8768979

13 files changed

Lines changed: 365 additions & 369 deletions

File tree

docs/ref/extensions/sandbox/flyio/sandbox.md

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `Sandbox`
2+
3+
::: agents.extensions.sandbox.sprites.sandbox

docs/sandbox/clients.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ For provider-specific setup notes and links for the checked-in extension example
9696
| `E2BSandboxClient` | `openai-agents[e2b]` | [E2B runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/e2b_runner.py) |
9797
| `ModalSandboxClient` | `openai-agents[modal]` | [Modal runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/modal_runner.py) |
9898
| `RunloopSandboxClient` | `openai-agents[runloop]` | [Runloop runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/runloop/runner.py) |
99-
| `FlySandboxClient` | `openai-agents[sprites]` | [Fly runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/fly_runner.py) |
99+
| `SpritesSandboxClient` | `openai-agents[sprites]` | [Sprites runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/sprites_runner.py) |
100100
| `VercelSandboxClient` | `openai-agents[vercel]` | [Vercel runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/vercel_runner.py) |
101101

102102
</div>
@@ -114,7 +114,7 @@ Hosted sandbox clients expose provider-specific mount strategies. Choose the bac
114114
| `DaytonaSandboxClient` | Supports rclone-backed cloud storage mounts with `DaytonaCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. |
115115
| `E2BSandboxClient` | Supports rclone-backed cloud storage mounts with `E2BCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. |
116116
| `RunloopSandboxClient` | Supports rclone-backed cloud storage mounts with `RunloopCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. |
117-
| `FlySandboxClient` | Supports rclone-backed cloud storage mounts with `FlyCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. The strategy lazy-installs `rclone` and `fuse` via `sudo apt-get` if the sprite image does not preinstall them. Sprites exposes at most one external HTTP port per sprite (declared as a service in the sprite image); other ports must be reverse-proxied inside the VM. |
117+
| `SpritesSandboxClient` | Supports rclone-backed cloud storage mounts with `SpritesCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. The strategy lazy-installs `rclone` and `fuse` via `sudo apt-get` if the sprite image does not preinstall them. Sprites exposes at most one external HTTP port per sprite (declared as a service in the sprite image); other ports must be reverse-proxied inside the VM. |
118118
| `VercelSandboxClient` | No hosted-specific mount strategy is currently exposed. Use manifest files, repos, or other workspace inputs instead. |
119119

120120
</div>
@@ -132,7 +132,7 @@ The table below summarizes which remote storage entries each backend can mount d
132132
| `DaytonaSandboxClient` |||||| - |
133133
| `E2BSandboxClient` |||||| - |
134134
| `RunloopSandboxClient` |||||| - |
135-
| `FlySandboxClient` |||||| - |
135+
| `SpritesSandboxClient` |||||| - |
136136
| `VercelSandboxClient` | - | - | - | - | - | - |
137137

138138
</div>

examples/sandbox/extensions/README.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ They intentionally keep the flow simple:
77

88
1. Build a tiny manifest in memory.
99
2. Create a `SandboxAgent` that inspects that workspace through one shell tool.
10-
3. Run the agent against E2B, Modal, Daytona, Cloudflare, Runloop, Blaxel, Fly, or Vercel.
10+
3. Run the agent against E2B, Modal, Daytona, Cloudflare, Runloop, Blaxel, Sprites, or Vercel.
1111

1212
All of these examples require `OPENAI_API_KEY`, because they call the model through the normal
1313
`Runner` path. Each cloud backend also needs its own provider credentials.
@@ -328,11 +328,7 @@ the default home and working directory become `/root`, so the example also uses
328328
`/root` as its manifest workspace root. If you configure root launch in your
329329
own code, either rely on that root-mode default or explicitly choose a
330330
`manifest.root` under `/root`.
331-
## Fly
332-
333-
Fly's sandbox product is powered by [Sprites](https://sprites.dev/), Fly's
334-
sandbox-platform credential and runtime. The SDK exposes it as
335-
`FlySandboxClient`; users authenticate with a Sprites API token.
331+
## Sprites
336332

337333
### Setup
338334

@@ -355,7 +351,7 @@ export SPRITES_API_TOKEN=...
355351
### Run
356352

357353
```bash
358-
uv run python examples/sandbox/extensions/fly_runner.py --stream
354+
uv run python examples/sandbox/extensions/sprites_runner.py --stream
359355
```
360356

361357
Useful flags:
@@ -365,15 +361,15 @@ Useful flags:
365361
- `--skip-snapshot-check` — skip the tar workspace persistence verification.
366362
- `--question "..."` — override the default prompt.
367363

368-
The Fly client resolves the Sprites API token from `SPRITES_API_TOKEN` (override
369-
via `FlySandboxClient(token=...)`) and supports exec, filesystem read/write,
370-
PTY-mode interactive exec, and tar-based workspace snapshots. The Fly sandbox
371-
exposes at most one external HTTP port per sprite — declare it as a service
372-
with `--http-port` in the sprite image, then reference it via
373-
`FlySandboxClientOptions(exposed_ports=(<port>,))`.
364+
The Sprites client resolves the API token from `SPRITES_API_TOKEN` (override via
365+
`SpritesSandboxClient(token=...)`) and supports exec, filesystem read/write,
366+
PTY-mode interactive exec, and tar-based workspace snapshots. Sprites exposes
367+
at most one external HTTP port per sprite — declare it as a service with
368+
`--http-port` in the sprite image, then reference it via
369+
`SpritesSandboxClientOptions(exposed_ports=(<port>,))`.
374370

375-
For cloud-bucket mounts, attach `FlyCloudBucketMountStrategy` from
376-
`agents.extensions.sandbox.flyio` to any rclone-compatible mount type
371+
For cloud-bucket mounts, attach `SpritesCloudBucketMountStrategy` from
372+
`agents.extensions.sandbox.sprites` to any rclone-compatible mount type
377373
(`S3Mount`, `R2Mount`, `GCSMount`, `AzureBlobMount`, `BoxMount`). The strategy
378374
lazy-installs `rclone` and the `fuse` package via `sudo apt-get` on first use
379375
if the sprite image does not preinstall them.

examples/sandbox/extensions/fly_runner.py renamed to examples/sandbox/extensions/sprites_runner.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333

3434
try:
3535
from agents.extensions.sandbox import (
36-
FlySandboxClient,
37-
FlySandboxClientOptions,
36+
SpritesSandboxClient,
37+
SpritesSandboxClientOptions,
3838
)
3939
except Exception as exc: # pragma: no cover - import path depends on optional extras
4040
raise SystemExit(
@@ -92,8 +92,8 @@ async def _verify_stop_resume(*, sprite_name: str | None) -> None:
9292
against the existing sprite (no create/delete on the API).
9393
"""
9494

95-
client = FlySandboxClient()
96-
options = FlySandboxClientOptions(sprite_name=sprite_name)
95+
client = SpritesSandboxClient()
96+
options = SpritesSandboxClientOptions(sprite_name=sprite_name)
9797

9898
with tempfile.TemporaryDirectory(prefix="sprites-snapshot-example-") as snapshot_dir:
9999
sandbox = await client.create(
@@ -157,10 +157,10 @@ async def main(
157157
model_settings=ModelSettings(tool_choice="required"),
158158
)
159159

160-
client = FlySandboxClient()
160+
client = SpritesSandboxClient()
161161
sandbox = await client.create(
162162
manifest=manifest,
163-
options=FlySandboxClientOptions(sprite_name=sprite_name),
163+
options=SpritesSandboxClientOptions(sprite_name=sprite_name),
164164
)
165165

166166
run_config = RunConfig(

src/agents/extensions/sandbox/__init__.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,24 @@
110110
_HAS_VERCEL = False
111111

112112
try:
113-
from .flyio import (
114-
DEFAULT_FLY_SANDBOX_API_URL as DEFAULT_FLY_SANDBOX_API_URL,
115-
DEFAULT_FLY_SANDBOX_CONTEXT_PATH as DEFAULT_FLY_SANDBOX_CONTEXT_PATH,
116-
DEFAULT_FLY_SANDBOX_WAIT_FOR_RUNNING_TIMEOUT_S as DEFAULT_FLY_SANDBOX_WAIT_FOR_RUNNING_TIMEOUT_S, # noqa: E501
117-
DEFAULT_FLY_SANDBOX_WORKSPACE_ROOT as DEFAULT_FLY_SANDBOX_WORKSPACE_ROOT,
118-
FlyCheckpoints as FlyCheckpoints,
119-
FlyCloudBucketMountStrategy as FlyCloudBucketMountStrategy,
120-
FlyPlatformContext as FlyPlatformContext,
121-
FlySandboxClient as FlySandboxClient,
122-
FlySandboxClientOptions as FlySandboxClientOptions,
123-
FlySandboxSession as FlySandboxSession,
124-
FlySandboxSessionState as FlySandboxSessionState,
125-
FlyUrlAccess as FlyUrlAccess,
126-
)
127-
128-
_HAS_FLY = True
113+
from .sprites import (
114+
DEFAULT_SPRITES_API_URL as DEFAULT_SPRITES_API_URL,
115+
DEFAULT_SPRITES_CONTEXT_PATH as DEFAULT_SPRITES_CONTEXT_PATH,
116+
DEFAULT_SPRITES_WAIT_FOR_RUNNING_TIMEOUT_S as DEFAULT_SPRITES_WAIT_FOR_RUNNING_TIMEOUT_S, # noqa: E501
117+
DEFAULT_SPRITES_WORKSPACE_ROOT as DEFAULT_SPRITES_WORKSPACE_ROOT,
118+
SpritesCheckpoints as SpritesCheckpoints,
119+
SpritesCloudBucketMountStrategy as SpritesCloudBucketMountStrategy,
120+
SpritesPlatformContext as SpritesPlatformContext,
121+
SpritesSandboxClient as SpritesSandboxClient,
122+
SpritesSandboxClientOptions as SpritesSandboxClientOptions,
123+
SpritesSandboxSession as SpritesSandboxSession,
124+
SpritesSandboxSessionState as SpritesSandboxSessionState,
125+
SpritesUrlAccess as SpritesUrlAccess,
126+
)
127+
128+
_HAS_SPRITES = True
129129
except Exception: # pragma: no cover
130-
_HAS_FLY = False
130+
_HAS_SPRITES = False
131131

132132
__all__: list[str] = []
133133

@@ -228,20 +228,20 @@
228228
]
229229
)
230230

231-
if _HAS_FLY:
231+
if _HAS_SPRITES:
232232
__all__.extend(
233233
[
234-
"DEFAULT_FLY_SANDBOX_API_URL",
235-
"DEFAULT_FLY_SANDBOX_CONTEXT_PATH",
236-
"DEFAULT_FLY_SANDBOX_WAIT_FOR_RUNNING_TIMEOUT_S",
237-
"DEFAULT_FLY_SANDBOX_WORKSPACE_ROOT",
238-
"FlyCheckpoints",
239-
"FlyCloudBucketMountStrategy",
240-
"FlyPlatformContext",
241-
"FlySandboxClient",
242-
"FlySandboxClientOptions",
243-
"FlySandboxSession",
244-
"FlySandboxSessionState",
245-
"FlyUrlAccess",
234+
"DEFAULT_SPRITES_API_URL",
235+
"DEFAULT_SPRITES_CONTEXT_PATH",
236+
"DEFAULT_SPRITES_WAIT_FOR_RUNNING_TIMEOUT_S",
237+
"DEFAULT_SPRITES_WORKSPACE_ROOT",
238+
"SpritesCheckpoints",
239+
"SpritesCloudBucketMountStrategy",
240+
"SpritesPlatformContext",
241+
"SpritesSandboxClient",
242+
"SpritesSandboxClientOptions",
243+
"SpritesSandboxSession",
244+
"SpritesSandboxSessionState",
245+
"SpritesUrlAccess",
246246
]
247247
)

src/agents/extensions/sandbox/flyio/__init__.py

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from __future__ import annotations
2+
3+
from .capabilities import (
4+
DEFAULT_SPRITES_CONTEXT_PATH,
5+
SpritesCheckpoints,
6+
SpritesPlatformContext,
7+
SpritesUrlAccess,
8+
UrlVisibility,
9+
clear_platform_context_cache,
10+
)
11+
from .mounts import SpritesCloudBucketMountStrategy
12+
from .sandbox import (
13+
DEFAULT_SPRITES_API_URL,
14+
DEFAULT_SPRITES_WAIT_FOR_RUNNING_TIMEOUT_S,
15+
DEFAULT_SPRITES_WORKSPACE_ROOT,
16+
SpritesSandboxClient,
17+
SpritesSandboxClientOptions,
18+
SpritesSandboxSession,
19+
SpritesSandboxSessionState,
20+
)
21+
22+
__all__ = [
23+
"DEFAULT_SPRITES_API_URL",
24+
"DEFAULT_SPRITES_CONTEXT_PATH",
25+
"DEFAULT_SPRITES_WAIT_FOR_RUNNING_TIMEOUT_S",
26+
"DEFAULT_SPRITES_WORKSPACE_ROOT",
27+
"SpritesCheckpoints",
28+
"SpritesCloudBucketMountStrategy",
29+
"SpritesPlatformContext",
30+
"SpritesSandboxClient",
31+
"SpritesSandboxClientOptions",
32+
"SpritesSandboxSession",
33+
"SpritesSandboxSessionState",
34+
"SpritesUrlAccess",
35+
"UrlVisibility",
36+
"clear_platform_context_cache",
37+
]

0 commit comments

Comments
 (0)