Agent playground
Open a project in the dashboard and choose Agent playground. Select the agent and environment independently, then create a new session or resume a previous playground session. Playground sessions stay in the playground list. Sessions started through an API appear under Sessions, where their durable turn history can be inspected. See Playground and debugging for target selection and the debug inspector.Finding sessions
Give a session labels when you create it, such as the ticket, repository or user it works for, and list sessions by project, environment, agent, deployment, status, creation or update time and label instead of keeping your own index of session ids. The list returns rows with the session’s status, its current turn activity and its latest result, and never the prompts or messages; open a session for its turns and events. The query, the row shape and the label bounds are on the API reference. When one session stands for one record in your application, give it that record’s id as itsexternalReference at creation. The reference is stored
as given, returned on the session and its lifecycle events, and is an exact
list filter: after a lost create response, retry with the same request key
first, then GET /sessions?externalReference=<ref> finds the session
however many unrelated sessions have been created since. Retrying the key
with a different reference is refused, so a record cannot be attached to
the wrong session. Bounds and semantics are on the API
reference.
The list is paged: at most 100 rows per request, 50 by default, newest
created first. Follow nextCursor with the same filters until it is
null; every session matching the filters appears exactly once, however
many were created in the same instant. The TypeScript
client does this for you with
sessions.iterate(filters).
Execution, labels and results
These describe different parts of a session:
A report does not finish a turn, and each report replaces the whole result.
Later work can run, fail or be cancelled while an earlier result remains.
For a review queue, check current activity, the last settled turn’s status,
and whether
result.turnId matches that turn before treating the report as
ready. Your application decides what the reported data means.
Questions
A turn can end by asking. When the agent calls theask tool, the turn completes with
outcome: "question" and the session’s question is set:
options is empty for a free-text question. question is null when
nothing is open, and it is independent of result: a session can hold a
result and an open question at the same time. A consumer that only knows
completed turns still reads an asking turn correctly, because its status is
completed.
Answer by sending a turn that names the question with answers:
useInput().answer.
Naming a question that is not the open one is refused with
409 question_stale; read the session again and answer its current
question.
While a question is open, a turn sent without answers does not run on its
own. It is held, and delivered with the answer, in order, as steering, so
the turn that interprets the answer sees every constraint written in the
meantime. steering carries a bounded number of held inputs, up to 64 KiB;
the rest run as ordinary turns after the answer, in order. The API answers a
held input with 202 { status: "held", questionId } and no turnId; see
Turns. A turn already queued behind the asking turn
settles as cancelled with reason held and keeps its turn id. Held inputs
are in the event log as message.held, then
message.delivered or message.discarded.
One question is open at a time. The answering turn may ask again, which opens
a new question. A question closes without an answer with
question.closed { reason }:
Interrupting a turn does not close a question. In Linear, messages typed
while the agent works usually arrive after the answer; see
Ask before acting.
Durability and recovery
Closing the browser or redeploying your application does not discard work the API has accepted. Reopen the session and resume reading its durable event log. If a submission’s response was lost, retry with the same request key and body; see Starting work from an application. Durable history does not make every command resumable. A lost computer can leave a command’s outcome unknown; OpenComputer does not automatically replay that command or roll back its effects. The turn can continue with a tool error or fail. Inspect the recorded outcome and verify external effects before asking the agent to retry. Interrupt stops the current turn while keeping the session available for more work. End closes the session and revokes its memory writes. Neither operation undoes completed writes; their different acknowledgement and cleanup guarantees are described in the API reference.CLI
Start a session against the development agent:--verbose to stream non-message lifecycle, runtime, tool, egress, usage,
and turn events. Assistant message text continues to stream normally:
list shows the newest sessions first, one page at a time; narrow it with
exact filters and continue from the cursor the previous page printed. With
--json the page is printed as { sessions, nextCursor } for scripts:
--agent takes the agent’s id, --limit is 1 to 100, and --cursor
continues only with the filters that produced it.
Bind memory documents when creating a session; add
--create-document to create the ones that do not exist yet:
--json, each event is one NDJSON
record suitable for a coding agent or log processor:
opencomputer binary from the installed
@opencomputer/cli package. For a one-off invocation outside those scripts,
select the scoped package explicitly:
--keep on supported commands when the session should remain active after
the command exits.
Workspace files
Files an agent writes under/workspace (reports, captures, screenshots, tool
output) can be listed and downloaded with session files. Newly written files
appear gradually and may take a few moments to finish syncing. Refresh or list
the workspace again if a file has just been created.
Downloads never pass through the model or the session transcript: OpenComputer
authorizes the exact versioned workspace object for a short-lived direct
download through its file-delivery edge. The CLI streams that object to disk,
checks its byte count, and computes SHA-256 locally before the file is saved.
cp is an alias for download. Workspace paths may be written relative to
/workspace or with the /workspace/ prefix; paths that leave the workspace
are refused before any request is made. Each download is written to a
temporary file and renamed into place only after the expected byte count is
received; SHA-256 is reported from the completed local file. An interrupted
transfer never leaves a partial file behind. The versioned S3-backed workspace
remains the source of the file in the
CLI, the session page’s Files tab, and the
playground debug inspector.
From an application
Applications create sessions with the management API:POST /api/managed-agents/sessions with an API key, then turns and the event log
under that session. The
TypeScript client wraps those
routes; its sessions.startOnDocument creates a memory document and a
session bound to it in one call. In the browser, the
useAgent hook attaches to a session your server created
and renders its messages.
Input sources
Inside an agent,useInput().source identifies how the current work arrived.
This lets the same agent distinguish direct work from delegated subagent work
without defining another session type.