> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# A model writes code, a sandbox runs its tests

A sandbox with infer:run and no internet asks the node's model for a function, runs the tests on it and sends failures back, at most three times.

The sandbox is created with two settings that do the work:

- `api.scopes: ["infer:run"]` lets code inside it call the node's model at `http://127.0.0.1:7700/v1/infer`, and
  `spend_cap_usd: 1` stops those calls once they have cost a dollar, whatever the model-written code does. The
  create sets `OPENAI_BASE_URL`, a placeholder `OPENAI_API_KEY` and `B3OS_MODEL` in its environment, so a stock
  OpenAI client (or plain HTTP, as here) works with no key inside the sandbox.
- `egress: {mode: "deny"}` leaves it no other way out. The recipe checks that: `curl https://example.com` from the
  sandbox fails (`internet: blocked`), while the model calls succeed.

Verified 2026-11-06: this recipe's last run passed against `https://beta-api.b3os.org`, label `live-recorded` (recorded from production), from commit `9fd4273e`. The recipe harness runs it again, and a failed run takes this page out of the cookbook.

## Run it

Each tab uploads the three files from this recipe's folder, checks that the sandbox cannot reach the internet, runs
`agent.py` and prints the solution it kept.

**curl**

```bash
API=https://beta-api.b3os.org
AUTH="Authorization: Bearer $B3OS_API_KEY"
post() { curl -s "$API$1" -H "$AUTH" -H "Content-Type: application/json" -d @-; }

SBX=$(echo '{"template": "base", "timeout_s": 300, "egress": {"mode": "deny"},
  "api": {"scopes": ["infer:run"], "spend_cap_usd": 1}}' | post /v1/sandboxes | jq -r .id)
for f in agent.py task.md test_solution.py; do
  curl -s -X PUT "$API/v1/sandboxes/$SBX/files?path=/workspace/$f" -H "$AUTH" \
    -H "Content-Type: application/octet-stream" --data-binary @"$f" > /dev/null
done
echo '{"cmd": "curl -s -m 5 -o /dev/null https://example.com && echo reached || echo blocked"}' \
  | post "/v1/sandboxes/$SBX/exec" | jq -r .stdout
echo '{"cmd": ["python3", "/workspace/agent.py"], "timeout_ms": 58000}' \
  | post "/v1/sandboxes/$SBX/exec" | jq -r '.stdout | split("\n") | map(select(. != "")) | last'
curl -s "$API/v1/sandboxes/$SBX/files?path=/workspace/solution.py" -H "$AUTH"
curl -s -X DELETE "$API/v1/sandboxes/$SBX" -H "$AUTH" > /dev/null
```
**TypeScript**

```ts
import { readFileSync } from "node:fs";

const API = "https://beta-api.b3os.org";
const auth = { authorization: `Bearer ${process.env.B3OS_API_KEY}` };
const call = async (method: string, path: string, body?: unknown): Promise<any> =>
  (
    await fetch(`${API}${path}`, {
      method,
      headers: { ...auth, "content-type": "application/json" },
      body: body === undefined ? undefined : JSON.stringify(body),
    })
  ).json();

const sbx = await call("POST", "/v1/sandboxes", {
  template: "base",
  timeout_s: 300,
  api: { scopes: ["infer:run"], spend_cap_usd: 1 },
  egress: { mode: "deny" },
});
for (const f of ["agent.py", "task.md", "test_solution.py"])
  await fetch(`${API}/v1/sandboxes/${sbx.id}/files?path=/workspace/${f}`, {
    method: "PUT",
    headers: { ...auth, "content-type": "application/octet-stream" },
    body: readFileSync(f, "utf8"),
  });
const probe = await call("POST", `/v1/sandboxes/${sbx.id}/exec`, {
  cmd: "curl -s -m 5 -o /dev/null https://example.com && echo reached || echo blocked",
});
console.log(`internet: ${probe.stdout.trim()}`);
const r = await call("POST", `/v1/sandboxes/${sbx.id}/exec`, { cmd: ["python3", "/workspace/agent.py"], timeout_ms: 58000 });
console.log(JSON.parse(r.stdout.trim().split("\n").at(-1) ?? "{}"));
const solution = await fetch(`${API}/v1/sandboxes/${sbx.id}/files?path=/workspace/solution.py`, { headers: auth });
console.log(await solution.text());
await call("DELETE", `/v1/sandboxes/${sbx.id}`);
```
**Python**

