fix(runner): deliver Pi tool specs via a file instead of an env var (spawn E2BIG) - #6039
fix(runner): deliver Pi tool specs via a file instead of an env var (spawn E2BIG)#6039mmabrouk wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughPi tool specifications now use relay-adjacent JSON files for local and Daytona runs. The Pi extension reads the file first and supports a temporary inline environment fallback. Delivery and parsing failures are logged and fail closed. ChangesPi tool specification delivery
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: ⚪ Minimal · up to The PR replaces oversized environment-variable delivery with file-based tool-spec delivery and includes coverage for local and Daytona paths. No actionable merge-blocking risk remains after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Runner
participant DaytonaSandbox
participant PiExtension
Runner->>Runner: Resolve tool specifications
Runner->>DaytonaSandbox: Upload relay-adjacent JSON file
Runner->>PiExtension: Set PUBLIC_SPECS_FILE_ENV
PiExtension->>PiExtension: Read and validate JSON specifications
PiExtension->>PiExtension: Register advertised tools
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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. Comment |
Railway Preview Environment
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
services/runner/tests/unit/extension-tools.test.ts (1)
401-428: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the fat tool-spec fixture into
tests/utils/.This fixture duplicates
fatToolSpecsinservices/runner/tests/unit/sandbox-agent-pi-assets.test.ts(lines 449-467): same name pattern, same 40-field schema, same repeat counts. Two copies drift independently, so a later size-limit change touches only one side. Export one generator fromtests/utils/and import it in both test files.As per coding guidelines, "keep shared helpers and fixtures under
tests/utils/".Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 27cc7c0c-afba-4a1f-bf43-050765ca1a3c
📒 Files selected for processing (8)
services/runner/src/engines/sandbox_agent/daytona.tsservices/runner/src/engines/sandbox_agent/environment-setup.tsservices/runner/src/engines/sandbox_agent/pi-assets.tsservices/runner/src/environment/runtime-lifecycle.tsservices/runner/src/extensions/agenta.tsservices/runner/src/lifecycle/reconciliation-router.tsservices/runner/tests/unit/extension-tools.test.tsservices/runner/tests/unit/sandbox-agent-pi-assets.test.ts
Any Pi agent with a large tool set fails every run with
Agent run failed: spawn E2BIG, before the model is ever reached. A real session with 44 hydrated Composio tools reproduces it on every turn.Root cause
buildPiExtensionEnvpacked every resolved tool spec into one environment variable (AGENTA_AGENT_TOOLS_PUBLIC_SPECS), which is merged into the daemon env the harness process inherits. Linux rejectsexecvewhen any single argv/env string exceedsMAX_ARG_STRLEN(131,072 bytes), so the spawn dies before the harness exists — 44 specs serialize to ~250 KB.The fix
The specs now ride a file, unconditionally: one code path, no size threshold, because tool JSON Schemas are unbounded and no threshold would be safe.
AGENTA_AGENT_TOOLS_PUBLIC_SPECS_FILEname (PUBLIC_SPECS_FILE_ENV) — not a second variable.AGENTA_AGENT_TOOLS_RELAY_DIRis unchanged.<relayDir>.tool-specs.json), like the OTLP auth file, becauseprepareWorkspaceclears and recreates the relay dir every turn.buildRuntimeEnvironment; Daytona runs upload it inprepareDaytonaPiAssets(the sandbox env map is fixed at sandbox creation and the runner's filesystem is not the sandbox's, so the env names a deterministic in-sandbox path and the bytes arrive before the session opens).This is the pattern the non-Pi stdio MCP shim already uses, for the reason its own comment gives: the env is copied through four exec layers and tool JSON Schemas are unbounded.
Scope
Pi only, and entirely runner-internal — no wire-contract change. Claude Code and Codex were never affected: they get specs over MCP (loopback HTTP) or, on Daytona, through the uploaded specs file.
Testing
pnpm test2185 passed / 127 files,pnpm run typecheckclean. New regression tests cover a 606 KB spec set leaving every env value under 131,072 bytes and round-tripping through the file, the extension read side (file preferred, inline fallback, unreadable/malformed file registers nothing), the Daytona upload path, and both fail-loud paths.pi_core, 44 fat tools = 606 KB of specs). With the old inline delivery:{"ok":false,"error":"spawn E2BIG"}. With the fix: the harness spawns and the ACP session opens (sandbox_start,probe_capabilities,create_sessionall complete); the run then fails only onrecords-query, because a standalone runner has no Agenta API to rebuild the conversation from.dist/extensions/agenta.js— the artifact baked into the runner image — loaded the 606 KB file that run wrote and registered all 44 tools.agenta-runner:v0.112.1image with no source mount, so it was not rebuilt and the fix was not exercised there; the Daytona upload path is covered by unit tests, not by a live Daytona run.