Skip to content

[feat] Bake pinned Pi into the Daytona snapshot - #5046

Merged
mmabrouk merged 2 commits into
big-agentsfrom
chore/bake-daytona-harnesses
Jul 10, 2026
Merged

[feat] Bake pinned Pi into the Daytona snapshot#5046
mmabrouk merged 2 commits into
big-agentsfrom
chore/bake-daytona-harnesses

Conversation

@junaway

@junaway junaway commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Context

The Daytona full sandbox-agent base already contains Claude, Codex, and OpenCode plus the Pi ACP adapter, but it does not contain the standalone Pi CLI that pi-acp launches.

Fresh bare images remain reliable by default: with AGENTA_AGENT_SANDBOX_PI_INSTALLED unset or true, the runner installs our pinned Pi version into the new sandbox session. Operators set it to false only when DAYTONA_SNAPSHOT points at a snapshot that already bakes Pi.

Changes

  • rebuild the stale PR on the current big-agents head
  • bake @earendil-works/pi-coding-agent 0.80.6 into agenta-sandbox-pi
  • fail the snapshot build if pi --version does not work
  • verify that the base image still contains the Claude, Codex, and OpenCode binaries
  • keep the session-time Pi install enabled by default and pin its fallback version to 0.80.6
  • wait for asynchronous snapshot deletion before recreating the fixed snapshot name
  • document the exact environment contract and add regression coverage for unset, true, and false

Scope

This PR changes the Daytona snapshot recipe and Pi installation behavior only. It does not add model-catalog entries; those remain in #5198.

Validation

  • GitHub runner unit, integration, and acceptance jobs: passed
  • runner typecheck: passed
  • Daytona helper unit test: 7 passed
  • runner unit suite excluding two pre-existing failed QA captures: 739 passed
  • snapshot recipe ruff and Python compilation: passed
  • live agenta-sandbox-pi rebuild: ACTIVE in 522 seconds
  • live snapshot checks: Pi 0.80.6; Claude, Codex, OpenCode, and geesefs present
  • live Pi catalogs: gpt-5.6-luna, gpt-5.6-sol, and gpt-5.6-terra present under openai and openai-codex
  • Daytona sandbox count: 0 before and 0 after

The API, SDK, and web jobs also fail on the big-agents integration PR at the same base SHA with the same unrelated test failures. This PR touches none of those areas.

Copilot AI review requested due to automatic review settings July 2, 2026 21:41
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 2, 2026
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 10, 2026 11:47am

Request Review

@dosubot dosubot Bot added the enhancement New feature or request label Jul 2, 2026
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: baking pinned Pi into the Daytona snapshot.
Description check ✅ Passed The description is directly related to the Daytona snapshot and Pi install behavior changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/bake-daytona-harnesses

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Daytona sandbox snapshot build and runner behavior so Pi no longer installs at session start by default (assuming the snapshot already bakes Pi), and adjusts related tests/docs. It also updates the session heartbeat unit test to reflect a contract change where status is no longer sent by the runner.

Changes:

  • Flip Pi runtime install behavior to opt-in (AGENTA_AGENT_SANDBOX_PI_INSTALLED === "true") and add unit tests for the new default.
  • Update Daytona snapshot docs/build script to reflect which harness components are baked and add base-image verification steps.
  • Update the alive-heartbeat unit test to assert status is no longer included in the final heartbeat payload.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
services/runner/tests/unit/session-alive.test.ts Updates heartbeat test expectations to match the runner → server heartbeat contract (no status in payload).
services/runner/tests/unit/sandbox-agent-daytona.test.ts Adds coverage for the new default/compat behavior of DAYTONA_PI_INSTALL.
services/runner/src/engines/sandbox_agent/daytona.ts Flips Pi runtime install from opt-out to opt-in and updates inline documentation.
services/runner/sandbox-images/daytona/README.md Documents what the base -full image bakes and how the Pi install lever now behaves.
services/runner/sandbox-images/daytona/build_snapshot.py Verifies baked harness binaries in the base image and installs the pi CLI into the snapshot.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +19
out to -- so this script's only real job is adding that. Everything else below is a
verify-and-mark step, not a re-install: we set the `_INSTALLED` marker for
claude/codex/opencode too so `daytona.ts` never re-runs their daemon auto-install
(currently a no-op safety net at runtime, since the daemon's own install is idempotent,
but skipping it avoids the "is it already there" round-trip on every run) and never pays
their (far larger) per-run cost were that ever to regress. Set the runner service to use
Comment on lines +22 to +26
DAYTONA_SNAPSHOT=agenta-sandbox-pi
AGENTA_AGENT_SANDBOX_PI_INSTALLED=false
AGENTA_AGENT_SANDBOX_PI_INSTALLED=true
AGENTA_AGENT_SANDBOX_CODEX_INSTALLED=true
AGENTA_AGENT_SANDBOX_OPENCODE_INSTALLED=true
AGENTA_AGENT_SANDBOX_CLAUDE_INSTALLED=true
@jp-agenta
jp-agenta marked this pull request as draft July 2, 2026 21:45

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jul 9, 2026
@mmabrouk
mmabrouk marked this pull request as ready for review July 9, 2026 10:55
@mmabrouk

