agent
The hub's cloud agent (A1/A2) — a session works toward a goal with the hub's own tools and a sandboxed shell, as a short-lived key scoped below its creator's; spends past a pre-approved budget wait for a person, and everything it does is an append-only event stream.
GET /v1/agent/sessions
List agent sessions
Sessions visible to the caller (owner, creator, or a member of the owning org), newest first. No session is public.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
status | query | AgentSessionStatus | |
limit | query | integer | Page size. |
cursor | query | string | Opaque cursor from the previous page's |
Responses
| Status | Description | Body |
|---|---|---|
200 | Page of sessions. | AgentSessionPage |
401 | Missing or invalid credentials. | Problem |
422 | Request failed validation. | Problem |
POST /v1/agent/sessions
Start an agent session (the hub's cloud agent works toward a goal)
{goal, robot?, campaign?, budget_usd, cap_usd?, scopes?, owner?} → a session whose first turn is queued at once. The agent loop runs on the hub (one arq job per turn, state in Postgres): a frontier model behind the coach's model interface, extended with tool use, calls the hub's MCP tools in-process as the session's own short-lived key and, where the deployment configures one, a Modal sandbox shell whose network reaches only the hub.
Keys. The hub mints a key for every turn, bound to the session (api_keys.agent_session_id), expiring on its own and revoked when the turn yields or the session ends. Its scope is the one the session was granted — scopes, never above the creator's own — and no agent key can call a session-scoped operation, approve its own spend (resolveAgentApproval is 403 to every agent key), create another session, or approve a device handoff.
Money. Two numbers. budget_usd is the spend a person pre-approves for the tools that cost money (submit_training on a priced executor, a Modal rollout_in_sim, serve_model on Modal, plan_task, the coach's two paid tools): inside it the tool runs and says so; above it the session pauses with an approval_requested event (waiting_on_you) until a person answers. cap_usd (default $10) caps the session's own model + sandbox spend. The model is billed at list price with 0 % markup — each call reserves count_tokens + max_tokens first and settles on the reported usage, cache fields included; the next call is refused at the cap. The sandbox is billed at Modal's sandbox rate × 1.28, only while active. Every call and every sandbox interval is one ledger_entries row. Until a payment system exists every account (an org shares one) gets a $5 monthly allowance for model + sandbox and nothing beyond it: 402 when it is spent. On the allowance only claude-sonnet-5 is offered. AG1: an account may run up to AGENT_MAX_LIVE_SESSIONS (3) working sessions at once — running, waiting on an event or waiting on you; a sleeping session does not count — and a fourth is 409 naming the three (A1's one-live-session rule is lifted; the money caps are unchanged).
Plan first (AG1, the founder's rule). Nothing billable runs before a person approves a plan: the agent's first move on a task that needs compute is a plan (listAgentPlans), and until one is approved every training run, round, rollout, render, endpoint and M16 plan the agent asks for is refused — by its tools and, for its key, by the hub's own routes. Model turns may run, and a session that only answers a question needs no plan.
Context (K3). context[] names the hub objects a session starts with ("Ask the agent about this model"): each one is checked as the caller (missing, private and the wrong kind are one 422 at context[i]), stored on the session, and handed to the model on its first turn as a compact summary built from the hub's own reads — a notice event (code: context) the page shows too.
Spends model dollars: key:train.
Request body
| Field | Type | Description |
|---|---|---|
goal | string | What the agent should achieve, in plain words. |
robot | string | null |
|
campaign | string | null | A campaign (C3) the session works inside, by id or slug. C3b: it must be an |
budget_usd | number | null | A total a person pre-approves for the session's spending tools (GPU training on a priced executor, a Modal rollout, a Modal endpoint, a plan, a coach call), on top of the per-run limit: a call is auto-approved only while every approved call's cap, this one's included, fits in it. Null: no session total — the per-run limit alone decides. 0: every spending call asks. Not the model or sandbox spend (that is |
auto_approve_per_run_usd | number | null | This session's per-call auto-approve limit, which may only LOWER the workspace's ( |
cap_usd | number | null | Cap on the session's own model + sandbox spend ( |
model | string | null | The model the loop runs on ( |
scopes | array of ApiKeyScope | null | Scopes the session's keys carry — the session acts with the highest one named, which may not exceed what the creating credential was granted ( |
owner | string | null | Who the session is billed to: the creator (null) or an org handle the creator is a member of. The allowance and the working-session cap (AG1) are per owner. |
sandbox | boolean | Offer the agent a sandbox shell (when the deployment configures one). |
context | array of AgentContextRef | K3 — hub objects the session starts with. Each is checked as the caller ( |
Responses
| Status | Description | Body |
|---|---|---|
201 | Session created; its first turn is queued. | AgentSession |
401 | Missing or invalid credentials. | Problem |
402 | The account's monthly allowance for agent model + sandbox spend is used up. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
409 | State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...). | Problem |
422 | Request failed validation. | Problem |
503 | A service this endpoint needs is not configured in this deployment (M0's boot guarantee: the API boots with zero secrets, and an endpoint that needs one says so instead of returning a stack trace). | Problem |
GET /v1/agent/sessions/{session_id}
Get an agent session (status, spend, what it waits on, pending approvals)
Everything a page needs beside the event stream: status and why, the three spend lines (model at list price, sandbox × 1.28, GPU committed from the budget), the allowance, what the agent waits on, the pending approvals, the sandbox's state, and last_event_id — where streamAgentEvents resumes. A session you may not see is 404.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
Responses
| Status | Description | Body |
|---|---|---|
200 | The session. | AgentSession |
401 | Missing or invalid credentials. | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
POST /v1/agent/sessions/{session_id}/messages
Send the agent a message (a user turn)
Appends a user message and queues a turn. AG1: a message wakes any session that is not canceled or failed — a sleeping one, a waiting_on_you one (a reply in words is how a person changes a proposed plan; the agent answers with a new version), a waiting_on_event one (it interrupts the wait) and a done one, which it reopens. On a running one it is handed to the model at its next step. 409 only on a canceled or failed session. A message never counts against the working-session cap. Spends model dollars: key:train; an agent's own key is 403.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
Request body
| Field | Type | Description |
|---|---|---|
text | string |
Responses
| Status | Description | Body |
|---|---|---|
202 | Message recorded; a turn is queued. | AgentSession |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
409 | State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...). | Problem |
422 | Request failed validation. | Problem |
GET /v1/agent/sessions/{session_id}/events
Stream a session's events (SSE, resumable)
Server-Sent Events from the session's append-only event table, in the order they were written. Every frame carries id: <event id> (a ULID), event: <kind> and data: <AgentEvent JSON>; a reconnecting EventSource sends Last-Event-ID and the stream resumes strictly after it (after does the same as a query parameter). With follow=true the stream stays open, sending : keepalive comments while nothing happens, until the session ends; event: end always closes it, with the session's status. Same shape as streamRunLogs. The kinds — message, tool_use, tool_result, terminal, approval_requested, approval_resolved, status, usage, sandbox, notice, error, and since AG1 plan, decision and round — and each one's data are AgentEvent's. Replaying the stream plus getAgentSession (and AG1's digest, objects and decisions) is everything the agent page needs.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
follow | query | boolean | Keep the stream open until the session ends. |
after | query | Id | Resume strictly after this event id (the |
Last-Event-ID | header | Id | The id of the last event the client saw (sent by |
Responses
POST /v1/agent/sessions/{session_id}/approvals/{approval_id}
Approve or deny a spend the agent asked for
A spend the rules do not allow — since AG1 any compute call outside the approved plan, whatever it costs, and a coach call over the per-run limit or the budget — is a spend decision (approval_requested); this answers it. AG1 made the wait non-blocking: the agent keeps working while it waits, and on approve its next turn runs the held call exactly as it was asked for (no longer a dry run) before anything else; deny tells it the call did not run and why. raise_budget_to approves this call and grants the session a standing allowance for the rest of its life: later compute calls whose caps fit in what is left of it run without asking (the rule reads session_grant), and the session's budget is raised to cover it. A call outside the approved plan is decided only by a signed-in person's session — the founder's rule that it asks a person, and a key is not a person: every API key is 403, the owner's train key included. A1's coach call over the per-run limit or the budget may still be decided by the owner's train key; every agent session key is 403 for everything, including this session's own — an agent never approves its own spend. 409 once the approval is decided or expired (expires_at, the session's window) or the session is canceled / failed.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
approval_id | path | Id | Agent spend approval id ( |
Request body
| Field | Type | Description |
|---|---|---|
decision | string | |
note | string | null | Shown to the agent with the decision. |
raise_budget_to | number | null | AG1, |
Responses
| Status | Description | Body |
|---|---|---|
200 | The decided approval. | AgentApproval |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
409 | State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...). | Problem |
422 | Request failed validation. | Problem |
POST /v1/agent/sessions/{session_id}/cancel
Cancel an agent session
Ends the session now (canceled): pending approvals are withdrawn, the sandbox is terminated and its last interval billed, the session's keys are revoked. A model call already in flight finishes and is billed (the ledger records it); nothing the model asked for after it runs. Runs, rollouts or plans the agent started are not touched — cancel them on their own pages. 409 when the session already ended.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
Responses
| Status | Description | Body |
|---|---|---|
200 | The canceled session. | AgentSession |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
409 | State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...). | Problem |
POST /v1/agent/sessions/{session_id}/end
End an agent session (done; a reply reopens it)
AG1 — the person ends the session: status done, stop_code: ended. Unlike cancelAgentSession it is not final: its sandbox snapshot is kept and a message reopens it (postAgentMessage wakes a done session). Pending decisions are withdrawn (a spend or a plan nobody answered does not survive the end), the session's keys are revoked, and runs, rollouts or rounds it started are not touched. 409 on a canceled or failed session, or one that is already done. An agent's own key is 403.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
Responses
| Status | Description | Body |
|---|---|---|
200 | The ended session. | AgentSession |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
409 | State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...). | Problem |
GET /v1/agent/sessions/{session_id}/plans
The plans the agent proposed in this session, newest version first
AG1 — every version of the session's plan. The agent proposes a plan before anything that costs compute (the founder's rule: nothing billable before a person approves a plan); a person approves the latest version (approveAgentPlan, session-only) or replies in words and the agent proposes the next version (the one it replaces reads edited). Only the latest version can be approved.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
Responses
| Status | Description | Body |
|---|---|---|
200 | The plans. | AgentPlanPage |
401 | Missing or invalid credentials. | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
GET /v1/agent/sessions/{session_id}/plans/{plan_id}
One version of the session's plan
AG1 — the plan as the Plan board draws it: its rounds (each a campaign round's locked-spec-to-be — one change and its keys, gates with the prediction written beside each, the hypothesis shown beside the gates and never counted, the gate while training, the stop rules, the estimate and the cap), contingent rounds and their condition, "then", "not doing", and the total cap. Estimates are the hub's own (estimateRun's function); nothing in a plan is spent until a person approves it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
plan_id | path | Id | Agent plan id ( |
Responses
POST /v1/agent/sessions/{session_id}/plans/{plan_id}/approve
Approve the agent's plan (a signed-in person only)
AG1 — session-only, like a device approval: no API key of any scope approves a plan, so no agent can approve its own. The plan is the contract: approving it pre-approves each round's cap. In a session with a campaign, every round of the plan that can start now (no contingent_on, no parent_from) is created and locked through createRound's own path in this request — the three rules and the campaign's budget are checked, and a refusal (422 with the rule reasons, 409 on the budget) records nothing and leaves the plan proposed. In a session without a campaign each such round's run is created through createRun's path. The later rounds start when the agent asks for them by key (start_planned_round), exactly as approved. Anything the agent then wants that the plan does not name asks a person again, whatever it costs. 409 when the plan is not the latest version, is not proposed, or the session is canceled or failed.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
plan_id | path | Id | Agent plan id ( |
Request body
| Field | Type | Description |
|---|---|---|
note | string | null | Shown to the agent with the approval. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The approved plan, with the rounds it created. | AgentPlan |
401 | Missing or invalid credentials. | Problem |
403 | Authenticated but not allowed (visibility, membership or scope). | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
409 | State conflict (duplicate handle/slug, wrong repo kind, terminal job, ...). | Problem |
422 | Request failed validation. | Problem |
GET /v1/agent/sessions/{session_id}/decisions
The session's decisions — plan, spend, shortlist, handoff
AG1 — the typed decision cards, one shape: a plan (answered by approveAgentPlan, or a reply in words), a spend outside the approved plan (resolveAgentApproval, with expires_at and raise_budget_to), a shortlist of checkpoints for the real robot (decideRound {action: shortlist} — the 20-seed scan runs first, then one consent request per checkpoint), and a handoff — a device consent request, which only links to the consent page and is never approved here. answer_via names the operation that answers each. Newest first; status filters.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
status | query | AgentDecisionStatus |
Responses
| Status | Description | Body |
|---|---|---|
200 | The decisions. | AgentDecisionPage |
401 | Missing or invalid credentials. | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
422 | Request failed validation. | Problem |
GET /v1/agent/sessions/{session_id}/digest
"Since you left" — what happened in the session since the viewer last looked
AG1 — generated by the hub from the session's events and the objects they link, never by the model: it costs nothing, is the same on every read, and cannot state a fact the rows do not hold. The agent's own words appear only as quotes (a round card's "Next", a spend's proposal). Lines, in order: runs that finished or failed, the gates their checkpoints got, the round's verdict by its locked gates, the tripwire, videos rendered or rendering, handoffs, and what needs you — each with the ids to open. since defaults to the viewer's last_seen_at (else the session's start). Unless mark=false, reading it moves the viewer's last_seen_at to now (an agent's own key never marks).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
since | query | string (date-time) | Lines about what happened after this instant (default the viewer's |
mark | query | boolean | Move the viewer's |
Responses
| Status | Description | Body |
|---|---|---|
200 | The digest. | AgentDigest |
401 | Missing or invalid credentials. | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
422 | Request failed validation. | Problem |
GET /v1/agent/sessions/{session_id}/objects
The session's objects grouped by state — Needs you, Running, Ready for review, Done
AG1 — the overview column of the session page: every object the session touched (derived from its events' links and its plan), one line of facts each, grouped. Needs you: pending decisions, and (P1) the spends a pre-AG1 session still holds the A1 way — pending AgentApprovals with no decision card (kind: approval), so a page never has to patch them in. A render's line says how long is left from the hub's measured render time (AgentRenderRef.expected_s). Running: queued or running runs, renders and the shortlist's scans. Ready for review: checkpoints that PASS the round's locked gates (a shortlist's candidates once one is proposed). Done: finished runs and renders, plan rounds that were not needed. The groups always come back in that order, empty ones included.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
session_id | path | Id | Agent session id ( |
Responses
| Status | Description | Body |
|---|---|---|
200 | The objects. | AgentObjects |
401 | Missing or invalid credentials. | Problem |
404 | Resource not found (or hidden from the caller). | Problem |
Schemas (28)
The schemas these operations reach before any other tag’s do. A type that links elsewhere is rendered on that tag’s page.
AgentSessionStatus
running — a turn is queued or in progress; waiting_on_you — a decision waits for a person (a plan, a spend, a shortlist: waiting_on.decision_ids; A1's held spend: pending_approvals) — the agent may still be woken by an event meanwhile; waiting_on_event — nothing waits for a person, and the agent yielded until a run, rollout, gate, approval request, plan or endpoint moves (waiting_on); sleeping (AG1) — nothing is pending and the agent waits for a message, its sandbox snapshotted and stopped, so nothing bills (no idle timeout ends it any more); idle — A1's name for the same wait, no longer written (read it as sleeping); done — the person ended it (endAgentSession) or the agent declared the task complete — a message reopens it; failed — a hard stop (the session cap, the monthly allowance, the call cap, a refused or failing model, the creating credential revoked), with stop_code; canceled — cancelAgentSession. Only failed and canceled are final.
AgentSessionPage
| Field | Type | Description |
|---|---|---|
items | array of AgentSession | |
next_cursor | string | null |
AgentSessionCreate
| Field | Type | Description |
|---|---|---|
goal | string | What the agent should achieve, in plain words. |
robot | string | null |
|
campaign | string | null | A campaign (C3) the session works inside, by id or slug. C3b: it must be an |
budget_usd | number | null | A total a person pre-approves for the session's spending tools (GPU training on a priced executor, a Modal rollout, a Modal endpoint, a plan, a coach call), on top of the per-run limit: a call is auto-approved only while every approved call's cap, this one's included, fits in it. Null: no session total — the per-run limit alone decides. 0: every spending call asks. Not the model or sandbox spend (that is |
auto_approve_per_run_usd | number | null | This session's per-call auto-approve limit, which may only LOWER the workspace's ( |
cap_usd | number | null | Cap on the session's own model + sandbox spend ( |
model | string | null | The model the loop runs on ( |
scopes | array of ApiKeyScope | null | Scopes the session's keys carry — the session acts with the highest one named, which may not exceed what the creating credential was granted ( |
owner | string | null | Who the session is billed to: the creator (null) or an org handle the creator is a member of. The allowance and the working-session cap (AG1) are per owner. |
sandbox | boolean | Offer the agent a sandbox shell (when the deployment configures one). |
context | array of AgentContextRef | K3 — hub objects the session starts with. Each is checked as the caller ( |
AgentSession
One cloud-agent session. The conversation itself is the event stream (streamAgentEvents); this is the state around it.
| Field | Type | Description |
|---|---|---|
id | Id | |
status | AgentSessionStatus | |
status_reason | string | null | |
stop_code | string | null | Why a |
title | string | null | AG1 — the session's title, set by the agent from the goal (e.g. "Omni walk · R4 lateral feed-forward"); null until it sets one. |
summary | string | null | AG1 — the status line the agent writes whenever it acts (the Home board's second line): what it last did and what waits. Set with its |
summary_at | string (date-time) | null (date-time) | |
slept_at | string (date-time) | null (date-time) | AG1 — when the session last went to sleep; null while it is awake. |
last_seen_at | string (date-time) | null (date-time) | AG1 — when the caller last read the session's digest (per viewer); the digest's default |
plan | AgentPlanRef | null | AG1 — the session's latest plan version (approved or not). |
approved_plan_id | string | null | AG1 — the plan version in force; null until a person approves one. |
pending_decisions | integer | AG1 — decisions waiting for a person (plan, spend, shortlist). |
goal | string | |
robot | string | null | |
campaign | string | null | |
context | array of AgentContextRef | K3 — the hub objects the session was started with ( |
owner | RepoOwner | |
created_by | UserPublic | null | |
model | string | |
backend | string |
|
billing | string | Who pays for the model: |
scopes | array of ApiKeyScope | What the session's keys are granted (the highest one is used). |
budget_usd | number | null | The session's pre-approved total for spending tools; null — the per-run limit alone. |
auto_approve_per_run_usd | number | The per-call auto-approve limit in force (the workspace's, or lower for this session). |
cap_usd | number | |
spend | AgentSpend | |
allowance | AgentAllowance | |
calls | integer | |
max_calls | integer | |
user_turns | integer | |
waiting_on | AgentWait | null | |
pending_approvals | array of AgentApproval | |
sandbox | AgentSandbox | |
last_event_id | string | null | Where |
created_at | string (date-time) | |
updated_at | string (date-time) | |
finished_at | string (date-time) | null (date-time) | |
expires_at | string (date-time) | AG1: no longer a kill. The end of the session's current window ( |
AgentMessageCreate
| Field | Type | Description |
|---|---|---|
text | string |
AgentApprovalDecision
| Field | Type | Description |
|---|---|---|
decision | string | |
note | string | null | Shown to the agent with the decision. |
raise_budget_to | number | null | AG1, |
AgentPlanPage
| Field | Type | Description |
|---|---|---|
items | array of AgentPlan |
AgentPlan
AG1 — the agent's plan for the session: what it will train, how each round is judged, what it may cost, and what it will not do. Nothing billable runs in a session before a person approves a plan; after that, the plan is the contract and anything outside it asks a person.
| Field | Type | Description |
|---|---|---|
id | Id | |
session_id | Id | |
version | integer | 1 for the first proposal; each edit is the next version. |
status | AgentPlanStatus | |
title | string | null | The plan card's title, e.g. "R4, and R4b if needed". |
summary | string | The agent's own paragraph about the plan, quoted as written. |
campaign | AgentCampaignRef | null | The session's campaign, whose rounds the plan's rounds become; null without one. |
robot | string | null | |
rounds | array of AgentPlanRound | |
after | array of string | "Then" — what follows a PASS (e.g. the 20-seed band scan, a shortlist of up to 2, the robot handoff by consent). |
not_doing | array of string | |
stop_rules | array of string | The session-level stop rules in words (its budget, its model cap), hub-generated. |
cap_usd | number | The most the plan can spend on compute — every round's cap, contingent rounds included. |
est_usd | number | null | The expected compute cost of the rounds that start at approval, where the planner models them. |
budget_usd | number | null | The session's |
model_estimate_usd | number | null | A rough figure for the agent's own model turns across the plan (a flat per-checkpoint wake cost), from the free allowance. |
model_estimate_basis | string | null | |
proposed_at | string (date-time) | |
approved_at | string (date-time) | null (date-time) | |
approved_by | UserPublic | null | |
approval_note | string | null | |
superseded_by | string | null | The plan version that replaced this one ( |
decision_id | string | null | The |
AgentPlanApprove
| Field | Type | Description |
|---|---|---|
note | string | null | Shown to the agent with the approval. |
AgentDecisionPage
| Field | Type | Description |
|---|---|---|
items | array of AgentDecision |
AgentDigest
| Field | Type | Description |
|---|---|---|
session_id | Id | |
since | string (date-time) | |
until | string (date-time) | |
marked | boolean | Whether this read moved the viewer's |
lines | array of AgentDigestLine |
AgentObjects
| Field | Type | Description |
|---|---|---|
session_id | Id | |
generated_at | string (date-time) | |
total | integer | |
groups | array of AgentObjectGroupItems | Always the four groups, in the order Needs you, Running, Ready for review, Done. |
AgentContextRef
| Field | Type | Description |
|---|---|---|
type | string | |
ref | string |
|
AgentSpend
The session's three lines, USD. model_usd is list price (0 % markup), sandbox_usd Modal's sandbox rate × 1.28 for the intervals it was active; both are sums of the session's ledger rows. gpu_budget_used_usd is what tools committed inside budget_usd (estimates, the most they can cost), gpu_approved_usd what a person approved above it; the GPU itself is billed on its run or endpoint.
| Field | Type | Description |
|---|---|---|
model_usd | number | |
sandbox_usd | number | |
total_usd | number |
|
reserved_usd | number | A model call's reservation while it is in flight; 0 between calls. |
gpu_budget_used_usd | number | |
gpu_approved_usd | number | |
calls | integer | Model calls made, each one a ledger row. |
ledger_rows | integer | |
gpu_usd | number | The header's third line: GPU dollars of the runs this session started — a finished run's |
gpu_runs | array of AgentGpuRun | |
sandbox_state | AgentSandboxState |
AgentWait
What the session is blocked on.
| Field | Type | Description |
|---|---|---|
kind | string |
|
decision_ids | array of Id | AG1 — the pending decisions ( |
event | string | null | AG1 — with |
ref | string | null | The resource id waited on. |
until | string | null | What wakes the agent: |
approval_ids | array of Id | |
since | string (date-time) | |
timeout_at | string (date-time) | null (date-time) | |
message | string | null |
AgentSandbox
| Field | Type | Description |
|---|---|---|
state | AgentSandboxState | |
sandbox_id | string | null | Modal's id for the current container. |
started_at | string (date-time) | null (date-time) | When the current active interval began. |
active_seconds | number | Seconds billed so far over every interval. |
cost_usd | number | |
expires_at | string (date-time) | null (date-time) | The sandbox's 24 h hard cap, from its first start. |
egress | array of string | The only hosts the sandbox's network may reach — the hub's. |
AgentCampaignRef
| Field | Type | Description |
|---|---|---|
id | Id | |
slug | string | |
name | string | |
robot | string | null |
|
AgentPlanRound
One round of a plan: what createRound will lock (C3) — a name, the checkpoint it resumes from, the spec (ONE change and its keys, the hypothesis shown beside the gates and never counted, gates each with the prediction written beside it, not-doing, tripwires, the iteration cap) and the recipe — plus what the hub derived from them. In a session without a campaign the same shape describes a run: the recipe is what createRun receives and the spec is the record of the gates and predictions (no C3 verdict is computed without a campaign).
| Field | Type | Description |
|---|---|---|
key | string | The round's short label inside the plan, e.g. |
name | string | The round's name, e.g. "lateral feed-forward". |
contingent_on | string | null | A contingent round's condition in words, e.g. "only if R4's vy±0.10 is still over the band at the scan". It never starts at approval; the agent starts it by key when it judges the condition met, and its reading is quoted on the round ( |
parent | CheckpointRef | null | The checkpoint it resumes from; null trains from scratch (or from the campaign's root). |
parent_from | string | null | Instead of |
spec | RoundSpec | |
recipe | Recipe | |
scan | RoundScanRequest | null | |
start | string |
|
gate | CheckpointGateSpec | null | The gate while training as it will run — the recipe's, else the campaign task's default (L1's poster c_matrix for walk/omni). |
estimate | RunEstimate | null |
|
est_usd | number | null | What the round is expected to cost where the hardware planner can model the template ( |
est_hours | number | null | The planner's expected wall-clock hours ( |
cap_usd | number | The most the round can cost — |
parent_name | string | null | What to call the parent checkpoint's run (its |
variables | RoundVariables | null | C3's one-variable arithmetic, planned when the plan was proposed (the recipe against the parent's resolved config) — null for a round whose parent is not known yet. A plan whose round breaks a rule is rejected before a person sees it. |
warnings | array of string | What C3 noticed and would not refuse (a stand round with no push gate, a key that cannot be compared). |
stop_rules | array of string | The round's stop rules in words, from its tripwires and its cap (hub-generated). |
status | AgentPlanRoundStatus | |
round_n | integer | null | The campaign round it became (C3), once created. |
round_id | string | null | |
run_id | string | null | Its training run, once created. |
started_at | string (date-time) | null (date-time) | |
note | string | null | The agent's reading of a contingent condition (quoted), a skip's reason (quoted), or why the hub refused it. |
AgentDigestLine
| Field | Type | Description |
|---|---|---|
kind | AgentDigestLineKind | |
state | AgentItemState | |
text | string | One sentence, hub-generated; the agent's words appear only inside quotes. |
short | string | null | P1 — the same line for a phone, at most 90 characters: the same facts with the identifiers, the quotes and the subordinate clauses dropped (docs/API.md "The digest's short form"), e.g. "R4 finished 11:06 — 1,600 it in 29 min, $1.60." Hub-generated like |
at | string (date-time) | null (date-time) | |
links | AgentLinks | null |
AgentObjectGroupItems
| Field | Type | Description |
|---|---|---|
group | AgentObjectGroup | |
items | array of AgentObject |
AgentGpuRun
AgentSandboxState
none — never started; running — a Modal Sandbox is up and billed; snapshotted — idle, its filesystem snapshotted and the container stopped (not billed; the next shell call restores it); terminated — ended with the session; unavailable — the deployment configures no sandbox (AGENT_SANDBOX_APP), so the agent has no shell.
AgentPlanRoundStatus
planned — not started (it starts at approval, or later by key when it is contingent or resumes from another plan round); created — its round (with a campaign) or run (without) exists: round_n, run_id; refused — the hub refused to create it (note carries why; the plan's approval failed with it); not_needed — a contingent round the agent skipped, with its reason quoted in note.
AgentDigestLineKind
AgentItemState
How a digest line or an object row reads, by word and shape as well as colour: needs_you (◆), running (■), done (●), failed (✕), skipped (○).
AgentObjectGroup
AgentObject
| Field | Type | Description |
|---|---|---|
kind | AgentObjectKind | |
id | string | The object's id (a checkpoint's is |
group | AgentObjectGroup | |
name | string | E.g. "R4 c4r4_side_ff", "step_1600", "Render video". |
line | string | One line of facts, e.g. "9 / 13 · vx+0.30 93 % · video ready". |
state | AgentItemState | |
word | string | null | The state as a word for the row ( |
since | string (date-time) | null (date-time) | |
links | AgentLinks | null |
AgentObjectKind
What a row is. P1 added approval: a spend a pre-AG1 session held the A1 way (an AgentApproval with no decision card), listed under Needs you while it is pending; its id is the approval's and it is answered through resolveAgentApproval.