@@ -10,6 +10,13 @@ class SandboxPreset:
1010 Attributes:
1111 name: Human-readable preset name.
1212 description: What this preset provides.
13+ image: Pre-built OCI container image for docker/daytona/modal backends
14+ (skips setup_commands if the backend supports images).
15+ tensorlake_image: Tensorlake project-scoped image name. Tensorlake
16+ doesn't accept arbitrary OCI URLs, so this is a separate field.
17+ Users register a project image with `tl sbx image build` (our
18+ Dockerfiles under images/ can be used as-is) and then set this.
19+ When set, setup_commands are skipped on the Tensorlake backend.
1320 setup_commands: Shell commands run after sandbox creation (in order).
1421 cpu: Minimum recommended vCPUs.
1522 memory_mb: Minimum recommended RAM in MB.
@@ -20,6 +27,8 @@ class SandboxPreset:
2027
2128 name : str
2229 description : str
30+ image : str | None = None
31+ tensorlake_image : str | None = None
2332 setup_commands : list [str ] = field (default_factory = list )
2433 cpu : float = 1.0
2534 memory_mb : int = 1024
@@ -49,11 +58,21 @@ def get_preset(name: str) -> SandboxPreset:
4958 return PRESETS [name ]
5059
5160
61+ # -- Constants -------------------------------------------------------------
62+
63+ IMAGE_REGISTRY = "ghcr.io/bespokelabsai/sandbox"
64+
65+ # Pinned tag for preset images. Bump to cut a new immutable image set,
66+ # then run the build-images workflow_dispatch with the same tag value.
67+ # Never use ":latest" here — it's not reproducible.
68+ PRESET_IMAGE_TAG = "v1"
69+
5270# -- Built-in presets ------------------------------------------------------
5371
5472register_preset (SandboxPreset (
5573 name = "claude-code" ,
5674 description = "Sandbox with Claude Code (Anthropic CLI) installed" ,
75+ image = f"{ IMAGE_REGISTRY } /claude-code:{ PRESET_IMAGE_TAG } " ,
5776 setup_commands = [
5877 "npm install -g @anthropic-ai/claude-code" ,
5978 ],
@@ -64,6 +83,7 @@ def get_preset(name: str) -> SandboxPreset:
6483register_preset (SandboxPreset (
6584 name = "claude-sdk" ,
6685 description = "Sandbox with Claude Agent SDK and bundled Claude Code CLI" ,
86+ image = f"{ IMAGE_REGISTRY } /claude-sdk:{ PRESET_IMAGE_TAG } " ,
6787 setup_commands = [
6888 "pip install claude-agent-sdk" ,
6989 ],
@@ -74,6 +94,7 @@ def get_preset(name: str) -> SandboxPreset:
7494register_preset (SandboxPreset (
7595 name = "codex" ,
7696 description = "Sandbox with Codex CLI installed" ,
97+ image = f"{ IMAGE_REGISTRY } /codex:{ PRESET_IMAGE_TAG } " ,
7798 setup_commands = [
7899 "npm install -g @openai/codex" ,
79100 ],
@@ -84,6 +105,7 @@ def get_preset(name: str) -> SandboxPreset:
84105register_preset (SandboxPreset (
85106 name = "python-data-science" ,
86107 description = "Python with numpy, pandas, matplotlib, scikit-learn" ,
108+ image = f"{ IMAGE_REGISTRY } /python-data-science:{ PRESET_IMAGE_TAG } " ,
87109 setup_commands = [
88110 "pip install numpy pandas matplotlib scikit-learn" ,
89111 ],
@@ -101,6 +123,7 @@ def get_preset(name: str) -> SandboxPreset:
101123register_preset (SandboxPreset (
102124 name = "web-dev" ,
103125 description = "Node.js with common web development tools" ,
126+ image = f"{ IMAGE_REGISTRY } /web-dev:{ PRESET_IMAGE_TAG } " ,
104127 setup_commands = [
105128 "npm install -g typescript ts-node prettier eslint" ,
106129 ],
@@ -110,6 +133,7 @@ def get_preset(name: str) -> SandboxPreset:
110133register_preset (SandboxPreset (
111134 name = "python-ml" ,
112135 description = "Python with PyTorch and common ML libraries" ,
136+ image = f"{ IMAGE_REGISTRY } /python-ml:{ PRESET_IMAGE_TAG } " ,
113137 setup_commands = [
114138 "pip install torch transformers datasets accelerate" ,
115139 ],
0 commit comments