Skip to main content

Runtime Packages

How the Code Interpreter's language runtimes (Python, Node.js, Bun, Bash) and their libraries are packaged into the /pkgs tree, and how to build your own bundle with the downloadable Package Builder Kit.

Every sandbox runs user code against a prebuilt language-runtime tree mounted read-only at SANDBOX_PACKAGES_DIRECTORY (default /pkgs). The tree holds the interpreters (Python, Node.js, Bun, Bash) and the libraries preinstalled into each — everything a job can import or require offline. An empty tree makes every run fail with runtime is unknown, so it must be populated before the Run Code feature works.

Where the tree comes from

The tree is built outside the stack and bind-mounted into the sandbox — it is not baked into any image. See Architecture → Language runtimes for how it's mounted, and Deploy → Components → Code Interpreter for the host path (${STORAGE_ROOT}/code-interpreter-packages).

The Package Builder Kit

The Package Builder Kit is a small, self-contained tool for building your own runtime bundle. You choose the interpreter versions and the exact library list; the kit compiles everything inside a throwaway Docker container and hands you a single .zip you drop into the sandbox packages directory.

Nothing is hardcoded — your whole bundle is described by three editable files, so you can tailor it to exactly the languages and libraries your users need.

FileWhat it controls
config.envRuntime versions (Python / Node.js / Bun / Bash) and on/off toggles
manifests/python-packages.txtThe pip packages to bundle (one per line)
manifests/javascript-packages.txtThe npm/bun packages to bundle (one per line)

Docker + a Linux build host

The kit builds inside a buildpack-deps:bookworm container, so Docker is required. Run it on Linux, WSL, or macOS — the bundle is compiled for the build host's CPU architecture, so build on the same architecture (amd64 or arm64) as your sandbox host. An arm64 bundle will not run on an amd64 host.

Get the kit

Download the kit from the Downloads page, or grab the latest release directly:

curl -LO https://intelliask.mt/api/downloads/package-builder-kit/latest/package-builder-kit.zip
unzip package-builder-kit.zip
cd package-builder-kit

Define your bundle

Edit the three spec files to describe what you want.

config.env — pin the exact releases and toggle whole runtimes on or off:

export PYTHON_VERSION="3.14.4"     # a real python.org release
export NODE_VERSION="24.15.0"      # a real nodejs.org release
export BUN_VERSION="1.3.14"        # a real oven-sh/bun release
 
export SKIP_BUN="1"                # don't bundle Bun at all
export SKIP_PYTHON_PACKAGES="1"    # bundle a bare interpreter, no pip libraries

manifests/python-packages.txt — one pip requirement per line (# comments and blank lines are ignored). Pin versions for reproducible, offline-identical builds:

pandas==2.2.2
numpy
scipy>=1.11,<2

manifests/javascript-packages.txt — one npm spec per line, installed into both the Node.js and Bun runtimes:

zod@4.3.6
lodash

Build

./build-packages.sh                     # build everything -> dist/codeapi-packages.zip
./build-packages.sh --version 1.2.0     # stamp an explicit release version
./build-packages.sh --no-package        # build into data/pkgs, skip the zip

Any config.env value can also be overridden inline for a single run — the command-line value always wins:

PYTHON_VERSION=3.13.2 SKIP_BUN=1 ./build-packages.sh

When it finishes you get dist/codeapi-packages.zip (the runtime tree, under a top-level pkgs/ folder) plus a dist/checksums.txt.

Install into the sandbox

The zip contains a top-level pkgs/ folder whose contents go at the root of the sandbox packages directory — the host path bound to /pkgs (on an IntelliAsk stack that's ${STORAGE_ROOT}/code-interpreter-packages):

unzip codeapi-packages.zip -d /tmp/codeapi
cp -a /tmp/codeapi/pkgs/. "${STORAGE_ROOT}/code-interpreter-packages/"
intelliask restart codeapi-sandbox-runner   # re-scan the runtimes

Anatomy of a package

Each runtime lands in its own versioned folder under the tree:

<packages-dir>/
├── python/3.14.4/
├── node/24.15.0/
├── bun/1.3.14/
└── bash/5.2.0/

Every runtime folder carries the metadata the sandbox needs to discover and launch it:

FilePurpose
pkg-info.jsonLanguage, version, and aliases (e.g. py, py3, python3).
runThe launcher the sandbox invokes to execute code with this runtime.
.envPATH / NODE_PATH / BUN_INSTALL the runtime is launched with.
.package-installedMarker that the libraries finished installing (a timestamp).

Notes & gotchas

  • Match the architecture. Build on the same CPU architecture (amd64 / arm64) as the sandbox host; a mismatched bundle won't run.
  • An empty tree fails closed. Until the tree is populated, every job errors with runtime is unknown — this is expected, not a bug.
  • Two Python pins ship for a reason. markitdown==0.0.2 (0.1.x pulls Magika/ONNX, which segfaults on arm64 under NsJail) and chdb==4.1.6 (ABI stability). Change them only after testing on your target.

Last updated on