provider: add CAPE SandboxProvider backend (assumed CLI contract)#155
Merged
Conversation
Adds agentix-provider-cape: a SandboxProvider that maps one Agentix sandbox onto one long-lived request inside a dedicated CAPE session (CAPE is a lease-based GPU pool whose sessions survive across commands with a persistent workspace). The agent sandbox *is* a CAPE session: persistent workspace, on-demand GPUs. Design: - CapeProviderConfig is fully defaulted (zero-arg construction for the plugin registry); credentials come from a token file or env var, read per operation, with a 0o077 file-mode gate and redaction of the token from any subprocess output that can reach exception text. - _CapeCli is the single class holding the assumed run/status/logs/ cancel verb surface. The contract was reverse-documented from a sibling project's adapter of the same CLI and has never been checked against a real cape binary; the README carries the verification checklist for when the real CLI arrives. - Endpoint discovery is serial-session friendly: the boot script prints an AGENTIX_ENDPOINT marker to stdout before exec'ing the bundle bootstrap, and discovery polls cape logs on the one server request (no concurrent in-session commands), then health-probes with a raw TCP client. Transient status/logs failures are tolerated up to a configurable consecutive limit. - Lifecycle discipline: the initial submit is shielded so cancellation can still harvest the request id and cancel it; subprocess timeout and cancellation paths kill and reap with bounded waits; delete() retains bookkeeping until a cancel is confirmed (retryable) and never raises; per-sandbox runtime ports come from a configurable range. - Deliberately out of scope: BundleDeployer / bundle transport to CAPE nodes (SandboxConfig.bundle is an opaque node-visible path), and any recovery of in-process bookkeeping after a crash (documented, with a session-key naming convention as the server-side cleanup handle). 24 plugin tests drive a fake cape executable (argv recorded as JSONL, fault injection via env vars) plus a loopback /health server: run-face assertions, multi-sandbox classification, discovery retry/timeout, health timeout, token hygiene, delete retry semantics, and real sh -c execution of the boot script round-tripped through the endpoint parser. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Meirtz
force-pushed
the
feat/cape-provider
branch
from
July 22, 2026 19:32
0c3587a to
714902d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New
agentix-provider-capeplugin: aSandboxProviderthat maps one Agentix sandbox onto one long-lived request inside a dedicated CAPE session (CAPE is a lease-based GPU pool whose sessions survive across commands with a persistent workspace). The agent sandbox is a CAPE session: persistent workspace, on-demand GPUs.CapeProviderConfigfully defaulted (zero-arg construction for the plugin registry); token from file or env, read per operation, 0o077 file-mode gate, token redacted from any subprocess output that can reach exception text._CapeCliis the single class holding the assumedrun/status/logs/cancelverb surface — the contract is reverse-documented from a sibling project's adapter of the same CLI and has never been checked against a realcapebinary. The README carries a prominent Contract status section and the verification checklist for when the real CLI arrives.AGENTIX_ENDPOINTmarker to stdout before exec'ing the bundle bootstrap; discovery pollscape logson the one server request (no concurrent in-session commands), then health-probes with a raw TCP client. Transient status/logs failures tolerated up to a configurable consecutive limit.delete()retains bookkeeping until cancel is confirmed (retryable) and never raises; per-sandbox runtime ports from a configurable range.BundleDeployer/bundle transport to CAPE nodes (SandboxConfig.bundleis an opaque node-visible path); recovery of in-process bookkeeping after a crash (session-key naming convention is the server-side cleanup handle).Review process
Implementation went through an adversarial review (4 lenses — lifecycle/leaks, asyncio subprocess discipline, contract fidelity, tests & conventions — each finding challenged by two independent refuters): 22 confirmed findings, all fixed or explicitly documented as known limitations. Notably the endpoint discovery was redesigned (originally a concurrent in-session control request, which contradicts the serial
RUNNING_COMMAND ↔ CACHED_IDLEsession model) and the submit/cancel windows were closed.Testing
uv run pytest plugins/providers/cape/tests -q→ 24 passed (fakecapeexecutable with argv JSONL recording + env fault injection; loopback/healthserver; multi-sandbox classification; discovery retry/timeout; token hygiene; delete retry semantics; realsh -cboot-script round-trip)uv run pytest tests/ plugins/ -q→ 713 passed, 1 skipped, 6 deselected, 22 xfaileduv run ruff check .→ clean;uv run pyright→ 0 errors;uv lock --check→ current🤖 Generated with Claude Code