From 524f40ec02b9e0fbd634cc6887d2b5deee425498 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Tue, 17 Mar 2026 16:54:20 -0700 Subject: [PATCH] feat(providers): simplify modal to use published base image The `-full` base image already includes sandbox-agent and all agents pre-installed. Remove redundant apt-get, install script, and install-agent dockerfile commands from the Modal provider. Also allow overriding the default image via SANDBOX_AGENT_IMAGE env var across all providers for testing with different published versions. Co-Authored-By: Claude Opus 4.6 --- sdks/typescript/src/providers/modal.ts | 16 +++++----------- sdks/typescript/src/providers/shared.ts | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/sdks/typescript/src/providers/modal.ts b/sdks/typescript/src/providers/modal.ts index 4e193c8..4d5b39f 100644 --- a/sdks/typescript/src/providers/modal.ts +++ b/sdks/typescript/src/providers/modal.ts @@ -1,11 +1,10 @@ import { ModalClient, type Image, type SandboxCreateParams } from "modal"; import type { SandboxProvider } from "./types.ts"; -import { DEFAULT_AGENTS, SANDBOX_AGENT_INSTALL_SCRIPT } from "./shared.ts"; +import { DEFAULT_SANDBOX_AGENT_IMAGE } from "./shared.ts"; const DEFAULT_AGENT_PORT = 3000; const DEFAULT_APP_NAME = "sandbox-agent"; const DEFAULT_MEMORY_MIB = 2048; -const DEFAULT_BASE_IMAGE = "node:22-slim"; type ModalCreateOverrides = Omit, "secrets" | "encryptedPorts"> & { secrets?: Record; @@ -33,17 +32,12 @@ export function modal(options: ModalProviderOptions = {}): SandboxProvider { async create(): Promise { const createOpts = await resolveCreateOptions(options.create); const appName = createOpts.appName ?? DEFAULT_APP_NAME; - const baseImage = options.image ?? DEFAULT_BASE_IMAGE; + const baseImage = options.image ?? DEFAULT_SANDBOX_AGENT_IMAGE; const app = await client.apps.fromName(appName, { createIfMissing: true }); - // Pre-install sandbox-agent and agents in the image so they are cached - // across sandbox creates and don't need to be installed at runtime. - const installAgentCmds = DEFAULT_AGENTS.map((agent) => `RUN sandbox-agent install-agent ${agent}`); - const image = (typeof baseImage === "string" ? client.images.fromRegistry(baseImage) : baseImage).dockerfileCommands([ - "RUN apt-get update && apt-get install -y curl ca-certificates && rm -rf /var/lib/apt/lists/*", - `RUN curl -fsSL ${SANDBOX_AGENT_INSTALL_SCRIPT} | sh`, - ...installAgentCmds, - ]); + // The default `-full` base image already includes sandbox-agent and all + // agents pre-installed, so no additional dockerfile commands are needed. + const image = typeof baseImage === "string" ? client.images.fromRegistry(baseImage) : baseImage; const envVars = createOpts.secrets ?? {}; const secrets = Object.keys(envVars).length > 0 ? [await client.secrets.fromObject(envVars)] : []; diff --git a/sdks/typescript/src/providers/shared.ts b/sdks/typescript/src/providers/shared.ts index c0f7b1c..100b707 100644 --- a/sdks/typescript/src/providers/shared.ts +++ b/sdks/typescript/src/providers/shared.ts @@ -1,4 +1,4 @@ -export const DEFAULT_SANDBOX_AGENT_IMAGE = "rivetdev/sandbox-agent:0.5.0-rc.1-full"; +export const DEFAULT_SANDBOX_AGENT_IMAGE = process.env.SANDBOX_AGENT_IMAGE ?? "rivetdev/sandbox-agent:0.5.0-rc.1-full"; export const SANDBOX_AGENT_INSTALL_SCRIPT = "https://releases.rivet.dev/sandbox-agent/0.3.x/install.sh"; export const DEFAULT_AGENTS = ["claude", "codex"] as const;