ANSWERED

Q-09: Bun / Pi Install / Model Routing

Status: ANSWERED Agent: opencode/ext-agent Timestamp UTC: 2026-05-11T00:15:00Z Claim: Q-09 | opencode/ext-agent | 2026-05-11T00:05:00Z

Prior Answers Checked

Short Answer

Keep Node.js for the Pi CLI. Do not switch to Bun for Pi agent containers. The current added 256 packages in 14s

34 packages are looking for funding run npm fund for details on Node v22 works. Bun offers no advantage here and introduces aarch64 compatibility risk. Model keys should stay mounted, not baked.

Evidence

Current Container Runtime (verified on relik-pi4)

Host Runtime (verified on relik-pi4)

Q-06 Dockerfile Proposal vs Reality

Q-06 proposed: bun add v1.3.6 (d530ed99)

installed @earendil-works/pi-coding-agent@0.74.0 with binaries: - pi

249 packages installed [4.47s]

Blocked 3 postinstalls. Run bun pm -g untrusted for details. Reality: Container uses changed 256 packages in 6s

34 packages are looking for funding run npm fund for details

These are different packages. The namespace may be a fork or earlier name. The actual running agent is .

Model Key Routing (verified)

Baked into container image as ENV: - FROM_AGENT_MODEL_PROVIDER=minimax - FROM_AGENT_MODEL=MiniMax-M2.7 - FROM_AGENT_FALLBACK_PROVIDER=kimi-coding - FROM_AGENT_FALLBACK_MODEL=kimi-for-coding

Mounted from host as secrets file: - /mnt/kitchen/from-house/secrets/model.env → MINIMAX_API_KEY, MISTRAL_API_KEY, KIMI_API_KEY

Agent loop behavior: The from-d3tui-agent-loop script sources model.env at runtime, then runs . The provider/model selection is in the agent loop script, not in the Pi CLI config. Each container gets a unique FROM_AGENT_ID but shares the same model.env.

Fit For This Pi Workcell

Three Pi Agents

Each agent container runs the same image with different FROM_AGENT_ID env vars. All three share: - Same Node.js runtime - Same Pi CLI version - Same mounted secrets - Same model.env file

The model routing happens at the shell-script level (from-d3tui-agent-loop), not at the Pi CLI level. This is clean — the Pi CLI doesn't need to know about multi-agent routing.

External Agents

External agents (like this session) run outside the containers on the host or on Mac. They don't need Bun or the container runtime. The protocol is file-based (LLM-wiki claims/answers).

One D3-TUI Repo

Bind-mounted into all containers at /from/repos/d3-tui. The Pi CLI works on this directory. No runtime-specific dependency.

Forgejo Issues

The agent loop commits and pushes to Forgejo via SSH (GIT_SSH_COMMAND configured with deploy key). This works with Node.js Pi CLI — no Bun dependency.

LLM-wiki

File-based, no runtime dependency. Any agent can read/write.

Raspberry Pi Constraints

Risks / Failure Modes

If We Switch to Bun

  1. aarch64 compatibility: Bun's aarch64 support has improved but is less mature than Node.js. Edge cases in native modules could cause silent failures.
  2. Package resolution differences: bun add v1.3.6 (d530ed99)

Usage: bun add [flags] <@version> Alias: bun a

Add a new dependency to package.json and install it.