mmabrouk commented Jul 9, 2026

Copy link
Copy Markdown
Member

@jp-agenta setting this to ready to review, since I think this one should make it into the initial release (in contrast to the other addition codex/opencode etc.. ). Did not test though, but the code is sensible

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0ef5c855-b5e8-4203-8fc1-c1ac586d0328

📥 Commits

Reviewing files that changed from the base of the PR and between 1cfb3dc and 62da5d8.

📒 Files selected for processing (5)
  • services/runner/sandbox-images/daytona/README.md
  • services/runner/sandbox-images/daytona/build_snapshot.py
  • services/runner/src/engines/sandbox_agent/daytona.ts
  • services/runner/tests/unit/sandbox-agent-daytona.test.ts
  • services/runner/tests/unit/session-alive.test.ts

Comment on lines +7 to +26
The `-full` sandbox-agent base image already bakes ALL FOUR harnesses: its own build
runs `sandbox-agent install-agent --all` as its last layer, which installs the claude,
codex, and opencode native binaries + ACP adapters (verified by pulling the image
manifest and inspecting the layer: `bin/claude`, `bin/codex` + `agent_processes/codex-acp`
(`@zed-industries/codex-acp`), `bin/opencode` + `agent_processes/opencode-acp`), plus the
`pi-acp` adapter for Pi. The ONE thing `install-agent --all` does NOT bake is the
standalone `pi` CLI binary itself (`@earendil-works/pi-coding-agent`) that `pi-acp` shells
out to -- so this script's only real job is adding that. Everything else below is a
verify-and-mark step, not a re-install: we set the `_INSTALLED` marker for
claude/codex/opencode too so `daytona.ts` never re-runs their daemon auto-install
(currently a no-op safety net at runtime, since the daemon's own install is idempotent,
but skipping it avoids the "is it already there" round-trip on every run) and never pays
their (far larger) per-run cost were that ever to regress. Set the runner service to use
this snapshot:

DAYTONA_SNAPSHOT=agenta-sandbox-pi
AGENTA_AGENT_SANDBOX_PI_INSTALLED=false
AGENTA_AGENT_SANDBOX_PI_INSTALLED=true
AGENTA_AGENT_SANDBOX_CODEX_INSTALLED=true
AGENTA_AGENT_SANDBOX_OPENCODE_INSTALLED=true
AGENTA_AGENT_SANDBOX_CLAUDE_INSTALLED=true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fix the configuration example: AGENTA_AGENT_SANDBOX_PI_INSTALLED=true should NOT be set when using this snapshot.

The docstring's configuration example (lines 23–26) recommends setting AGENTA_AGENT_SANDBOX_PI_INSTALLED=true alongside DAYTONA_SNAPSHOT=agenta-sandbox-pi. However, daytona.ts (line 31) interprets === "true" as opt in to runtime installation, and the README (lines 43–47) explicitly says to use true only for bare/non-snapshot images. Following this example with the snapshot would trigger a redundant ~150s npm install of Pi on every session, defeating the snapshot's purpose.

Additionally, the docstring (lines 15–19) claims the _INSTALLED markers for claude/codex/opencode prevent daytona.ts from re-running their daemon auto-install. But the README (lines 48–51) states these markers are "reserved for symmetry only" and "nothing reads them yet" — daytona.ts has no session-time install path for those three harnesses.

🔧 Proposed fix for the configuration example and docstring
-their (far larger) per-run cost were that ever to regress. Set the runner service to use
-this snapshot:
+their (far larger) per-run cost were that ever to regress.
+
+Set the runner service to use this snapshot (all four harnesses are baked, so leave
+the AGENTA_AGENT_SANDBOX_*_INSTALLED flags unset — the runner defaults to install-OFF):

     DAYTONA_SNAPSHOT=agenta-sandbox-pi
