Expand description
Agent VMs: the L3 helpers over the lifecycle (docs/AGENT-VMS.md).
§What this module is
One VM with a coding agent installed, model access wired, running as a non-root user,
and one call that hands the agent a task. Every step is a composition of
crate::sandbox and crate::session calls that
examples/coding-agents-on-bedrock/run.sh performed by hand; this module is where
that composition, and the four measured traps it closes, live once:
- Root silently breaks the agent. Claude Code’s
--dangerously-skip-permissionsrefuses to run as uid 0 and then denies its own tool calls while still reporting (measured: zero shell calls as root, 147 as uid 1000). Every prompt runs asAGENT_UID/AGENT_GID, and the image creates that user. - The daemon’s execs start from an empty environment, so the agent’s subshells
find no
PATHand every command exits 127. The environment file sets it. - The daemon writes uploaded files as root, mode 0600, which a demoted agent
cannot read. One root
chownfollows the uploads. - Codex reaches Bedrock through
bedrock-runtime’s/openai/v1on the Responses wire API, with an inference-profile model id and hosted web search disabled. Its config file names that host for the launch region, and its credential comes fromAWS_BEARER_TOKEN_BEDROCKrather than the provider’senv_key.
§What it is not
Not an orchestrator (docs/STRATEGY.md): no scheduling, no retries across VMs, no
turn loop. Not a harness provider class: a Harbor environment or an eve backend
imports its harness and lives there, calling this. And not a place agent detail
sprawls: every vendor-shaped fact is a row in profile, dated.
§Two shapes over one recipe
AgentVm owns a Sandbox and is the shape for a caller who builds, launches,
provisions, prompts, and tears down in one process. The free functions
(install_access, prompt, installed_agents) take a Session, because the
CLI’s refresh and prompt paths hold an attached session for a VM some earlier process
launched and no sandbox at all; AgentVm’s methods delegate to them so the two
paths cannot drift.
Re-exports§
pub use bedrock::BearerToken;pub use bedrock::Minted;pub use profile::Agent;pub use profile::CODEX_CONFIG_FILE;pub use profile::ENV_FILE;pub use profile::MARKER_FILE;pub use profile::Profile;
Modules§
- bedrock
- A Bedrock bearer token from the caller’s own AWS credentials (AGENT-4).
- profile
- The profile table: every agent-specific fact L3 knows, in one place, dated.
Structs§
- Agent
Spec - One agent to install, with its two overridable defaults.
- AgentVm
- One VM with coding agents in it: the
Sandboxplus the specs it was built for. - Bedrock
Access - Model access for the agents: a Bedrock bearer token minted for a region.
- Guest
File - One file to place in the guest.
- Prompt
Options - The knobs on one prompt.
Constants§
- AGENT_
GID - The gid to match.
- AGENT_
UID - The uid every agent runs as, and the owner of
/workspace. Created by the image. - DEFAULT_
PROMPT_ TIMEOUT - The default wait for one prompt. Agent tasks run minutes, not seconds.
- DEFAULT_
SIZE - The size class agent sessions default to: a 4 GiB always-present ceiling at half the
floor cost of the 2048 default, because agent sessions are peaky (the example’s
measured choice,
examples/coding-agents-on-bedrock/microvm.toml). - WORKDIR
- The image
WORKDIR, the agent’sHOME, and where a synced project lands. The same pathmicrovms-cli/src/sync.rsnames asREMOTE_WORKDIR, on purpose:run <DIR>andagent-up --projectput the tree in the same place.
Functions§
- dockerfile
- The Dockerfile for an image carrying
specs(AGENT-2). - headless_
command_ template - The headless command with
<TASK>where the quoted task goes, for a caller who wants to run it throughexec --streamor read whatpromptwould do. - image_
name_ for AgentVm::image_namefor a caller holding the sandbox and the specs separately: the bindings, whose sandbox sits behind a lock shared with every session they hand out.- image_
request_ for AgentVm::image_requestfor a caller holding the sandbox and the specs separately.- image_
stem - The stem of the image name:
agent-vm-<agents>in profile order (AGENT-3). The caller appends the artifact content hash, exactly asbuild --reusedoes. - install_
access - Places the provisioning files and hands
/workspaceto the agent uid (AGENT-5). - installed_
agents - The agents a running VM was provisioned with, read from the guest marker (AGENT-10).
- launch_
request_ for AgentVm::launch_requestfor a caller holding the specs separately.- prompt
- Starts one task and returns its handle. Wait, stream, poll, or ack through the handle, exactly as for any other exec.
- prompt_
request - The start request for one task (AGENT-7). Pure; the test reads every field.
- provisioning_
files - The files
install_accessplaces (AGENT-5, AGENT-6): the environment file, Codex’s config when Codex is present, and the marker. Pure, so a test reads the exact bytes. - require_
specs - Refuses an empty spec list and a repeated agent.
- sh_
double_ quote - Wraps
valuein double quotes forsh, escaping the four characters that are special inside them. Used for the environment file, whose values are model ids, a region, and a token (base64 plus the prefix), none of which contain them today; the escaping is what keeps that “today” from mattering. - sh_
single_ quote - Wraps
valuein single quotes forsh. A single quote inside becomes'\'', the one sequence that is literal under every POSIX shell. Used for the task text, which is the caller’s prose and may contain anything. - spec_
for - The spec in
specsforagent, or the refusalAgentVm::promptgives.