```python
import json
import os

import requests

API = "https://beta-api.b3os.org"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['B3OS_API_KEY']}"

sbx = s.post(f"{API}/v1/sandboxes", json={
    "template": "base", "timeout_s": 300, "egress": {"mode": "deny"},
    "api": {"scopes": ["infer:run"], "spend_cap_usd": 1},
}).json()["id"]
for f in ["agent.py", "task.md", "test_solution.py"]:
    with open(f, "rb") as fh:
        s.put(f"{API}/v1/sandboxes/{sbx}/files", params={"path": f"/workspace/{f}"}, data=fh.read(),
              headers={"Content-Type": "application/octet-stream"})
probe = s.post(f"{API}/v1/sandboxes/{sbx}/exec", json={
    "cmd": "curl -s -m 5 -o /dev/null https://example.com && echo reached || echo blocked",
}).json()
print("internet:", probe["stdout"].strip())
r = s.post(f"{API}/v1/sandboxes/{sbx}/exec",
           json={"cmd": ["python3", "/workspace/agent.py"], "timeout_ms": 58000}).json()
print(json.loads(r["stdout"].strip().split("\n")[-1]))
print(s.get(f"{API}/v1/sandboxes/{sbx}/files", params={"path": "/workspace/solution.py"}).text)
s.delete(f"{API}/v1/sandboxes/{sbx}")
```
**MCP**

The MCP `sandbox_create` tool takes no `api` grant, and without `infer:run` the sandbox has no `OPENAI_BASE_URL` for
`agent.py` to call. Create the sandbox with the API, with the same `B3OS_API_KEY` your MCP client sends:

```bash
curl -s https://beta-api.b3os.org/v1/sandboxes -H "Authorization: Bearer $B3OS_API_KEY" \
  -H "Content-Type: application/json" -d '{"template": "base", "timeout_s": 600, "egress": {"mode": "deny"},
  "api": {"scopes": ["infer:run"], "spend_cap_usd": 1}}' | jq -r .id
```

Then, on the remote [B3OS MCP server](/sdks/mcp), with the three files' contents in the conversation, ask your agent:

```text
In sandbox <id>, write agent.py, task.md and test_solution.py to /workspace. Check that curl https://example.com
fails from inside it, then run python3 /workspace/agent.py with a 58 second timeout, show me /workspace/solution.py
and say how many tests passed, then delete the sandbox.
```

The agent calls `sandbox_write_file` three times, `sandbox_exec` twice, `sandbox_read_file` and `sandbox_delete`.

Inside the sandbox, `agent.py` (standard library only) sends `task.md` to the model, writes the answer's code block
to `solution.py`, runs `python3 -m unittest test_solution` and, when a test fails, sends the failure back and tries
again, at most three times. The task is `parse_duration("1h30m") == 5400` with seven tests, including the inputs it
must refuse (`"30m1h"`, `"1.5h"`, `"10"`).

The outputs are the run's own measurements: `model_ms` is the time spent in model calls and `tests_ms` the last test
run, both measured inside the sandbox; `create_ms` is the create's server-side total from its `timing`; `exec_ms` is
the agent's exec as the client saw it. The sandbox is deleted at the end, whatever happened.

Files: `run.mjs` (the client), `agent.py`, `task.md` and `test_solution.py` (uploaded to the sandbox).

Owner: Sandboxes. Products: Sandboxes, Infer.

## Output of the last green run

**Outputs**

```json
{
  "model": "b3os/qwen3.5-9b",
  "internet": "blocked",
  "attempts": 1,
  "all_passed": true,
  "tests_total": 7,
  "tests_passed": 7,
  "model_ms": 2722.6,
  "completion_tokens": 624,
  "tests_ms": 92.7,
  "create_ms": 1.821,
  "exec_ms": 2887.1,
  "solution_lines": 72,
  "solution_head": "def parse_duration(text: str) -> int:\n    import re\n    \n    text = text.strip()\n    if not text:\n        raise ValueError(\"Empty string\")\n    \n    # Pattern to match integer followed by a unit\n    # We need to ensure the whole string is consumed by these parts\n    pattern = r'^(\\d+)([hms])'\n    \n    parts = []\n    remaining = text\n    \n    while remaining:\n        match = re.match(pattern, remain"
}
```
**Command**

```bash
$ node run.mjs
# exit 0
```

The outputs this recipe publishes (the `publish.outputs` list in its recipe.json), with workspace identifiers redacted. The run's stdout, stderr and other outputs are not published.

Captured 2026-11-06 from commit `9fd4273e`, label `live-recorded` (recorded from production). Case `recipes/sandbox-model-writes-tested-code`.