-    AGENTA_AGENT_SANDBOX_PI_INSTALLED=true
-    AGENTA_AGENT_SANDBOX_CODEX_INSTALLED=true
-    AGENTA_AGENT_SANDBOX_OPENCODE_INSTALLED=true
-    AGENTA_AGENT_SANDBOX_CLAUDE_INSTALLED=true
+    # Only set AGENTA_AGENT_SANDBOX_PI_INSTALLED=true when running against a bare
+    # image that lacks pi (see sandbox-images/daytona/README.md).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The `-full` sandbox-agent base image already bakes ALL FOUR harnesses: its own build
runs `sandbox-agent install-agent --all` as its last layer, which installs the claude,
codex, and opencode native binaries + ACP adapters (verified by pulling the image
manifest and inspecting the layer: `bin/claude`, `bin/codex` + `agent_processes/codex-acp`
(`@zed-industries/codex-acp`), `bin/opencode` + `agent_processes/opencode-acp`), plus the
`pi-acp` adapter for Pi. The ONE thing `install-agent --all` does NOT bake is the
standalone `pi` CLI binary itself (`@earendil-works/pi-coding-agent`) that `pi-acp` shells
out to -- so this script's only real job is adding that. Everything else below is a
verify-and-mark step, not a re-install: we set the `_INSTALLED` marker for
claude/codex/opencode too so `daytona.ts` never re-runs their daemon auto-install
(currently a no-op safety net at runtime, since the daemon's own install is idempotent,
but skipping it avoids the "is it already there" round-trip on every run) and never pays
their (far larger) per-run cost were that ever to regress. Set the runner service to use
this snapshot:
DAYTONA_SNAPSHOT=agenta-sandbox-pi
AGENTA_AGENT_SANDBOX_PI_INSTALLED=false
AGENTA_AGENT_SANDBOX_PI_INSTALLED=true
AGENTA_AGENT_SANDBOX_CODEX_INSTALLED=true
AGENTA_AGENT_SANDBOX_OPENCODE_INSTALLED=true
AGENTA_AGENT_SANDBOX_CLAUDE_INSTALLED=true
The `-full` sandbox-agent base image already bakes ALL FOUR harnesses: its own build
runs `sandbox-agent install-agent --all` as its last layer, which installs the claude,
codex, and opencode native binaries + ACP adapters (verified by pulling the image
manifest and inspecting the layer: `bin/claude`, `bin/codex` + `agent_processes/codex-acp`
(`@zed-industries/codex-acp`), `bin/opencode` + `agent_processes/opencode-acp`), plus the
`pi-acp` adapter for Pi. The ONE thing `install-agent --all` does NOT bake is the
standalone `pi` CLI binary itself (`@earendil-works/pi-coding-agent`) that `pi-acp` shells
out to -- so this script's only real job is adding that. Everything else below is a
verify-and-mark step, not a re-install: we set the `_INSTALLED` marker for
claude/codex/opencode too so `daytona.ts` never re-runs their daemon auto-install
(currently a no-op safety net at runtime, since the daemon's own install is idempotent,
but skipping it avoids the "is it already there" round-trip on every run) and never pays
their (far larger) per-run cost were that ever to regress.
Set the runner service to use this snapshot (all four harnesses are baked, so leave
the AGENTA_AGENT_SANDBOX_*_INSTALLED flags unsetthe runner defaults to install-OFF):
DAYTONA_SNAPSHOT=agenta-sandbox-pi
# Only set AGENTA_AGENT_SANDBOX_PI_INSTALLED=true when running against a bare
# image that lacks pi (see sandbox-images/daytona/README.md).

Comment on lines 96 to 100
image = Image.base(SANDBOX_AGENT_IMAGE).dockerfile_commands(
[
"USER root",
f"RUN npm install -g --ignore-scripts {PI_PACKAGE}",
"RUN pi --version || true",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

RUN pi --version || true silently masks a failed Pi installation.

Pi is the one binary this script actually installs, yet its verification uses || true while the pre-baked harnesses (claude/codex/opencode, lines 104–109) use fatal test -x checks. If the npm install -g --ignore-scripts on line 99 fails (e.g., due to --ignore-scripts skipping a required post-install step), the build silently produces a snapshot without Pi. Since DAYTONA_PI_INSTALL defaults to false, the runtime will assume Pi is present and never attempt a fallback install — resulting in broken Pi sessions.

🔒 Proposed fix: make Pi verification fatal
-            "RUN pi --version || true",
+            "RUN pi --version",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
image = Image.base(SANDBOX_AGENT_IMAGE).dockerfile_commands(
[
"USER root",
f"RUN npm install -g --ignore-scripts {PI_PACKAGE}",
"RUN pi --version || true",
image = Image.base(SANDBOX_AGENT_IMAGE).dockerfile_commands(
[
"USER root",
f"RUN npm install -g --ignore-scripts {PI_PACKAGE}",
"RUN pi --version",

Copilot AI review requested due to automatic review settings July 10, 2026 11:39
@mmabrouk
mmabrouk force-pushed the chore/bake-daytona-harnesses branch from 62da5d8 to f48b249 Compare July 10, 2026 11:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jul 10, 2026
@mmabrouk mmabrouk changed the title [feat] Bake harnesses into Daytona snapshot, flip Pi install default [feat] Bake pinned Pi into the Daytona snapshot Jul 10, 2026
Copilot AI review requested due to automatic review settings July 10, 2026 11:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

@mmabrouk
mmabrouk merged commit f0aa9df into big-agents Jul 10, 2026
14 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants