Skip to main content

Using AIO Sandbox

Best practices for tasks combining browser automation, code execution, and file handling: create a template from the all-in-one image and complete page visits, screenshots, downloads, data cleaning, and result export in one sandbox.

AIO Sandbox is designed for agent tasks where "browser automation + code execution + file handling" happen in sequence. Create a template based on the all-in-one image (all-in-one): port 3000 provides the browser service and port 5000 provides the Code Interpreter/envd service. An agent can complete page visits, screenshots, downloads, data cleaning, code computation, and result export in the same isolated environment. If a task only needs page visits, button clicks, screenshots, or file downloads, prefer the Browser Use Sandbox. Choose AIO Sandbox only when browser artifacts must be handed to Python/Node.js immediately for further processing.
Treat the sandbox's public URL as an access credential: without application-layer authentication, anyone holding the URL has full control over the browser inside the sandbox, including logged-in state and cookies. Do not share it publicly, and do not write it into logs or frontend code.

Use Cases

ScenarioDescription
Scrape then analyzeVisit dynamic pages with the browser, save HTML, screenshots, or downloads, then clean, aggregate, and export with Python
Automated test reportsRun browser E2E tests, then analyze logs, screenshots, and test results in the same sandbox
Content-production agentsGenerate page screenshots, PDFs, tables, JSON, and archive files
Multi-tool agentsCombine the browser, terminal commands, Code Interpreter, and file APIs in one session
  1. Create a template based on the all-in-one image (all-in-one) and obtain its templateCode—see Template Management.
  2. Create a sandbox from the template with a generous timeout. Browser cold start, page loading, and code execution all consume time.
  3. Get the public host of the browser service via sandbox.getHost(3000).
  4. Poll /health until the browser service is ready.
  5. Connect Playwright or Puppeteer through the CDP endpoint to visit pages, interact, screenshot, and download.
  6. Write browser artifacts to the sandbox filesystem, then continue processing them through the Code Interpreter or commands.
  7. Download result files and record URLs, action summaries, screenshot paths, script versions, and outputs.
  8. Destroy the sandbox when the task ends, cleaning up temporary credentials and intermediate files.

Prepare the Local Environment

The following example uses Node.js to connect to the browser inside the sandbox and run Python code in the same sandbox. The business side only needs the SDK and Playwright Core; the browser runs inside the sandbox.
{
  "name": "aio-sandbox-demo",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "@e2b/code-interpreter": "2.6.1",
    "e2b": "2.31.0",
    "playwright-core": "^1.49.0"
  },
  "devDependencies": {
    "tsx": "^4.23.0",
    "typescript": "^6.0.3"
  }
}
e2b and @e2b/code-interpreter are pinned to the versions verified in these examples (2.31.0 / 2.6.1). Newer SDK versions return 405 when creating a sandbox.

Example Code

The example flow:
  1. Create a sandbox.
  2. Wait until the browser service /health returns 200.
  3. Connect to the cloud browser over CDP, visit https://example.com, and write the screenshot to a task directory inside the sandbox.
  4. Use the Code Interpreter to read the browser artifacts and produce a structured summary.
import { Sandbox } from "@e2b/code-interpreter";
import { chromium } from "playwright-core";

const ALIYUN_UID = "your aliyunUid";
const BAILIAN_API_KEY = "sk-...";
const BASE_URL = "https://{workspace_id}.cn-beijing.maas.aliyuncs.com/api/v1/agentstudio/sandbox";
const TEMPLATE = "your template code";

const BROWSER_PORT = 3000;
const TARGET_URL = "https://example.com";
const TASK_DIR = "/tmp/aio-task";
const SCREENSHOT_PATH = `${TASK_DIR}/page.png`;

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

function toArrayBuffer(bytes) {
  return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
}

async function waitUntilHealthy(sandbox, host, timeoutMs = 60_000) {
  const deadline = Date.now() + timeoutMs;

  while (Date.now() < deadline) {
    let result;
    try {
      result = await sandbox.commands.run(
        `curl -sS -o /dev/null -w '%{http_code}' -m 4 ` +
          `https://${host}/health`,
        { timeoutMs: 10_000 },
      );
    } catch (error) {
      result = error;
    }

    const code = (result.stdout || "").trim();
    if (code === "200") {
      return;
    }
    await sleep(2_000);
  }

  throw new Error(`browser service not ready within ${timeoutMs}ms`);
}

async function collectPage(cdpUrl) {
  const browser = await chromium.connectOverCDP(cdpUrl);
  const contexts = browser.contexts();
  const context = contexts.length ? contexts[0] : await browser.newContext();
  const page = await context.newPage();

  try {
    await page.goto(TARGET_URL, {
      waitUntil: "domcontentloaded",
      timeout: 30_000,
    });

    const result = await page.evaluate(() => ({
      url: location.href,
      title: document.title,
      textLength: document.body.innerText.length,
    }));

    const screenshot = await page.screenshot({ fullPage: true });
    return { result, screenshot };
  } finally {
    await page.close();
    await browser.close();
  }
}

let sandbox;

try {
  sandbox = await Sandbox.create(TEMPLATE, {
    apiUrl: BASE_URL,
    apiKey: `e2b_${ALIYUN_UID}`,
    apiHeaders: { Authorization: `Bearer ${BAILIAN_API_KEY}` },
    timeoutMs: 900_000,
    secure: true,
  });

  const host = sandbox.getHost(BROWSER_PORT);
  const cdpUrl = `wss://${host}/ws/automation`;

  await waitUntilHealthy(sandbox, host);

  await sandbox.files.makeDir(TASK_DIR);
  const { result: pageResult, screenshot } = await collectPage(cdpUrl);
  await sandbox.files.write(SCREENSHOT_PATH, toArrayBuffer(screenshot));

  const execution = await sandbox.runCode(`
import json
from pathlib import Path

page = ${JSON.stringify(JSON.stringify(pageResult))}
data = json.loads(page)
summary = {
    "status": "ok",
    "source": "aio-sandbox",
    "title": data["title"],
    "url": data["url"],
    "text_length": data["textLength"],
    "artifacts": [str(Path("${SCREENSHOT_PATH}"))],
}
print(json.dumps(summary, ensure_ascii=False))
`);

  console.log(execution.logs.stdout);
} finally {
  if (sandbox) {
    await sandbox.kill();
  }
}

Integration Advice

  • Use a fixed task directory such as /tmp/aio-task/<task-id> and keep screenshots, HTML, downloads, scripts, and result files together.
  • Log inputs, outputs, logs, and errors separately for the browser phase and the code phase. When troubleshooting, first determine whether the page operation or the subsequent script failed.
  • Validate the type, size, and path of downloaded files before passing them to the code phase.
  • Web content and downloaded files may carry prompt injection. Do not treat page text directly as system instructions or high-privilege tool instructions.
  • Inject browser accounts, cookies, model keys, and business credentials at runtime; never bake them into the template image.
  • Set a maximum page count, maximum download size, command timeouts, and sandbox lifetime so an agent cannot crawl or compute without bound.
  • To watch the browser live, use the noVNC page built into the image: https://<sandbox-host>/static/vnc.html?path=/ws/livestream&autoconnect=true. The path parameter is mandatory and must start with /—a relative ws/livestream resolves to /static/ws/livestream and fails; the root path /vnc.html returns 404. WebSocket clients can connect directly to wss://<sandbox-host>/ws/livestream (equivalent alias /ws/liveview).

Next Steps

Agent Context
Agent Governance & Evolution
Store
Application Marketplace
Using AIO Sandbox - 阿里云百炼