Flags: -c, --config= Specify path to config file (bunfig.toml) -y, --yarn Write a yarn.lock file (yarn v1) -p, --production Don't install devDependencies --no-save Don't update package.json or save a lockfile --save Save to package.json (true by default) --ca= Provide a Certificate Authority signing certificate --cafile= The same as --ca, but is a file path to the certificate --dry-run Perform a dry run without making changes --frozen-lockfile Disallow changes to lockfile -f, --force Always request the latest versions from the registry & reinstall all dependencies --cache-dir= Store & load cached data from a specific directory path --no-cache Ignore manifest cache entirely --silent Don't log anything --quiet Only show tarball name when packing --verbose Excessively verbose logging --no-progress Disable the progress bar --no-summary Don't print a summary --no-verify Skip verifying integrity of newly downloaded packages --ignore-scripts Skip lifecycle scripts in the project's package.json (dependency scripts are never run) --trust Add to trustedDependencies in the project's package.json and install the package(s) -g, --global Install globally --cwd= Set a specific cwd --backend= Platform-specific optimizations for installing dependencies. Possible values: "clonefile" (default), "hardlink", "symlink", "copyfile" --registry= Use a specific registry by default, overriding .npmrc, bunfig.toml and environment variables --concurrent-scripts= Maximum number of concurrent jobs for lifecycle scripts (default 5) --network-concurrency= Maximum number of concurrent network requests (default 48) --save-text-lockfile Save a text-based lockfile --omit= Exclude 'dev', 'optional', or 'peer' dependencies from install --lockfile-only Generate a lockfile without installing dependencies --linker= Linker strategy (one of "isolated" or "hoisted") --minimum-release-age= Only install packages published at least N seconds ago (security feature) --cpu= Override CPU architecture for optional dependencies (e.g., x64, arm64, * for all) --os= Override operating system for optional dependencies (e.g., linux, darwin, * for all) -h, --help Print this help menu -d, --dev Add dependency to "devDependencies" --optional Add dependency to "optionalDependencies" --peer Add dependency to "peerDependencies" -E, --exact Add the exact version instead of the ^range -a, --analyze Recursively analyze & install dependencies of files passed as arguments (using Bun's bundler) --only-missing Only add dependencies to package.json if they are not already present

Examples: Add a dependency from the npm registry bun add zod bun add zod@next bun add zod@3.0.0

Add a dev, optional, or peer dependency bun add -d typescript bun add --optional lodash bun add --peer esbuild

Full documentation is available at https://bun.com/docs/cli/add. may resolve dependencies differently than npm. The @mariozechner/pi-coding-agent package was built and tested with npm. 3. No benefit: The Pi CLI is a Node.js application (dist/cli.js). Running it through Bun's Node compatibility layer adds a translation step for zero gain. 4. Image rebuild cost: Switching runtimes means rebuilding and retesting all container images.

If We Keep Node.js (Recommended)

  1. Known working: Current setup runs without runtime errors.
  2. Larger image: Node.js base image is ~704MB. Bun base would be smaller, but on a 29GB SD card with 18GB free, this is not a constraint.
  3. No hot-reload: npm global install is static. To update Pi version, rebuild image. This is acceptable for MVP.

Model Key Risks

  1. Shared secrets file: All containers mount the same model.env. If one agent consumes all API quota, others are affected.
  2. Keys on disk: model.env is plaintext on the USB drive. Acceptable for local-only Pi, risky if the Pi is exposed beyond tailnet.
  3. No per-agent rate limiting: Three agents hitting MiniMax simultaneously could hit rate limits.

Decision Needed From Mehdi

  1. Pi CLI package name: Current is . Q-06 referenced . Which is canonical? Should we pin to a specific version or track latest?

  2. Per-agent API keys: Should each agent container have its own API key to avoid quota contention? Or is shared keys fine for MVP?

  3. Pi CLI on host: Currently not installed on the host. Should it be? Useful for manual testing outside containers.

  4. Bun for host-side tools only: The d3-opencode-sentinel already uses Bun on the host. Should Bun remain host-only (for TypeScript tooling) while containers stay Node?

Next Probe

Test bun add v1.3.6 (d530ed99)

installed @mariozechner/pi-coding-agent@0.73.1 with binaries: - pi

4 packages installed [1.93s] on the RPi4 host to verify aarch64 compatibility before considering it for containers. If it works, the image size savings (~200MB) could be evaluated against the risk of changing a working setup.