### Upstash Box Setup and Goose Installation Source: https://upstash.com/docs/box/overall/custom-harness/goose This script initializes an Upstash Box, installs the Goose binary by downloading and extracting it, and writes the custom agent code. It then executes two turns of agent interaction. ```javascript const box = await Box.create({ apiKey: process.env.UPSTASH_BOX_API_KEY!, baseUrl: process.env.UPSTASH_BOX_BASE_URL, runtime: "node", agent: { harness: Agent.Custom, model: "anthropic/claude-sonnet-4-5", customHarness: { command: "node", args: ["/workspace/home/custom-goose-agent.mjs"], protocol: "box-sse-v1", }, }, env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!, GOOSE_PROVIDER: "anthropic", GOOSE_DISABLE_KEYRING: "1", PATH: "/home/boxuser/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", }, }); console.log(`Created box: ${box.id}`); try { console.log("Installing Goose..."); await box.exec.command(` node --input-type=module -e " import { writeFileSync } from 'fs'; const arch = process.arch === 'arm64' ? 'aarch64' : 'x86_64'; const url = 'https://github.com/aaif-goose/goose/releases/download/stable/goose-' + arch + '-unknown-linux-gnu.tar.gz'; const buf = Buffer.from(await (await fetch(url)).arrayBuffer()); writeFileSync('/tmp/goose.tar.gz', buf); " mkdir -p /home/boxuser/.local/bin tar -xzf /tmp/goose.tar.gz -C /home/boxuser/.local/bin/ chmod +x /home/boxuser/.local/bin/goose `); await box.files.write({ path: "custom-goose-agent.mjs", content: agentSource, }); console.log("\n=== Turn 1 ==="); const run1 = await box.agent.run({ prompt: "Create a file called hello.txt with the content 'Hello from Goose!'", }); console.log(run1.result); console.log("\n=== Turn 2 (follow-up) ==="); const run2 = await box.agent.run({ prompt: "Read back the file you just created.", }); console.log(run2.result); } finally { await box.delete(); console.log("\nBox deleted."); } ``` -------------------------------- ### Reusable Base Environments (Python) Source: https://upstash.com/docs/box/overall/snapshots Install dependencies once into a base environment, snapshot it, and then spawn new boxes from this snapshot to avoid repeated setup time. ```python import asyncio from upstash_box import AsyncBox async def main() -> None: base = await AsyncBox.create(runtime="node") await base.exec.command("npm install -g typescript eslint prettier") base_snap = await base.snapshot(name="node-toolchain") await base.delete() async def run_task(task: str) -> AsyncBox: box = await AsyncBox.from_snapshot(base_snap.id) await box.agent.run(prompt=task) return box # spawn boxes from the snapshot in parallel await asyncio.gather(*(run_task(t) for t in tasks)) asyncio.run(main()) ``` -------------------------------- ### Download and Install Hermes Agent Source: https://upstash.com/docs/box/guides/hermes-setup Use curl to download and execute the Hermes installation script. Follow the on-screen prompts to complete the setup. ```bash curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash ``` -------------------------------- ### Reusable Base Environments (TypeScript) Source: https://upstash.com/docs/box/overall/snapshots Install dependencies once into a base environment, snapshot it, and then spawn new boxes from this snapshot to avoid repeated setup time. ```typescript import { Agent, Box } from "@upstash/box" const base = await Box.create({ runtime: "node" }) await base.exec.command("npm install -g typescript eslint prettier") const baseSnap = await base.snapshot({ name: "node-toolchain" }) await base.delete() const boxes = await Promise.all( tasks.map(async (task) => { const box = await Box.fromSnapshot(baseSnap.id) await box.agent.run({ prompt: task }) return box }) ) ``` -------------------------------- ### Install Dependencies Before Run (Python) Source: https://upstash.com/docs/box/overall/shell This Python snippet demonstrates setting up a development environment by cloning a repository and installing npm dependencies. It requires ANTHROPIC_API_KEY and GITHUB_TOKEN environment variables. ```python import os from upstash_box import Box, Agent box = Box.create( runtime="node", agent={"harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-opus-4-6", "api_key": os.environ["ANTHROPIC_API_KEY"]}, git={"token": os.environ["GITHUB_TOKEN"]}, ) box.git.clone(repo="github.com/your-org/your-api") box.exec.command("npm install") box.agent.run(prompt="Run the test suite and fix any failing tests") ``` -------------------------------- ### Install Crabbox using Homebrew Source: https://upstash.com/docs/box/guides/crabbox-setup Install the Crabbox CLI tool using the Homebrew package manager. ```bash brew install openclaw/tap/crabbox ``` -------------------------------- ### Install Upstash Box SDK with bun Source: https://upstash.com/docs/box/overall/quickstart Install the Upstash Box SDK using bun. This is a fast, all-in-one JavaScript runtime. ```bash bun install @upstash/box ``` -------------------------------- ### Install Dependencies Source: https://upstash.com/docs/box/guides/ai-sdk-code-interpreter Install the necessary packages for Upstash Box, Vercel AI SDK, and Zod. Ensure you have the required API keys configured in your environment variables. ```bash npm install @upstash/box @ai-sdk/anthropic @ai-sdk/react ai zod ``` -------------------------------- ### Create a Public URL for a Web Server (Python) Source: https://upstash.com/docs/box/overall/preview Starts a web server on port 3000 within the box and creates a public URL to access it using Python. Requires installing express and writing a simple server file. ```python from upstash_box import Box box = Box.create(runtime="node") # Start a web server on port 3000 box.exec.command("cd /work && npm install express") box.files.write( path="/work/server.js", content=""" const express = require('express') const app = express() app.get('/', (req, res) => res.send('Hello from Box!')) app.listen(3000) """, ) box.exec.command("node /work/server.js &") # Create a public URL public_url = box.get_public_url(3000) print(public_url.url) # -> https://{BOX_ID}-3000.preview.box.upstash.com ``` -------------------------------- ### Create a Public URL for a Web Server Source: https://upstash.com/docs/box/overall/preview Starts a web server on port 3000 within the box and creates a public URL to access it. Requires installing express and writing a simple server file. ```typescript import { Agent, Box } from "@upstash/box" const box = await Box.create({ runtime: "node" }) // Start a web server on port 3000 await box.exec.command("cd /work && npm install express") await box.files.write({ path: "/work/server.js", content: "\n const express = require('express')\n const app = express()\n app.get('/', (req, res) => res.send('Hello from Box!'))\n app.listen(3000)\n ", }) await box.exec.command("node /work/server.js &") // Create a public URL const publicUrl = await box.getPublicUrl(3000) console.log(publicUrl.url) // → https://{BOX_ID}-3000.preview.box.upstash.com ``` -------------------------------- ### Provision Box and Install Playwright Source: https://upstash.com/docs/box/guides/web-scraping-playwright Provision a new Box, install Playwright, and then install Chromium with its system dependencies using npx. This prepares the Box environment for web scraping. ```typescript import "dotenv/config" import { Agent, Box } from "@upstash/box" const box = await Box.create({ runtime: "node", agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-sonnet-4-6", }, }) console.log(`Box ready: ${box.id}`) await box.exec.command("npm init -y && npm install playwright") // `--with-deps` pulls in the Linux system libraries Chromium needs via apt-get const setup = await box.exec.command("npx playwright install chromium --with-deps") if (setup.status !== "completed") { throw new Error(`Chromium setup failed: ${setup.result}`) } console.log("Chromium and its system dependencies are ready.") ``` -------------------------------- ### Configure and Start OpenClaw Gateway Source: https://upstash.com/docs/box/guides/openclaw-setup Configure the OpenClaw gateway to bind to the LAN interface and then start it in the background. The output is redirected to gateway.log. This ensures the gateway is accessible on the local network and runs persistently. ```bash openclaw config set gateway.bind lan nohup openclaw gateway > gateway.log 2>&1 & ``` -------------------------------- ### Install Dependencies Before Run (TypeScript) Source: https://upstash.com/docs/box/overall/shell Use this snippet to set up your environment by cloning a repository and installing npm dependencies before handing off to an agent. Ensure your ANTHROPIC_API_KEY and GITHUB_TOKEN environment variables are set. ```typescript import { Agent, Box } from "@upstash/box" const box = await Box.create({ runtime: "node", agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-opus-4-6", apiKey: process.env.ANTHROPIC_API_KEY }, git: { token: process.env.GITHUB_TOKEN }, }) await box.git.clone({ repo: "github.com/your-org/your-api" }) await box.exec.command("npm install") await box.agent.run({ prompt: "Run the test suite and fix any failing tests", }) ``` -------------------------------- ### Install System Packages Source: https://upstash.com/docs/box/overall/shell Install additional system tools using Debian's package manager within the box. Ensure you have the necessary permissions for `sudo`. ```typescript await box.exec.command("sudo apt-get install ") ``` ```python box.exec.command("sudo apt-get install ") ``` -------------------------------- ### Install Upstash Box SDK with npm Source: https://upstash.com/docs/box/overall/quickstart Install the Upstash Box SDK using npm. This is the first step to using Upstash Box in your Node.js project. ```bash npm install @upstash/box ``` -------------------------------- ### Install Upstash Box SDK with pip Source: https://upstash.com/docs/box/overall/quickstart Install the Upstash Box Python SDK using pip. This is the standard package installer for Python. ```bash pip install upstash-box ``` -------------------------------- ### Install Upstash Box Source: https://upstash.com/docs/box/guides/web-scraping-playwright Install the Upstash Box package using npm. Ensure your environment variables are set. ```bash npm install @upstash/box ``` ```bash UPSTASH_BOX_API_KEY=box_xxxxxxxxxxxxxxxxxxxxxxxx ``` -------------------------------- ### Create Playwright Snapshot Source: https://upstash.com/docs/box/guides/web-scraping-playwright Create a snapshot of the Box after Playwright and its dependencies are installed. This allows for faster subsequent Box initializations by skipping the setup process. ```typescript const snapshot = await box.snapshot({ name: "playwright-ready" }) console.log(`Snapshot ready: ${snapshot.id}`) ``` -------------------------------- ### Install OpenClaw CLI Source: https://upstash.com/docs/box/guides/openclaw-setup Install the OpenClaw command-line interface globally within the Upstash Box. This command requires sudo privileges. ```bash sudo npm install -g openclaw ``` -------------------------------- ### Install Dependencies and Write Agent File Source: https://upstash.com/docs/box/overall/custom-harness/pi Installs necessary npm packages for the Pi coding agent and writes the agent's source code to a file within the Box environment. Ensure the agent source code is correctly defined elsewhere. ```bash await box.exec.command( "cd /workspace/home && npm install @earendil-works/pi-coding-agent @earendil-works/pi-ai --silent" ); await box.files.write({ path: "custom-pi-agent.mjs", content: agentSource, }); ``` -------------------------------- ### Install Upstash Box and Zod Source: https://upstash.com/docs/box/guides/code-review-agent Install the necessary npm packages for Upstash Box and Zod. This is the first step in setting up the code review agent. ```bash npm install @upstash/box zod ``` -------------------------------- ### Install Upstash Box SDK with yarn Source: https://upstash.com/docs/box/overall/quickstart Install the Upstash Box SDK using yarn. This is an alternative package manager for Node.js projects. ```bash yarn add @upstash/box ``` -------------------------------- ### Fan-out from a Single State (Python) Source: https://upstash.com/docs/box/overall/snapshots Clone a repository once, create a snapshot, and then spawn multiple boxes from this snapshot to run different agents or prompts in parallel from the same starting point. ```python import asyncio import os from upstash_box import AsyncBox async def main() -> None: seed = await AsyncBox.create( runtime="node", git={"token": os.environ["GITHUB_TOKEN"]}, ) await seed.git.clone(repo="github.com/your-org/monorepo") snap = await seed.snapshot(name="repo-cloned") await seed.delete() security, performance, docs = await asyncio.gather( AsyncBox.from_snapshot(snap.id), AsyncBox.from_snapshot(snap.id), AsyncBox.from_snapshot(snap.id), ) await asyncio.gather( security.agent.run(prompt="Audit src/ for SQL injection vulnerabilities"), performance.agent.run(prompt="Profile the hot paths in src/api/ and optimize"), docs.agent.run(prompt="Generate API documentation for all public exports"), ) asyncio.run(main()) ``` -------------------------------- ### Install Upstash Box SDK with pnpm Source: https://upstash.com/docs/box/overall/quickstart Install the Upstash Box SDK using pnpm. This is another package manager for Node.js projects. ```bash pnpm add @upstash/box ``` -------------------------------- ### Open a Pull Request with Agent and Git Source: https://upstash.com/docs/box/overall/agent This example demonstrates cloning a repository, running an agent to fix a bug, and then opening a pull request. It requires environment variables for API keys. ```tsx import { Agent, Box } from "@upstash/box" const box = await Box.create({ runtime: "node", agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-opus-4-5", apiKey: process.env.ANTHROPIC_API_KEY, }, git: { token: process.env.GITHUB_TOKEN, }, }) await box.git.clone({ repo: "github.com/your-org/your-repo" }) const stream = await box.agent.stream({ prompt: "Fix the null token bug in src/auth.ts and add tests", }) for await (const chunk of stream) { if (chunk.type === "text-delta") process.stdout.write(chunk.text) } await box.git.createPR({ title: "Fix null token bug", base: "main", }) ``` ```python import os from upstash_box import Box, Agent box = Box.create( runtime="node", agent={ "harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-opus-4-5", "api_key": os.environ["ANTHROPIC_API_KEY"], }, git={"token": os.environ["GITHUB_TOKEN"]}, ) box.git.clone(repo="github.com/your-org/your-repo") stream = box.agent.stream(prompt="Fix the null token bug in src/auth.ts and add tests") for chunk in stream: if chunk.type == "text-delta": print(chunk.text, end="") box.git.create_pr(title="Fix null token bug", base="main") ``` -------------------------------- ### Execute Sandbox Code Example Source: https://upstash.com/docs/box/guides/ai-sdk-code-interpreter Demonstrates the execution of a Python code snippet within a sandbox environment to perform complex calculations. The output shows the results of square root and factorial computations, and their sum. Ensure a timeout is always set for `exec.code` to prevent hangs. ```text executeSandboxCode ✓ Square root of 144: 12.0 25 factorial: 15511210043330985984000000 Sum: 1.5511210043330986e+25 ``` -------------------------------- ### Set Init Command for Keep-Alive Box (Python) Source: https://upstash.com/docs/box/overall/keep-alive Configure an 'init_command' to run automatically when a keep-alive box starts. This is useful for starting web servers or preparing agent environments. ```python box = Box.create( runtime="node", keep_alive=True, init_command="npm install && npm run dev", ) ``` -------------------------------- ### Create and Run a Next.js App in the Box Source: https://upstash.com/docs/box/guides/remote-development Commands to create a new Next.js application within the box and start the development server. This assumes an SSH connection with port forwarding is already active. ```bash npx create-next-app@latest my-app cd my-app npm run dev ``` -------------------------------- ### Install Dependencies for TanStack AI and Upstash Box Source: https://upstash.com/docs/box/guides/tanstack-ai-file-editor Install the necessary packages for TanStack AI, Anthropic, React integration, Upstash Box, and Zod for schema validation. ```bash npm install @tanstack/ai @tanstack/ai-anthropic @tanstack/ai-react @upstash/box zod ``` -------------------------------- ### Initialize Pi Agent Session Source: https://upstash.com/docs/box/overall/custom-harness/pi Sets up a new agent session using the Pi harness. It configures the model, working directory, and session directory. Use this to start an agent interaction with a specific prompt and model. ```typescript import { createAgentSession, SessionManager } from "@earendil-works/pi-coding-agent"; import { getModel } from "@earendil-works/pi-ai"; import { randomUUID } from "crypto"; import { mkdir } from "fs/promises"; import { readFileSync, unlinkSync } from "fs"; const WORK_DIR = "/workspace/home"; const SESSIONS_DIR = "/workspace/home/.pi-sessions"; const MCP_CONFIG_PATH = "/workspace/home/.box-internal/mcp-config.json"; function loadMcpServers() { try { const configs = JSON.parse(readFileSync(MCP_CONFIG_PATH, "utf-8")); if (!configs.length) return { urls: [], warned: false }; const urls = []; let warned = false; for (const cfg of configs) { if (cfg.source === "url") { urls.push(cfg.package_or_url); if (cfg.headers && Object.keys(cfg.headers).length) { console.error("[pi] Warning: headers for MCP server '" + cfg.name + "' are not supported by extensionUrls — headers will be ignored"); } } else { console.error("[pi] Warning: npm MCP server '" + cfg.name + "' not supported; only HTTP MCP servers are applied"); warned = true; } } if (urls.length) console.error("[pi] MCP servers: " + urls.join(", ")); return { urls, warned }; } catch { return { urls: [], warned: false }; } } const args = process.argv.slice(2); function readArg(name, fallback = "") { const idx = args.indexOf(name); return idx >= 0 ? args[idx + 1] ?? fallback : fallback; } // Redirect SDK stdout noise to stderr so only SSE events hit stdout const _write = process.stdout.write.bind(process.stdout); process.stdout.write = process.stderr.write.bind(process.stderr); function emit(event, data) { _write("event: " + event + "\n"); _write("data: " + JSON.stringify(data) + "\n\n"); } const prompt = readArg("-p"); const modelStr = readArg("--model", "anthropic/claude-sonnet-4-5"); const sessionId = readArg("--session") || randomUUID(); const sessionDir = SESSIONS_DIR + "/" + sessionId; if (!prompt) { emit("error", { error: "no prompt provided", session_id: sessionId }); process.exit(1); } function isTextMimeType(mime) { if (mime.startsWith("text/")) return true; return ["application/json","application/javascript","application/typescript", "application/xml","application/yaml","application/x-yaml","application/toml", "application/sql","application/graphql"].includes(mime.split(";")[0]); } function buildPrompt(base) { if (!process.env.PROMPT_FILES_PATH) return base; try { const raw = readFileSync(process.env.PROMPT_FILES_PATH, "utf-8"); try { unlinkSync(process.env.PROMPT_FILES_PATH); } catch {} const files = JSON.parse(raw); const fence = String.fromCharCode(96,96,96); const parts = [base]; for (const f of files) { if (isTextMimeType(f.media_type)) { const content = Buffer.from(f.data, "base64").toString("utf-8"); parts.push("\n\nAttached file: " + (f.filename || "unnamed") + "\n" + fence + "\n" + content + "\n" + fence); } else { console.error("[pi] Skipping unsupported file type: " + f.media_type + " (" + (f.filename || "unnamed") + ")"); } } return parts.join(""); } catch { return base; } } if (process.env.JSON_SCHEMA) { console.error("[pi] Warning: JSON_SCHEMA is not supported by the Pi harness"); } function agentOptions() { if (!process.env.AGENT_OPTIONS) return {}; try { const opts = JSON.parse(process.env.AGENT_OPTIONS); console.error("[pi] Agent options applied: " + Object.keys(opts).join(", ")); return opts; } catch (e) { console.error("[pi] Warning: Failed to parse AGENT_OPTIONS: " + e.message); return {}; } } // Parse "provider/model-id" → getModel(provider, modelId) function resolveModel(str) { const slash = str.indexOf("/"); if (slash !== -1) { return getModel(str.slice(0, slash), str.slice(slash + 1)); } return getModel("anthropic", str); } try { process.chdir(WORK_DIR); await mkdir(sessionDir, { recursive: true }); const model = resolveModel(modelStr); const fullPrompt = buildPrompt(prompt); const extraOpts = agentOptions(); const { urls: mcpUrls } = loadMcpServers(); // Each session gets its own agentDir so continueRecent() is scoped to it const { session } = await createAgentSession({ model, workingDir: WORK_DIR, agentDir: sessionDir, sessionManager: SessionManager.continueRecent(WORK_DIR, sessionDir), ...(mcpUrls.length ? { extensionUrls: mcpUrls } : {}), ...extraOpts, }); emit("tool", { name: "pi_agent", toolCallId: sessionId, input: { model: modelStr } }); let output = ""; let inputTokens = 0; let outputTokens = 0; let cachedInputTokens = 0; let totalCostUSD = 0; // Pi attaches usage to each AssistantMessage as { input, output, cacheRead, // cacheWrite, cost: { total } }. We sum across all assistant messages // produced in this turn (the agent may loop with tool calls). ``` -------------------------------- ### Fan-out from a Single State (TypeScript) Source: https://upstash.com/docs/box/overall/snapshots Clone a repository once, create a snapshot, and then spawn multiple boxes from this snapshot to run different agents or prompts in parallel from the same starting point. ```typescript import { Agent, Box } from "@upstash/box" const seed = await Box.create({ runtime: "node", git: { token: process.env.GITHUB_TOKEN }, }) await seed.git.clone({ repo: "github.com/your-org/monorepo" }) const snap = await seed.snapshot({ name: "repo-cloned" }) await seed.delete() const [security, performance, docs] = await Promise.all([ Box.fromSnapshot(snap.id), Box.fromSnapshot(snap.id), Box.fromSnapshot(snap.id), ]) await Promise.all([ security.agent.run({ prompt: "Audit src/ for SQL injection vulnerabilities" }), performance.agent.run({ prompt: "Profile the hot paths in src/api/ and optimize" }), docs.agent.run({ prompt: "Generate API documentation for all public exports" }), ]) ``` -------------------------------- ### Manage Upstash Box Schedules Source: https://upstash.com/docs/box/overall/schedules Provides examples for listing, pausing, resuming, and deleting schedules. Ensure you have a valid `box` instance initialized. ```typescript const schedules = await box.schedule.list() for (const s of schedules) { console.log(`${s.id} — ${s.type} — ${s.cron} — ${s.status}`) } // Pause a schedule await box.schedule.pause(schedules[0].id) // Resume it later await box.schedule.resume(schedules[0].id) // Remove a specific schedule await box.schedule.delete(schedules[0].id) ``` ```python schedules = box.schedule.list() for s in schedules: print(f"{s.id} — {s.type} — {s.cron} — {s.status}") # Pause a schedule box.schedule.pause(schedules[0].id) # Resume it later box.schedule.resume(schedules[0].id) # Remove a specific schedule box.schedule.delete(schedules[0].id) ``` -------------------------------- ### Expose Agent-Built App with Public URL (Python) Source: https://upstash.com/docs/box/overall/preview Exposes an application built by an agent to a public URL. This example demonstrates setting up an Express server and then making it accessible externally. Ensure you have the necessary API keys configured. ```python import os from upstash_box import Box, Agent box = Box.create( runtime="node", agent={ "harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-opus-4-6", "api_key": os.environ["ANTHROPIC_API_KEY"], }, ) box.agent.run( prompt=""" Create a simple Express web server that: - Listens on port 3000 - Has a / route that returns "Hello World" - Has a /health route that returns {"status": "ok"} - Start the server in the background """, ) public_url = box.get_public_url(3000) print(f"Public URL available at: {public_url.url}") import httpx response = httpx.get(f"{public_url.url}/health") print(response.json()) # {"status": "ok"} ``` -------------------------------- ### Configure Hermes Auto-Restart Source: https://upstash.com/docs/box/guides/hermes-setup Set this command as an init script in the Upstash Console to ensure the Hermes gateway starts automatically when the box boots up. It redirects output to gateway.log. ```bash hermes gateway start > gateway.log 2>&1 & ``` -------------------------------- ### Manage Init Command for Keep-Alive Box (Python) Source: https://upstash.com/docs/box/overall/keep-alive Manage the init command for an existing keep-alive box, including setting, getting, and deleting it. Init command management is only available when 'keep_alive' is enabled. ```python box.set_init_command("npm run dev") command = box.get_init_command() box.delete_init_command() print(box.keep_alive) # True ``` -------------------------------- ### Fast Code Review Summary with OpenCode Source: https://upstash.com/docs/box/overall/agent Use OpenCode for concise reviews or summaries of existing git diffs or repository states. This example reviews a git diff. ```tsx const run = await box.agent.run({ prompt: ` Review the current git diff and return: - the top 3 risks - missing test coverage - whether the change looks safe to merge `, }) console.log(run.result) console.log(run.cost.totalUsd) ``` ```python run = box.agent.run( prompt=""" Review the current git diff and return: - the top 3 risks - missing test coverage - whether the change looks safe to merge """, ) print(run.result) print(run.cost.total_usd) ``` -------------------------------- ### Snapshot and restore a box Source: https://upstash.com/docs/box/overall/how-it-works Create a snapshot of a box's current state to use as a reusable starting point or checkpoint. Restore a box from a previously created snapshot. ```APIDOC ## Snapshot and restore ### Description Snapshots are the best way to turn a prepared environment into a reusable starting point, especially for installing dependencies. This is useful for reusable base environments, checkpoints before risky work, and branching multiple boxes from the same setup state. ### TypeScript ```typescript const snapshot = await box.snapshot({ name: "after-setup" }) const restored = await Box.fromSnapshot(snapshot.id) ``` ### Python ```python snapshot = box.snapshot(name="after-setup") restored = Box.from_snapshot(snapshot.id) ``` ``` -------------------------------- ### Write and Run Custom Agent in Box Source: https://upstash.com/docs/box/overall/custom-agent These code snippets demonstrate how to write the custom agent source code to a file within the Box environment and then execute it. The examples show the process in both TypeScript and Python, allowing you to choose your preferred scripting language. ```typescript await box.files.write({ path: "custom-anthropic-agent.mjs", content: agentSource, }) const result = await box.agent.run({ prompt: "Say hello from my custom agent", }) console.log(result.result) ``` ```python box.files.write( path="custom-anthropic-agent.mjs", content=agent_source, ) result = box.agent.run(prompt="Say hello from my custom agent") print(result.result) ``` -------------------------------- ### Expose Agent-Built App with Public URL Source: https://upstash.com/docs/box/overall/preview Exposes an application built by an agent to a public URL. This example demonstrates setting up an Express server and then making it accessible externally. Ensure you have the necessary API keys configured. ```typescript import { Agent, Box } from "@upstash/box" const box = await Box.create({ runtime: "node", agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-opus-4-6", apiKey: process.env.ANTHROPIC_API_KEY, }, }) await box.agent.run({ prompt: ` Create a simple Express web server that: - Listens on port 3000 - Has a / route that returns "Hello World" - Has a /health route that returns {"status": "ok"} - Start the server in the background `, }) const publicUrl = await box.getPublicUrl(3000) console.log(`Public URL available at: ${publicUrl.url}`) const response = await fetch(`${publicUrl.url}/health`) console.log(await response.json()) // { status: "ok" } ``` -------------------------------- ### Run OpenClaw Onboarding Source: https://upstash.com/docs/box/guides/openclaw-setup Initiate the interactive OpenClaw onboarding process, which includes setting up providers, authentication, and gateway configuration. The --install-daemon flag ensures the necessary services are set up for continuous operation. ```bash openclaw onboard --install-daemon ``` -------------------------------- ### Run Agent with Response Schema Source: https://upstash.com/docs/box/overall/agent Use `box.agent.run` with a `responseSchema` to get typed output. This example uses Zod for TypeScript and Pydantic for Python. ```typescript import { z } from "zod" const responseSchema = z.object({ customers: z.array( z.object({ name: z.string(), revenue: z.number(), }), ), }) const analysis = await box.agent.run({ prompt: "Analyze /work/report.csv and return top customers by revenue", responseSchema, }) console.log(analysis.result.customers) ``` ```python from pydantic import BaseModel class Customer(BaseModel): name: str revenue: float class Analysis(BaseModel): customers: list[Customer] analysis = box.agent.run( prompt="Analyze /work/report.csv and return top customers by revenue", response_schema=Analysis, ) print(analysis.result.customers) ``` -------------------------------- ### Configure Environment Variables Source: https://upstash.com/docs/box/guides/ai-sdk-code-interpreter Set up your Upstash Box API key and your AI provider's API key in a .env.local file for authentication and access. ```bash UPSTASH_BOX_API_KEY=box_xxxxxxxxxxxxxxxxxxxxxxxx ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxx ``` -------------------------------- ### Run Scrape Job from Snapshot Source: https://upstash.com/docs/box/guides/web-scraping-playwright Initialize a Box from a pre-existing snapshot to immediately start scraping tasks. This avoids the time-consuming installation of Playwright and its dependencies on each run. ```typescript import { Box } from "@upstash/box" const box = await Box.fromSnapshot(process.env.PLAYWRIGHT_SNAPSHOT_ID!) const run = await box.agent.run({ prompt: "Navigate to and extract ...", }) await box.delete() ``` -------------------------------- ### Run Build and Extract Artifacts (TypeScript) Source: https://upstash.com/docs/box/overall/shell Upload source files, execute a build command, and then download the build artifacts. This snippet is useful for CI/CD pipelines. Ensure the Box is created with the appropriate runtime. ```typescript import { Agent, Box } from "@upstash/box" const box = await Box.create({ runtime: "node" }) await box.files.upload([ { path: "./src", destination: "/work/src" }, { path: "./package.json", destination: "/work/package.json" }, ]) await box.exec.command("cd /work && npm install && npm run build") await box.files.download({ folder: "/work/dist" }) await box.delete() ``` -------------------------------- ### Set Init Command for Keep-Alive Box (TypeScript) Source: https://upstash.com/docs/box/overall/keep-alive Configure an 'initCommand' to run automatically when a keep-alive box starts. This is useful for starting web servers or preparing agent environments. ```typescript const box = await Box.create({ runtime: "node", keepAlive: true, initCommand: "npm install && npm run dev", }) ``` -------------------------------- ### Configure OpenCode Agent in Python Source: https://upstash.com/docs/box/overall/agent Initialize the Box SDK with the OpenCode agent. Ensure OPENCODE_API_KEY is set in your environment variables. ```python import os from upstash_box import Box, Agent box = Box.create( runtime="node", agent={ "harness": Agent.OPEN_CODE, "model": "opencode/claude-sonnet-4-6", "api_key": os.environ["OPENCODE_API_KEY"], }, ) ``` -------------------------------- ### Initialize and Configure Custom Agent Box Source: https://upstash.com/docs/box/overall/custom-harness/pi Sets up a new Box instance with a custom agent harness, specifying the model and command to run the agent. It also configures environment variables for different AI providers. ```javascript const box = await Box.create({ apiKey: process.env.UPSTASH_BOX_API_KEY!, baseUrl: process.env.UPSTASH_BOX_BASE_URL, runtime: "node", agent: { harness: Agent.Custom, model: "anthropic/claude-sonnet-4-5", customHarness: { command: "node", args: ["/workspace/home/custom-pi-agent.mjs"], protocol: "box-sse-v1", }, }, env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY ?? "", GEMINI_API_KEY: process.env.GEMINI_API_KEY ?? "", OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? "", }, }); console.log(`Created box: ${box.id}`); ``` -------------------------------- ### Create a Custom Agent Box in Python Source: https://upstash.com/docs/box/overall/custom-agent This Python code demonstrates how to set up an Upstash Box with a custom agent. It requires specifying the agent harness, model, and the command to run for the custom harness, along with necessary environment variables. ```python import os from upstash_box import Agent, Box box = Box.create( api_key=os.environ["UPSTASH_BOX_API_KEY"], runtime="node", agent={ "harness": Agent.CUSTOM, "model": "claude-haiku-4-5-20251001", "custom_harness": { "command": "node", "args": ["/workspace/home/custom-anthropic-agent.mjs"], "protocol": "box-sse-v1", }, }, env={ "ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"], }, ) ``` -------------------------------- ### Restore from a Snapshot Source: https://upstash.com/docs/box/overall/snapshots Provision a new box from a snapshot using `Box.from_snapshot()`. This creates an identical copy of the box at the time of the snapshot. You can also provide creation options like a name. ```python restored = Box.from_snapshot(snapshot.id) # Box.from_snapshot accepts creation options such as name: named = Box.from_snapshot(snapshot.id, name="restored-worker") files = restored.files.list("/work") print(files) ``` -------------------------------- ### Retrieve logs Source: https://upstash.com/docs/box/overall/shell Get the full timestamped output of a command after it has finished, useful for debugging and auditing. ```APIDOC ## Retrieve logs After a command finishes, call `logs()` to get the full timestamped output for debugging or auditing. ### Example ```typescript const run = await box.exec.command("npm test") const logs = await run.logs() console.log(logs) // [ // { timestamp: "2026-02-23T...", level: "info", message: "PASS src/auth.test.ts" }, // { timestamp: "2026-02-23T...", level: "info", message: "Tests: 12 passed, 12 total" }, // ] ``` ``` -------------------------------- ### Read File Content from Box Source: https://upstash.com/docs/box/overall/files Read the contents of a file as a string. The content can then be parsed, for example, as JSON. ```typescript const content = await box.files.read("/work/output.json") console.log(JSON.parse(content)) ``` ```python import json content = box.files.read("/work/output.json") print(json.loads(content)) ``` -------------------------------- ### Run Build and Extract Artifacts (Python) Source: https://upstash.com/docs/box/overall/shell This Python snippet uploads source files, runs a build command, and downloads the resulting artifacts. It's suitable for build processes. The Box is initialized with a specified runtime. ```python from upstash_box import Box box = Box.create(runtime="node") box.files.upload([ {"path": "./src", "destination": "/work/src"}, {"path": "./package.json", "destination": "/work/package.json"}, ]) box.exec.command("cd /work && npm install && npm run build") box.files.download(folder="/work/dist") box.delete() ``` -------------------------------- ### Stream Agent Response Source: https://upstash.com/docs/box/overall/agent Use `box.agent.stream` to get a streaming response from the agent. Options like `effort` and `maxTurns` can be configured. ```typescript const stream = await box.agent.stream({ prompt: "Review the latest git diff and summarize risks", options: { effort: "high", maxTurns: 20, }, }) ``` ```python stream = box.agent.stream( prompt="Review the latest git diff and summarize risks", options={ "effort": "high", "max_turns": 20, }, ) ``` -------------------------------- ### Create an Ephemeral Box (Python) Source: https://upstash.com/docs/box/overall/ephemeral-box Use EphemeralBox.create to initialize a short-lived sandbox. Specify the runtime, TTL, and optionally a name and network policy. The box is ready immediately upon creation. ```python from upstash_box import EphemeralBox box = EphemeralBox.create( runtime="node", # "node" | "python" | "golang" | "ruby" | "rust" ttl=3600, # seconds, max 259200 (3 days), default 259200 name="my-ephemeral-worker", # optional network_policy={"mode": "allow-all"}, # optional ) ``` -------------------------------- ### Get Git Diff Source: https://upstash.com/docs/box/overall/git Returns the current Git diff as a string. This is useful for displaying patches or reviewing changes made by an agent. ```APIDOC ## Get Git Diff Returns the current Git diff as a string. ### Description Useful to display a patch in your UI and review what an agent changed. ``` -------------------------------- ### Warm Up an Upstash Box Source: https://upstash.com/docs/box/guides/crabbox-setup Provision a remote box with the specified runtime and size. This command prepares the box for subsequent operations. ```bash crabbox warmup --provider upstash-box --upstash-box-runtime node --upstash-box-size small ``` -------------------------------- ### Get Git Status Source: https://upstash.com/docs/box/overall/git Returns the Git status output for the repository in the current working directory. This helps in identifying changed and untracked files. ```APIDOC ## Get Git Status Returns the Git status output for the repository in the current working directory. ### Description See what files changed and if there are any untracked files. ``` -------------------------------- ### Get Git Diff with Box Source: https://upstash.com/docs/box/overall/git Returns the current Git diff as a string. This is useful for displaying patches or reviewing changes made by an agent. ```typescript const diff = await box.git.diff() ``` ```python diff = box.git.diff() ``` -------------------------------- ### Restore Box from Snapshot with Size Configuration Source: https://upstash.com/docs/box/overall/how-it-works Restore a box from a snapshot while specifying a different size configuration. This allows for flexible environment setup. ```typescript const box = await Box.fromSnapshot("snap_abc123", { size: "medium" }) ``` ```python box = Box.from_snapshot("snap_abc123", size="medium") ``` -------------------------------- ### Box size configuration Source: https://upstash.com/docs/box/overall/how-it-works Configure the resource size (CPU and Memory) of a box at creation time. Supported sizes are 'small', 'medium', and 'large'. ```APIDOC ## Box size ### Description Boxes have configurable resource sizes, set at creation time via the `size` option. Defaults to `"small"`. | Size | CPU | Memory | | -------- | ------- | ------ | | `small` | 2 cores | 4 GB | | `medium` | 4 cores | 8 GB | | `large` | 8 cores | 16 GB | ### TypeScript ```typescript const box = await Box.create({ size: "large", agent: { harness: Agent.ClaudeCode, model: "anthropic/claude-sonnet-4-5" }, }) console.log(box.size) // "large" ``` ### Python ```python box = Box.create( size="large", agent={"harness": Agent.CLAUDE_CODE, "model": "anthropic/claude-sonnet-4-5"}, ) print(box.size) # "large" ``` ### From Snapshot Also supported in `Box.fromSnapshot()`: ### TypeScript ```typescript const box = await Box.fromSnapshot("snap_abc123", { size: "medium" }) ``` ### Python ```python box = Box.from_snapshot("snap_abc123", size="medium") ``` ``` -------------------------------- ### Convert Image to Grayscale with Pillow Source: https://upstash.com/docs/box/guides/tanstack-ai-file-editor Use this snippet to convert an image to grayscale using the Pillow library. Ensure the Pillow library is installed in your environment. ```python from PIL import Image img = Image.open("/workspace/home/photo.png").convert("L") img.save("/workspace/home/out/photo.png") print("converted to grayscale") ``` -------------------------------- ### Troubleshoot SSH Connection Freezes Source: https://upstash.com/docs/box/guides/openclaw-setup If your SSH session freezes during onboarding, use this command to retry the connection with a clean configuration and disabled control master. This bypasses local SSH configurations and uses periodic keepalives to maintain the connection. ```bash ssh -F /dev/null -o ControlMaster=no -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -L 18789:127.0.0.1:18789 @us-east-1.box.upstash.com ``` -------------------------------- ### Get a schedule Source: https://upstash.com/docs/box/overall/schedules Retrieve a single schedule by its ID. The response includes details about the schedule's type, status, cron expression, and other configuration options. ```APIDOC ## GET /schedule/{schedule_id} ### Description Retrieve a single schedule by ID. ### Method GET ### Endpoint /schedule/{schedule_id} ### Parameters #### Path Parameters - **schedule_id** (string) - Required - The ID of the schedule to retrieve. ### Response #### Success Response (200) - **id** (string) - The unique identifier for the schedule. - **box_id** (string) - The ID of the box this schedule belongs to. - **type** (string) - The type of the schedule, either "exec" or "prompt". - **cron** (string) - The cron expression defining the schedule's execution time. - **command** (array of strings) - Present when type is "exec". The command to execute. - **prompt** (string) - Present when type is "prompt". The prompt to use. - **folder** (string) - The folder associated with the schedule. - **model** (string) - The model to use for the schedule. - **agent_options** (object) - Additional options for the agent. - **timeout** (number) - The timeout for the schedule execution in seconds. - **status** (string) - The current status of the schedule, "active", "paused", or "deleted". - **webhook_url** (string) - The URL for webhook notifications. - **webhook_headers** (object) - Headers for webhook notifications. - **last_run_at** (number) - Timestamp of the last successful run. - **last_run_status** (string) - Status of the last run: "completed", "failed", or "skipped". - **last_run_id** (string) - The ID of the last run. - **total_runs** (number) - The total number of times the schedule has run. - **total_failures** (number) - The total number of failures for the schedule. - **created_at** (number) - Timestamp when the schedule was created. - **updated_at** (number) - Timestamp when the schedule was last updated. ### Response Example ```json { "id": "schedule_abc123", "box_id": "box_xyz789", "type": "exec", "cron": "0 0 * * *", "command": ["echo", "hello"], "status": "active", "total_runs": 10, "total_failures": 0, "created_at": 1678886400, "updated_at": 1678886400 } ``` ``` -------------------------------- ### Get Git Repository Status with Box Source: https://upstash.com/docs/box/overall/git Retrieves the Git status output for the current working directory. This is useful for seeing changed or untracked files. ```typescript const status = await box.git.status() ``` ```python status = box.git.status() ``` -------------------------------- ### Structured Analysis with Codex Source: https://upstash.com/docs/box/overall/agent Use Codex for strongly structured responses that can be fed into another system. This example analyzes a CSV and returns top customers. ```tsx import { z } from "zod" const result = await box.agent.run({ prompt: "Analyze /work/report.csv and return the top 10 customers by revenue", responseSchema: z.object({ customers: z.array( z.object({ name: z.string(), revenue: z.number(), }), ), }), }) console.log(result.result.customers) ``` ```python from pydantic import BaseModel class Customer(BaseModel): name: str revenue: float class Result(BaseModel): customers: list[Customer] result = box.agent.run( prompt="Analyze /work/report.csv and return the top 10 customers by revenue", response_schema=Result, ) print(result.result.customers) ``` -------------------------------- ### Run Tests with bun Source: https://upstash.com/docs/box/guides/crabbox-setup Execute your test suite using bun within the remote box. Environment variables from a local .env file are automatically injected. ```bash crabbox run --provider upstash-box --env-from-profile .env -- bun test ```