Computers
A Computer is the Linux environment an Agent’s Sessions run in. It has its own
disk, processes and Secret bindings, and it outlives the Sessions that use it.
Every Computer is created from a Template definition that you declare in source
with template() and deploy with your Agents.
Defining a Computer
import { agent, template, image } from "@helmr/sdk"
// Create these Secret IDs in each target Environment.
const GITHUB_TOKEN = "GITHUB_TOKEN"
const REGISTRY_TOKEN_ID = "REGISTRY_TOKEN"
export const repo = template({
id: "repo",
image: image("repo")
.from("node:24-bookworm-slim")
.run(["sh", "-ceu", "apt-get update && apt-get install -y git ripgrep"])
.workdir("/workspace"),
resources: { cpu: 2, memory: "4GiB" },
async prepare(build) {
await build.exec(["git", "clone", "https://github.com/acme/app.git", "/workspace/app"])
await build.exec("npm ci", { cwd: "/workspace/app" })
},
refresh: { every: "1d" },
prepareSecrets: [{ secret: REGISTRY_TOKEN_ID, env: { name: "REGISTRY_TOKEN", mode: "raw" } }],
secrets: [{ secret: GITHUB_TOKEN, env: { name: "GITHUB_TOKEN", mode: "raw" } }],
deleteAfterUnused: "30d",
})
export const fixer = agent({
id: "fixer",
template: repo,
async turn(turn) {
return { received: turn.input.length }
},
})
The full field list is in the Computer reference.
Durations are positive integer milliseconds or a string such as "30m", "12h"
or "7d".
The disk is 32 GiB in this release. You can omit disk; a Computer whose
definition sets any other size cannot be created.
The prepared image
A template’s image() is the recipe; an image is the disk Helmr builds from
that recipe and, when you declare one, the result of running prepare.
Every Computer starts from a prepared image. New Computers start from a copy of
it, so work that every Computer needs (cloning a repository, installing
dependencies, warming caches) runs once instead of at the start of every
Session.
prepare(build) runs inside a Computer built from the image() recipe.
build.exec runs one command and rejects if it exits with a nonzero status.
Pass a string to run it through /bin/sh -c, or an argv array to run it
directly, with optional cwd and env. build.signal aborts when preparation
is cancelled. When prepare returns and its commands finish, Helmr saves the
disk as the prepared image. If prepare throws or a command fails, no image is
produced and Computers waiting for it report an unavailable residency with the
error code computer_preparation_failed.
When you promote a Deployment, Helmr waits for a usable image for every Template
with a prepare callback and every Template referenced by an Agent in that
Deployment. A changed image specification needs a new image. Templates with
the same image specification share one preparation.
A Template with no callback and no Agent reference can prepare its image when
the first Computer needs it. Concurrent requests share that preparation.
Refresh
A prepared image ages. refresh: { every } sets the interval between
background re-preparations, and it also limits how old an image may be: a new
Computer does not start from an image older than three every intervals.
Helmr prepares a new image instead. Without refresh, images have no age limit
and are not re-prepared in the background.
Refresh affects only Computers created afterward. A Computer keeps the image it started from for its whole life, and its disk then changes only through its own work.
The age limit is enforced when a Computer is created and when a Deployment is
promoted. Promoting a Deployment activates its every policy for background
preparation. The interval is best effort: a usable build already in progress
satisfies the interval, missed intervals are coalesced, and capacity or an
executor awaiting physical shutdown can delay work. It does not guarantee a
successful image at each interval; the age limit allows two missed intervals
before a new Computer waits for preparation.
Helmr keeps the newest usable prepared image for each immutable recipe and images still needed by existing Computers or waiting preparations. Superseded payloads are reclaimed after the producing executor has stopped; image identities and build history remain. A new preparation may produce different bytes if external inputs changed. Historical generated image versions are not selectable through the API.
Preparation and runtime Secrets
A Template definition has two separate sets of Secret bindings:
| Binding | Available to | Effect of rotation |
|---|---|---|
prepareSecrets |
prepare only. |
An image prepared with an older Secret version is not used for new Computers; Helmr prepares a new one. Existing Computers are unaffected. |
secrets |
Processes in Computers created from the definition. | Follows the Secret’s own delivery rules. See Secrets. |
Anything prepare writes to disk becomes part of the prepared image and is copied
into every new Computer. Do not write preparation Secret values to files.
Revoking a prepareSecrets Secret stops new preparations that need it and keeps
images prepared with it from being used for new Computers. Existing Computers
keep running; when the binding is raw, helmr computer list --secret NAME marks them as possibly holding
the value through their image.
Bindings use stable Secret IDs, never values. Runtime bindings are fixed when a
Computer is created: it takes the definition’s secrets, or the bindings passed
explicitly to client.computers.create.
Template network policies apply to the actual Computer and have a separate resolved preparation phase. Changing a policy changes preparation identity and newly selected definitions; existing Computers keep their original pins. See Execution policies.
Lifecycle
Starting an Agent without an existing Computer creates a new one from the Agent’s Template definition. You can also create a Computer directly and place Sessions on it:
const computer = await client.computers.create({
template: "repo",
key: "repo:acme/app",
idempotencyKey: "create:repo:acme/app",
})
await client.sessions.create({ agent: "fixer", input: [{ type: "text", text: "Fix the failing test" }],
computer: { id: computer.id }, })
key is an optional immutable lookup value; it does not make creation
get-or-create. Several Sessions can use one Computer and see each other’s
committed files. Use separate Computers when work must not share files or
Secret placements. Workloads in one Environment are mutually trusted.
A Computer’s status is its resource lifecycle: available, deleting or
deleted. Its residency describes where it is running; the Console shows the
residency as a Computer’s status, and the lifecycle only while it is deleting
or deleted:
| Residency | Meaning |
|---|---|
starting |
Its image is being prepared or a machine is being started for it. |
running |
It is running on a worker. |
cold |
It is not running and has no ready memory checkpoint. |
parked |
Its durable memory checkpoint is ready; background progress is paused. |
restoring |
It is resuming from hibernation. |
parking |
Capture or physical release is in progress. |
unavailable |
It cannot run; error carries a code such as computer_preparation_failed or computer_recovery_required. |
Use await computer.hibernate() to request hibernation of the whole Computer,
or await computer.wake() to resume background execution without sending a
prompt. Both return an accepted-operation receipt; observe computer.get() and
executionControl for completion or failure. An optional idempotencyKey makes
retries return the same accepted operation. Hibernate rejects active foreground
work; it does not cancel work or queue a deferred sleep instruction.
Console provides the same actions and shows how many open Sessions hibernation
pauses before you confirm; GET /v1/computers/{computerID}/hibernate-preview
returns that count as { "sessions": N }. Wake does not release Session holds,
reopen closed Sessions or change Slack mute.
Helmr also hibernates a Computer on its own when its Sessions’ Agents set
hibernateAfterIdle and every open Session has been idle that long, or when
the Computer has had no open Session and no unsettled Command for 10 minutes.
See Hibernation.
Starting a Session or a Command on a Computer starts or restores it as needed. This applies after explicit and automatic hibernation. Rejected wake admission preserves the sleeping checkpoint. Failures after an accepted wake require observing the operation state; they do not imply rollback. See Durability for what is saved and when.
A Computer is unused when all its Sessions are finished, its Commands have
settled and its disk saves are complete. After its origin Template’s
deleteAfterUnused, Helmr deletes it. New work resets that interval; internal
saves do not. A Computer that should live longer is created from a Template
with a longer period. Delete a Computer explicitly at any time. Deleting cancels its Sessions and the Sessions they started, and its
unfinished Commands; computers.delete is enough.
Commands
A Command runs one argv command inside a Computer, independent of any Session.
It has its own ID, outcome and output logs, and it can change the Computer’s
files. Commands default to /workspace as their working directory.
A Command owns a bounded process scope: when its main process exits, including
a successful exit, Helmr terminates remaining descendants. Starting a background
server with sh -c 'server &' therefore does not keep that server running after
the Command finishes.
helmr computer exec --id "$COMPUTER_ID" -- git status --short
Inside Agent code, run local work as ordinary child processes. See Run commands.
Related
A Computer can also report an execution_wait reason for accepted runnable work:
scheduling while compatible placement is pending, environment_limit while the
Environment’s execution limits prevent admission, or saving while a save or
checkpoint transition blocks follow-up work. The SDK exposes this as
executionWait. An idle Computer reports null; this field does not give an ETA
or replace residency, errors, or Session holds.