Concepts
The vocabulary the guides and dashboard use.
Runs, participants, sessions
A run is one training or evaluation job inside a project. Metrics, commands, and artifacts belong to it. launchhelm.init creates a run; resume= reopens one by id or title.
A participant is one process inside the run. A single-process run has one. In distributed training each rank is its own participant (rank-0, rank-1, …) so the dashboard can tell which worker is alive and which one wrote a metric.
A session is a participant's current attachment to the run. Crashes and reconnects produce new sessions under the same participant. The session_lost alert fires when a session stops renewing — the process stopped checking in (network loss, pause, or crash), which is not proof the process died.
Telemetry
run.log({"loss": 0.4}, step=3) writes scalar points to named streams. Stream names come from your metric keys.
Delivery levels:
run.log(...)returns as soon as the point is recorded locally.run.flush(delivered=False)persists queued points on the local machine, so they survive a crash and upload on the next start with the samestate_dir.run.flush()additionally waits until the server has stored the points, so they are query-visible when it returns.run.finish()— called automatically bywith launchhelm.init(...)— waits for delivery and ends the run.
run.close() saves the local queue without waiting for delivery; prefer finish() for normal work.
Rich renderers
A stream can declare a presentation renderer — fixed at creation — whose points carry a structured value instead of a number:
| Renderer | Typical use |
|---|---|
text | Notes and generated samples, plain or markdown |
media | Images, audio, video, grids |
table | Sweep results, prediction previews |
histogram | Weight and gradient distributions |
A media item's source is either an uploaded object or an external https: URL. Size and shape bounds are on Limits.
Reads go through client.read_samples(stream_id, select=...) with latest, at, spread, or index selection. A sample read returns at most one point per axis value — the newest write wins — and complete=false marks a truncated page.
Safe points and commands
A safe point is a place in your loop where it is legal to mutate state — conventionally between steps (after_step). You publish capabilities (typed commands with input/output schemas) bound to safe points; the dashboard issues commands against them.
run.sync("after_step", step=step) applies at most one waiting command at that point — sync doesn't wait on the network.
Command outcomes
| Outcome | Meaning |
|---|---|
applied | The handler ran and reported success. |
rejected | The runtime refused it locally — bad input, wrong safe point, or a closed run. |
failed | The handler raised. |
cancelled | Withdrawn before the run claimed it. |
outcome_unknown | The result could not be recorded — for example the acknowledgement was lost. |
A runtime with several processes also reports how many of them applied the command (applied_on: count of total). It is the runtime's report, not a server observation.
An applied result can also carry restore: the input that, sent to the same control, puts back what the command changed (for example {"scale": 2} after halving the learning rate). The server checks it against the control's input schema. The control's card offers it as "Undo this change…", which opens an ordinary request, prefilled, to review and send; approval rules apply as to any other change.
A change waits for a second person when its control declares requires_approval, when one of the project's approval rules matches it, or when the sender names someone (approver_id on the request). A rule names a control and, optionally, a bound on one numeric input field ("lr with scale above 1.5"), and can name who may approve. When every matching rule names approvers, only they may approve, and a request may name one of them; otherwise anyone who can approve commands may. Nobody approves their own change. The command records why it waits and who may approve it (approval). Rules are edited under "Who approves changes" on the project page (they are the project document's approval), and the request form says before sending whether a change needs approval and from whom.
Changes to a process apply one at a time within a conflict domain (a capability's conflict_domain; Python capabilities default to runtime). A request is checked against the process's state when it is sent and again when it begins, and every applied change advances that state, so a request queued behind another change in its domain would be rejected as stale (expired_or_stale). The request form therefore lists unfinished changes in the same domain, from anyone, with who sent them and their state, and holds Review until they apply or are cancelled. Reviewing then checks the new request against the state they left. Observe-only controls don't advance state and never wait.
outcome_unknown is never retried automatically. The handler may or may not have run. The run's Controls tab shows the state and keeps enough detail to decide whether reissuing is safe — the decision stays with you.
Documents and the API
Runs, streams, participants, and other catalog resources are revisioned documents under the versioned HTTP API. Commands and participant sessions use dedicated protocol routes. SDKs and the LaunchHelm dashboard share that API; the low-level launchhelm.Client exposes it for tooling. See Read points back.