Manage AI coding-agent sandboxes with Polyaxon
Manage Polyaxon sandbox-enabled services from versioned environment templates through readiness checks, process execution, file persistence, and resource cleanup.
Polyaxon gives a coding agent a repeatable way to connect to a service, execute commands, move files, and preserve the results of its work. The same service remains available across tool calls, so an agent can inspect a repository, edit code, and run an evaluation within one configured environment.
The management workflow is built around a regular Polyaxon run. The sandbox plugin adds process, filesystem, and PTY access inside the service's main container; its image, user, mounts, connections, and network policies determine what those commands can access. Treat that service definition as part of your agent application.
Define the environment your agent needs
Start with the sandbox quick start, then clone the examples repository for the shared lifecycle helper:
git clone https://github.com/polyaxon/polyaxon-examples.git
cd polyaxon-examples/blog/sandbox-lifecycleAdapt the component to your team's tools. This minimal CPU environment uses writable scratch storage and an absolute one-hour runtime limit:
version: 1.1
kind: component
name: coding-agent-workspace
plugins:
sandbox: true
termination:
timeout: 3600
run:
kind: service
volumes:
- name: workspace
emptyDir: {}
container:
image: python:3.11
workingDir: /workspace
command: ["sleep", "infinity"]
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
volumeMounts:
- name: workspace
mountPath: /workspaceSave it as coding-agent.yaml in this directory. Replace the image with a pinned team image when you need Git, a compiler, browser dependencies, or the Polyaxon tracking library. Repeated package installation during sessions should become an image or lockfile change.
Use presets to share queue, resource, and environment settings. Configure necessary connections through the platform, then include only those the workspace needs. Environment settings cover pod-level choices such as service accounts, node placement, and security contexts; cluster policy remains responsible for enforcing the required boundary.
Wait for the run and the command interface
A created run may still be queued or starting. The controller should wait until it reaches RUNNING or a terminal state, then check the sandbox interface before issuing commands. Application preparation can require further checks, such as confirming that a repository and expected tools exist.
The following controller uses an existing agent-evaluations project and a configured Polyaxon client. Save it as manage-workspace.py beside coding-agent.yaml and the repository's shared lifecycle.py helper, then run it from that directory after completing the project and client setup. The helper sets a 10-second HTTP timeout with transport retries disabled and applies a separate deadline to status polling. The controller starts the component, runs a Python version check, and records whether service termination was confirmed:
from polyaxon.client import SandboxClient
from lifecycle import make_run_client, stop_and_record, wait_for_running
run_client = make_run_client(project="agent-evaluations")
run = run_client.create_from_polyaxonfile(
polyaxonfile="coding-agent.yaml",
approved=True,
)
try:
wait_for_running(run_client, seconds=300)
with SandboxClient(
project="agent-evaluations",
run_uuid=run.uuid,
client=run_client.client,
) as sandbox:
sandbox.ping()
result = sandbox.process.exec(
command=["python", "-V"],
workdir="/workspace",
timeout_ms=30_000,
)
print(result.stdout, end="")
print(result.stderr, end="")
if result.timed_out or result.exit_code != 0:
raise RuntimeError("Workspace command failed")
finally:
cleanup = stop_and_record(run_client, seconds=30)
if not cleanup["confirmed"]:
raise RuntimeError("Command finished, but service termination needs review")Here, approved=True assumes trusted automation is already authorized to launch this component. If a reviewer must approve the operation, use your approval workflow before starting it. Bind the resulting project and run UUID in the controller; the language model should receive task tools scoped to that selected service.
The helper checks the 300-second polling deadline between HTTP calls, so a call already in progress still follows its transport timeout. Cleanup writes cleanup-<run UUID>.json and leaves confirmed: false when it cannot observe a terminal status. Inspect that run before treating resource cleanup as complete. The lifecycle walkthrough explains how host polling, sandbox health, command limits, and workload termination fit together.
Choose the process API for each interaction
Use sandbox.process.exec() for a bounded command and inspect its exit code, timeout status, stdout, and stderr. Use exec_stream() when output should arrive while the command runs. For background work, exec_bg() returns a process handle that supports reading output and waiting for completion.
Use a PTY only when the program needs terminal behavior. Enable SSH for an IDE or native terminal workflow, and tmux for reconnectable shell sessions when appropriate. These are documented in the automation guide.
Separate commands start separate processes. Environment changes in one shell and Python variables from a previous command do not automatically appear in the next command. Put reproducible settings in the component, pass command-specific environment values through the process API, and use files for data exchanged across calls.
Save results before releasing the workspace
The component's emptyDir lasts for the pod's lifetime. A later run does not inherit it. Use sandbox.fs.upload_file() to provide inputs and sandbox.fs.download_file() to retrieve scratch outputs. Keep a patch, evaluation report, or generated dataset in durable storage before stopping the service.
For outputs produced inside an image with Polyaxon tracking installed, write to tracking.get_outputs_path() and log artifact metadata with tracking.log_artifact_ref(). The persistence guide explains the distinction: the outputs directory is synced, while an artifact reference by itself does not copy an arbitrary scratch file into storage.
Store source changes in Git and move repeatable configuration into a Polyaxonfile or preset. Associate the saved output with the run UUID, repository revision, image revision, and task input. Another engineer can then reproduce the workflow without retaining the original live workspace.
Bound idle capacity and handle failure
The controller should stop completed sessions even when individual tools fail. Retain an absolute termination timeout as a backstop for abandoned work. From v2.12, idle culling is also available when an activity probe can distinguish active work from inactivity.
Define activity around the application: an evaluation process may still be working while the user is disconnected. Culling stops a service; it does not preserve process memory or provide a suspended session. Recovery requires starting another run and restoring the files and task state your application saved.
Inspect failures in the run's logs and monitoring views, then connect them to the agent's command results. Keep startup failure, command failure, task rejection, and cleanup failure distinct in your application record. This makes operational problems easier to find without confusing an unhealthy environment with a poor model decision.
When the environment works consistently, publish it as a component version. Teams can reuse that definition for agent development and evaluation while adjusting compute placement through presets and keeping every session connected to Polyaxon's run history.