Install
openclaw skills install ppio-sandboxRun browser operations and untrusted code in a secure PPIO cloud sandbox (Firecracker VM). Use when: (1) browsing any external URL or website, (2) executing...
openclaw skills install ppio-sandboxRun browser operations and untrusted code in an isolated PPIO cloud sandbox (Firecracker microVM).
Script: skills/ppio-sandbox/scripts/sandbox.py
References: skills/ppio-sandbox/references/
ALWAYS use this skill when:
npm install, pip install, make in an unfamiliar projectDO NOT use this skill when:
read/write/edit directlypip3 install "ppio_sandbox>=1.0.5"
# Or:
pip3 install -r skills/ppio-sandbox/scripts/requirements.txt
Important: This skill requires ppio_sandbox>=1.0.5. Do NOT modify scripts/sandbox.py — the SDK version is tested and pinned.
export PPIO_API_KEY="sk_your_key" # Required (Note: Sandbox usage incurs API costs billed per second)
export E2B_DOMAIN="sandbox.ppio.cn" # Optional, default shown
python3 -c "from ppio_sandbox.code_interpreter import Sandbox; print('OK')"
⚠️ CDP browser mode is currently DISABLED due to an OpenClaw bug.
The current version of OpenClaw has a bug where config.patch unconditionally sends a SIGUSR1 restart signal, regardless of the gateway.reload setting. This means any config.patch call (including setting browser.profiles.sandbox.cdpUrl) will crash the gateway process. Setting gateway.reload to "hot" does NOT prevent this — the SIGUSR1 is sent through a separate code path that bypasses the reload mode check.
Until OpenClaw fixes this bug, this skill uses Exec mode only. All browsing is done inside the sandbox via curl, puppeteer, or playwright, with results returned as text.
⚠️ NEVER call config.patch for any reason. It will crash the gateway.
PPIO provides two pre-built sandbox templates:
| Template | ID | Pre-installed | Use Case |
|---|---|---|---|
| Browser Use | browser-chromium | Chromium + CDP (port 9223) | Browsing URLs, web scraping, form filling, JS rendering |
| Code Interpreter | code-interpreter-v1 | Python, Node.js, shell, common dev tools | Running untrusted code, builds, scripts |
Sandboxes are created with auto_pause=True by default:
create(timeout, auto_pause=True)
│
▼
[Running] ─── timeout expires ──→ [Paused] (all state preserved)
│ │
│ connect() / any command
│ │
│ ▼
│ [Resumed/Running]
│
kill() ─────────────────────→ [Deleted] (permanent)
Before creating a new sandbox, always check for existing ones:
python3 skills/ppio-sandbox/scripts/sandbox.py list
If a matching sandbox exists (right template, still active/paused), reuse it. Only create new if none match.
python3 skills/ppio-sandbox/scripts/sandbox.py create --template <template> --timeout <seconds>
You MUST estimate the timeout based on the task:
| Task type | Suggested timeout |
|---|---|
| Quick URL fetch / simple page read | 60–120s |
| Multi-step browsing (login, navigate, extract) | 300–600s |
| Clone + install dependencies | 300–600s |
| Full build + test suite | 600–1200s |
| Long-running computation or large project | 1200–1800s |
python3 skills/ppio-sandbox/scripts/sandbox.py exec <sandbox_id> "<command>" --timeout 60
# Read
python3 skills/ppio-sandbox/scripts/sandbox.py read <sandbox_id> /home/user/output.txt
# Write (short content)
python3 skills/ppio-sandbox/scripts/sandbox.py write <sandbox_id> /home/user/script.py "print('hello')"
# Write (multi-line via stdin)
cat <<'EOF' | python3 skills/ppio-sandbox/scripts/sandbox.py write <sandbox_id> /home/user/run.sh --stdin
#!/bin/bash
echo "hello from sandbox"
EOF
# Local → Sandbox
python3 skills/ppio-sandbox/scripts/sandbox.py upload <sandbox_id> ./local.txt /home/user/file.txt
# Sandbox → Local
python3 skills/ppio-sandbox/scripts/sandbox.py download <sandbox_id> /home/user/result.png ./result.png
python3 skills/ppio-sandbox/scripts/sandbox.py status <sandbox_id>
python3 skills/ppio-sandbox/scripts/sandbox.py list
python3 skills/ppio-sandbox/scripts/sandbox.py kill <sandbox_id>
For browsing tasks, create a browser-chromium sandbox and run commands inside the isolated VM. All browsing is done via Exec mode — running curl, puppeteer, or playwright inside the sandbox and returning results as text.
⚠️ CDP mode (native browser tool via config.patch) is DISABLED. The current version of OpenClaw has a bug where config.patch unconditionally sends SIGUSR1, which crashes the gateway — even with gateway.reload set to "hot". Do NOT call config.patch for any reason.
python3 skills/ppio-sandbox/scripts/sandbox.py create --template browser-chromium --timeout 120
python3 skills/ppio-sandbox/scripts/sandbox.py exec <sandbox_id> \
"curl -sL https://example.com" --timeout 30
python3 skills/ppio-sandbox/scripts/sandbox.py exec <sandbox_id> \
"node -e \"const p=require('puppeteer');(async()=>{const b=await p.launch({args:['--no-sandbox']});const pg=await b.newPage();await pg.goto('https://example.com',{waitUntil:'networkidle2'});console.log(await pg.evaluate(()=>document.body.innerText));await b.close()})()\"" \
--timeout 60
# Write a browsing script to the sandbox
cat <<'PYEOF' | python3 skills/ppio-sandbox/scripts/sandbox.py write <sandbox_id> /home/user/browse.py --stdin
import subprocess, json
# Use puppeteer or any browser automation tool
# Output structured results to stdout
print(json.dumps({"title": "...", "content": "..."}))
PYEOF
# Execute it
python3 skills/ppio-sandbox/scripts/sandbox.py exec <sandbox_id> \
"python3 /home/user/browse.py" --timeout 60
For pages that require interaction (clicking buttons, filling forms, multi-step navigation), write a puppeteer/playwright script and execute it inside the sandbox:
cat <<'PYEOF' | python3 skills/ppio-sandbox/scripts/sandbox.py write <sandbox_id> /home/user/interact.js --stdin
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto('https://example.com/login', { waitUntil: 'networkidle2' });
await page.type('#username', 'user');
await page.type('#password', 'pass');
await page.click('#submit');
await page.waitForNavigation();
const text = await page.evaluate(() => document.body.innerText);
console.log(text);
await browser.close();
})();
PYEOF
python3 skills/ppio-sandbox/scripts/sandbox.py exec <sandbox_id> \
"node /home/user/interact.js" --timeout 60
Create a browser-chromium sandbox and use Exec mode (curl/puppeteer/playwright) as shown above.
# 1. Create compute sandbox
python3 skills/ppio-sandbox/scripts/sandbox.py create --template code-interpreter-v1 --timeout 600
# 2. Clone and build
python3 skills/ppio-sandbox/scripts/sandbox.py exec abc123 \
"git clone https://github.com/user/repo /home/user/project" --timeout 120
python3 skills/ppio-sandbox/scripts/sandbox.py exec abc123 \
"cd /home/user/project && npm install && npm test" --timeout 180
# 3. Read results
python3 skills/ppio-sandbox/scripts/sandbox.py read abc123 /home/user/project/test-results.txt
# 4. Download artifacts if needed
python3 skills/ppio-sandbox/scripts/sandbox.py download abc123 \
/home/user/project/dist/output.zip ./output.zip
# 5. Let auto-pause handle cleanup, or kill
python3 skills/ppio-sandbox/scripts/sandbox.py kill abc123
# Previous session created a sandbox that has since auto-paused
python3 skills/ppio-sandbox/scripts/sandbox.py list
# → {"sandboxes": [{"sandbox_id": "abc123", "template_id": "browser-chromium", "status": "paused"}]}
# Just use it — auto-resumes, all state preserved (browser tabs, cookies, files)
python3 skills/ppio-sandbox/scripts/sandbox.py exec abc123 "echo hello"
list first to find reusable sandboxes.browser-chromium for browsing, code-interpreter-v1 for code execution.exec call when possible, avoid redundant sandbox creation, and always reuse existing sandboxes.kill the sandbox to stop all billing.config.patch — the current OpenClaw version has a bug where config.patch unconditionally sends SIGUSR1, crashing the gateway. This affects ALL config paths including browser.profiles.*. Do not use config.patch for any reason.brew install python@3