Sessions and runs
A session is the continuity boundary for one enabled agent version: its workspace, files, and interactions. A run is one admitted unit of execution inside it. Keep both IDs: the session tells you where state lives; the run tells you what happened during one request.
- SessionreadyAccepts work
- Run 1runningFirst request
- InteractionpendingRun 1 waits
- Run 1succeededTerminal
- SessionidleReusable
- Run 2runningLater request
- Run 2failedTerminal
- SessionidleCan run again
Session ready → Run 1 running → interaction pending (awaiting_input: true) → Run 1
succeeded → session idle → Run 2 running → Run 2 failed → session idle.
Run 2 starts only after Run 1 is terminal; the failed second run does not erase the first or end the session.
Choose the invocation boundary
Section titled “Choose the invocation boundary”| Choose | When it fits | Tradeoff |
|---|---|---|
| One-shot invocation | One independent request where immediate streaming is the main goal. | Tanomis creates a session and run and returns their IDs in X-Session-ID and X-Run-ID, but retrying the request creates a new session boundary. |
| Explicit session | Retries, multiple runs, durable interaction, files, or reconnecting to events matter. | Two requests to begin: create the session, then start the run. |
One-shot still creates durable resources; record the IDs it returns. For anything your product depends on, create the session explicitly.
Read resource state
Section titled “Read resource state”Session status describes whether the continuity boundary can accept or continue work:
| Session status | Meaning |
|---|---|
creating |
Tanomis is provisioning the session. |
ready |
The session is prepared and can accept a run. |
running |
A run is active. |
idle |
No run is active; the session can be reused. |
stopping |
Stop is fencing new work and releasing the active runtime. |
stopped |
The session was explicitly stopped and must be resumed before another run. |
failed |
Session activation or runtime failed; explicit resume can attempt recovery. |
expired |
The session reached its lifecycle limit; explicit resume can reactivate it. |
Run status describes one execution attempt:
| Run status | Meaning |
|---|---|
queued |
Admitted and waiting for dispatch. |
running |
Executing or waiting on a durable human interaction. |
succeeded |
Completed successfully. |
failed |
Ended with an error; inspect error_code and error_message when present. |
cancelled |
Ended after cancellation. |
succeeded, failed, and cancelled are terminal. A terminal run stays readable through the
run resource, and the session returns to idle for the next run.
One run at a time
Section titled “One run at a time”One session admits at most one active run, where active means queued or running. Starting
another run while one is active returns 409 Conflict. Wait for a terminal state, use another
session for independent concurrency, or retry the same run idempotently. Terminal runs do not hold
the slot, so a reused session is an ordered history:
session A run 1: succeeded run 2: failed run 3: runningFiles and durable interactions belong to the session. Attachments select session files for one run; they do not move the files anywhere.
Make retries deliberate
Section titled “Make retries deliberate”Use a stable idempotency key for one logical operation and never recycle it for new intent. Keys are opaque, at most 255 bytes, and scoped differently at each boundary:
| Operation | Same key | Changed intent or no key |
|---|---|---|
| Create session | For the same authenticated caller, tenant, and provisioning inputs, returns the original non-terminal session with 200 OK. |
Changed provisioning inputs return 409 Conflict. Reusing the key after the original session is stopped, failed, or expired returns 412 Precondition Failed. Omitting the key creates a new session. |
| Start run | Within the same session, returns the original active or terminal run; a JSON replay is 200 OK, while a streaming replay follows the original event stream. |
Changed input, model, or work does not replace the original run, so bind the key to one immutable request in your client. Attachment-set drift returns 409 Conflict. A new or absent key starts a new run only when no run is active; otherwise it returns 409 Conflict. |
The run key is scoped to the session; the same string in another session refers to nothing. A one-shot retry creates another session first, so a run key in its body cannot make the whole one-shot operation retry-safe.
Inspect, cancel, stop, and resume
Section titled “Inspect, cancel, stop, and resume”Resource reads are authoritative. A stream close, command exit, or accepted cancellation does not replace them.
| Action | Request | Then |
|---|---|---|
| Read | GET /v1/sessions/{session_id} and GET /v1/sessions/{session_id}/runs/{run_id} |
Use the run’s status; the session read carries awaiting_input. |
| Cancel | POST /v1/sessions/{session_id}/runs/{run_id}/cancel |
Read the run until it is terminal. The session’s history is untouched. |
| Stop | POST /v1/sessions/{session_id}/stop |
Stop fences new runs and settles active work before stopped. A conflict during admission means the boundary is still settling: inspect and retry. |
| Resume | POST /v1/sessions/{session_id}/resume |
Resume only a stopped, failed, or expired session. It keeps the session ID and pinned version and returns to ready; on a live session it conflicts. |
Handle a run waiting for a person
Section titled “Handle a run waiting for a person”Availability: Durable interactions are on in hosted Tanomis and operator-enabled when self-hosted. See What is available where.
A pending interaction adds no run status. The run remains running; a session read exposes the
derived signal awaiting_input: true. List the session’s pending interactions, answer by the
stable interaction_key, and keep observing the same run. Tanomis may suspend and restore the
runtime while it waits without changing the public model. The full first-answer-wins flow is in
Approval-required actions.
A run may instead bind to durable settlement work that can continue from a later session; see Durable work and settlement.
Keep lineage separate
Section titled “Keep lineage separate”A later run continues the same session. It is not a fork and it is not a delegated session; those create separate lineage and authority and have their own guides.
Where to go next
Section titled “Where to go next”- Invoke from your application: the six-step flow from a backend.
- Stream and replay events: watching a run safely.
- Session workspace and state: what persists.