Repository navigation
feat(sandbox): add a boat.dev sandbox provider - #376
Conversation
boat.dev sandboxes are Ubuntu machines with Docker and Compose running, as a user with passwordless sudo, so they run envs and agents as the other VM providers' machines do. The provider, `boat`, is the `boat` extra (boat-sdk 1.13). - A sandbox is the smallest boat type covering the request, created with none of the boat account's secrets (noEnv) and no snapshots, and stopped by boat at the run's timeout. Its ports are hosted on public HTTPS URLs and recorded in its labels, so get_sandbox on a fresh provider restores them. - Every command runs detached and is followed to its end: no 600 s limit, and the output stream reconnects with no gap. A cancelled exec stops its command. - A create is idempotent across retries of a lost answer; a refused one takes a new key. A create that failed or was cancelled deletes what it made, found by a create label. - Files past one exec's worth, and objects a store cannot sign, go through signed upload URLs, are moved into place as root and checked by sha256. - boat has no egress controls, so a policy that restricts egress is refused. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Thanks for taking the time to do this! |
…nections - A create cancelled while it waits to retry deletes what an unanswered attempt made, found by its create label, as a create cancelled mid-call already did. - Commands' output streams run on a thread pool of their own, so streams that fill it can't keep a stop or a delete from running. - The Docker readiness wait is built from named attempts and interval. - close clears the SDK client's urllib3 pool: the SDK's ApiClient has no close, and the end-to-end run's teardown failed on it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| for key in sorted(attribution) | ||
| if attribution[key] is not None | ||
| ] | ||
| return "-".join(["ae", uuid.uuid4().hex[:8], *filter(None, slugs)])[:_NAME_MAX].rstrip("-") |
There was a problem hiding this comment.
sandbox_name hardcodes the random suffix length in uuid.uuid4().hex[:8]. The repository requires magic numbers to live in descriptive class or instance variables. Give this length a named setting so readers can understand and change it without editing the expression. This repository requirement must be satisfied before merging.
Rule Used: Store magic numbers as class or instance variables with descriptive names rather than using them inline in the code. (source)
Learned From
scaleapi/scaleapi#126388
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agent_env/providers/sandbox_providers/boat/config.py
Line: 97
Comment:
**Name length is hardcoded**
`sandbox_name` hardcodes the random suffix length in `uuid.uuid4().hex[:8]`. The repository requires magic numbers to live in descriptive class or instance variables. Give this length a named setting so readers can understand and change it without editing the expression. This repository requirement must be satisfied before merging.
**Rule Used:** Store magic numbers as class or instance variables with descriptive names rather than using them inline in the code. ([source](https://app.greptile.com/scale-ai/-/custom-context?memory=002e0051-41ad-46c1-9098-47433c580150))
**Learned From**
[scaleapi/scaleapi#126388](https://github.com/scaleapi/scaleapi/pull/126388)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Adds boat.dev as a built-in sandbox provider,
boat, installed with theboatextra (boat-sdk1.13, MIT).What
userwith passwordless sudo, so envs and agents run on it the way they do on the other VM providers' machines.noEnv, so they get none of the boat account's secrets (model keys, GitHub token, environment variables), and with snapshots off, since agent-env never resumes one.timeout, and teardown deletes it with its data.https://<sandbox>-<port>.on.boat.dev. They are recorded in the sandbox's labels, soget_sandboxon a freshly built provider restores them.execruns detached and is followed to its end. A synchronous boat command stops at 600 s, while a detached one has no limit, and its output stream reconnects without a gap. A cancelledexecstops its command in the sandbox.*.on.boat.devjoins the built-in egress floor, so an allowlisted workload on another provider can still reach a gateway hosted on boat._BUILTIN_SANDBOX_PROVIDERSand thedevextra;--sandboxhelp, AGENTS.md andconfig.example.toml;THIRD_PARTY_NOTICES.md;remote_sandbox_is_available, and the stamping and capability tables.Website
Supported sandboxes should get a boat row, its logo, and a short section with the config above.
Tests
To come: the unit results, and the live runs on boat (smoke,
agent-env run hello, an env deploy and chaos).🤖 Generated with Claude Code
The previous fixes are addressed, but the remaining named-setting requirement must be satisfied before merging.
Fix with agent prompt
Summary
Adds boat.dev as a built-in sandbox provider, including commands, file uploads, hosted ports, reconnect, and cleanup.
boatoption appears in provider setup and shared egress rules.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR Exec["exec"] --> Streams["Output-stream workers"] Cancel["Cancel exec"] --> Calls["Separate SDK-call workers"] Create["Create or retry"] --> Calls Delete["Delete sandbox"] --> Calls Calls --> Boat["boat.dev"] Streams --> BoatReviews (2) · Last reviewed commit: "fix(sandbox): keep boat's cleanup off bu..." · Reviewed by Greptile