diff --git a/examples/computesdk/src/computesdk.ts b/examples/computesdk/src/computesdk.ts index 46f43d6..21ca596 100644 --- a/examples/computesdk/src/computesdk.ts +++ b/examples/computesdk/src/computesdk.ts @@ -10,7 +10,7 @@ import { type ProviderName, } from "computesdk"; import { SandboxAgent } from "sandbox-agent"; -import { detectAgent, buildInspectorUrl } from "@sandbox-agent/example-shared"; +import { detectAgent, buildInspectorUrl, generateInstallCommand, type SandboxAgentComponent } from "@sandbox-agent/example-shared"; import { fileURLToPath } from "node:url"; import { resolve } from "node:path"; @@ -90,18 +90,12 @@ export async function setupComputeSdkSandboxAgent(): Promise<{ return result; }; + const components: SandboxAgentComponent[] = []; + if (env.ANTHROPIC_API_KEY) components.push("claude"); + if (env.OPENAI_API_KEY) components.push("codex"); + console.log("Installing sandbox-agent..."); - await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh"); - - if (env.ANTHROPIC_API_KEY) { - console.log("Installing Claude agent..."); - await run("sandbox-agent install-agent claude"); - } - - if (env.OPENAI_API_KEY) { - console.log("Installing Codex agent..."); - await run("sandbox-agent install-agent codex"); - } + await run(generateInstallCommand({ components })); console.log("Starting server..."); await run(`sandbox-agent server --no-token --host 0.0.0.0 --port ${PORT}`, { background: true }); diff --git a/examples/daytona/src/daytona-with-snapshot.ts b/examples/daytona/src/daytona-with-snapshot.ts index 661d303..117cd0e 100644 --- a/examples/daytona/src/daytona-with-snapshot.ts +++ b/examples/daytona/src/daytona-with-snapshot.ts @@ -1,6 +1,6 @@ import { Daytona, Image } from "@daytonaio/sdk"; import { SandboxAgent } from "sandbox-agent"; -import { detectAgent, buildInspectorUrl } from "@sandbox-agent/example-shared"; +import { detectAgent, buildInspectorUrl, generateInstallCommand } from "@sandbox-agent/example-shared"; const daytona = new Daytona(); @@ -11,7 +11,7 @@ if (process.env.OPENAI_API_KEY) envVars.OPENAI_API_KEY = process.env.OPENAI_API_ // Build a custom image with sandbox-agent pre-installed (slower first run, faster subsequent runs) const image = Image.base("ubuntu:22.04").runCommands( "apt-get update && apt-get install -y curl ca-certificates", - "curl -fsSL https://releases.rivet.dev/sandbox-agent/0.3.x/install.sh | sh", + generateInstallCommand(), ); console.log("Creating Daytona sandbox (first run builds the base image and may take a few minutes, subsequent runs are fast)..."); diff --git a/examples/daytona/src/index.ts b/examples/daytona/src/index.ts index 09f4cff..9f18426 100644 --- a/examples/daytona/src/index.ts +++ b/examples/daytona/src/index.ts @@ -1,6 +1,6 @@ import { Daytona } from "@daytonaio/sdk"; import { SandboxAgent } from "sandbox-agent"; -import { detectAgent, buildInspectorUrl } from "@sandbox-agent/example-shared"; +import { detectAgent, buildInspectorUrl, generateInstallCommand } from "@sandbox-agent/example-shared"; const daytona = new Daytona(); @@ -14,11 +14,7 @@ const sandbox = await daytona.create({ envVars, autoStopInterval: 0 }); // Install sandbox-agent and start server console.log("Installing sandbox-agent..."); -await sandbox.process.executeCommand("curl -fsSL https://releases.rivet.dev/sandbox-agent/0.3.x/install.sh | sh"); - -console.log("Installing agents..."); -await sandbox.process.executeCommand("sandbox-agent install-agent claude"); -await sandbox.process.executeCommand("sandbox-agent install-agent codex"); +await sandbox.process.executeCommand(generateInstallCommand({ components: ["claude", "codex"] })); await sandbox.process.executeCommand("nohup sandbox-agent server --no-token --host 0.0.0.0 --port 3000 >/tmp/sandbox-agent.log 2>&1 &"); diff --git a/examples/docker/src/index.ts b/examples/docker/src/index.ts index c6f29c2..115ceda 100644 --- a/examples/docker/src/index.ts +++ b/examples/docker/src/index.ts @@ -2,7 +2,7 @@ import Docker from "dockerode"; import fs from "node:fs"; import path from "node:path"; import { SandboxAgent } from "sandbox-agent"; -import { detectAgent, buildInspectorUrl } from "@sandbox-agent/example-shared"; +import { detectAgent, buildInspectorUrl, generateInstallCommand } from "@sandbox-agent/example-shared"; const IMAGE = "node:22-bookworm-slim"; const PORT = 3000; @@ -35,7 +35,7 @@ const container = await docker.createContainer({ "apt-get update", "DEBIAN_FRONTEND=noninteractive apt-get install -y curl ca-certificates bash libstdc++6", "rm -rf /var/lib/apt/lists/*", - "curl -fsSL https://releases.rivet.dev/sandbox-agent/0.3.x/install.sh | sh", + generateInstallCommand(), `sandbox-agent server --no-token --host 0.0.0.0 --port ${PORT}`, ].join(" && "), ], diff --git a/examples/e2b/src/index.ts b/examples/e2b/src/index.ts index 7dd2882..a646f4c 100644 --- a/examples/e2b/src/index.ts +++ b/examples/e2b/src/index.ts @@ -1,6 +1,6 @@ import { Sandbox } from "@e2b/code-interpreter"; import { SandboxAgent } from "sandbox-agent"; -import { detectAgent, buildInspectorUrl } from "@sandbox-agent/example-shared"; +import { detectAgent, buildInspectorUrl, generateInstallCommand } from "@sandbox-agent/example-shared"; const envs: Record = {}; if (process.env.ANTHROPIC_API_KEY) envs.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; @@ -16,11 +16,7 @@ const run = async (cmd: string) => { }; console.log("Installing sandbox-agent..."); -await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/0.3.x/install.sh | sh"); - -console.log("Installing agents..."); -await run("sandbox-agent install-agent claude"); -await run("sandbox-agent install-agent codex"); +await run(generateInstallCommand({ components: ["claude", "codex"] })); console.log("Starting server..."); await sandbox.commands.run("sandbox-agent server --no-token --host 0.0.0.0 --port 3000", { background: true, timeoutMs: 0 }); diff --git a/examples/shared/src/sandbox-agent-client.ts b/examples/shared/src/sandbox-agent-client.ts index 8efec19..0e67e5c 100644 --- a/examples/shared/src/sandbox-agent-client.ts +++ b/examples/shared/src/sandbox-agent-client.ts @@ -3,6 +3,25 @@ * Provides minimal helpers for connecting to and interacting with sandbox-agent servers. */ +export const SANDBOX_AGENT_INSTALL_VERSION = "0.3.1"; + +export type SandboxAgentComponent = "claude" | "codex" | "opencode" | "amp"; + +export function generateInstallCommand({ + version = SANDBOX_AGENT_INSTALL_VERSION, + components = [], +}: { + version?: string; + components?: SandboxAgentComponent[]; +} = {}): string { + const uniqueComponents = [...new Set(components)]; + + return [ + `curl -fsSL https://releases.rivet.dev/sandbox-agent/${version}/install.sh | sh`, + ...uniqueComponents.map((component) => `sandbox-agent install-agent ${component}`), + ].join(" && "); +} + function normalizeBaseUrl(baseUrl: string): string { return baseUrl.replace(/\/+$/, ""); } diff --git a/examples/vercel/src/index.ts b/examples/vercel/src/index.ts index 4a63bfc..336b345 100644 --- a/examples/vercel/src/index.ts +++ b/examples/vercel/src/index.ts @@ -1,6 +1,6 @@ import { Sandbox } from "@vercel/sandbox"; import { SandboxAgent } from "sandbox-agent"; -import { detectAgent, buildInspectorUrl } from "@sandbox-agent/example-shared"; +import { detectAgent, buildInspectorUrl, generateInstallCommand } from "@sandbox-agent/example-shared"; const envs: Record = {}; if (process.env.ANTHROPIC_API_KEY) envs.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; @@ -22,11 +22,7 @@ const run = async (cmd: string, args: string[] = []) => { }; console.log("Installing sandbox-agent..."); -await run("sh", ["-c", "curl -fsSL https://releases.rivet.dev/sandbox-agent/0.3.x/install.sh | sh"]); - -console.log("Installing agents..."); -await run("sandbox-agent", ["install-agent", "claude"]); -await run("sandbox-agent", ["install-agent", "codex"]); +await run("sh", ["-c", generateInstallCommand({ components: ["claude", "codex"] })]); console.log("Starting server..."); await sandbox.runCommand({