Skip to main content
A session is an agent run with an append-only event log, a pinned configuration snapshot, and a lifecycle status. The execution substrate depends on the runtime: built-in runtimes use managed sandboxes, while Flue uses a deployed Worker and one Durable Object per session.
The dashboard lists your sessions and opens each with a live event stream you can watch and steer — handy for following or debugging a run without building UI.

Session flow

  1. You create a session from an agent. Built-in runtimes pin the active revision, including its prompt, model, and skills. Flue records the selected deployment, but all of an agent’s Flue sessions execute on its one live Worker; see Flue deployment behavior.
  2. OpenComputer stores the input, allocates a turn, and returns. Runtime execution continues asynchronously. Pass model to override a built-in runtime’s model for this session; Flue rejects model overrides because its model is part of the deployed app.
  3. The runtime appends events as it works. Built-in runtimes execute in managed sandboxes. Flue executes in its Worker and Durable Object, with no sandbox unless the app explicitly uses ocSandbox.
  4. With nothing left to do, the session becomes idle. A steer message starts the next ordered turn with the same conversation context.
Pass sources to give a session working repositories. Built-in runtimes prepare them before turn one. Flue keeps the same pinned source contract but materializes a repository lazily, when its app first uses the repository tools.
The built-in runtimes restart from checkpointed state, enforce a turn deadline, and survive sandbox reclaim. Flue relies on Durable Object recovery and event projection instead; its current limit and recovery differences are listed on the Flue page.

Lifecycle

A session also carries last_turn = { id, state, yield_reason?, result_event_id? }; the fuller turn record (started_at, completed_at, active_seconds, usage, error) comes from GET …/result and …/turns. The yield_reason tells you why the last turn ended: completed, needs_input (the agent asked a question and the session is now awaiting_input), budget_exceeded, deadline_exceeded, max_turns, or canceled. Limit outcomes require runtime enforcement; the current Flue path does not enforce the generic session limits below.

Fetch the result

Do not infer completion from prose. Await the turn.completed event (on the stream or a webhook), then fetch the answer:
Response:
For background jobs, register a destination. Polling GET /…/result ties up a request and doesn’t survive your process restarting. Create the session with metadata and a destination; handle turn.completed in your webhook, then fetch the result. Reserve result() polling for synchronous or interactive flows.

Idempotency & routing

Three independent knobs — don’t overload one for another:
  • keyget-or-create. One session per natural key (e.g. one per PR). A second create with the same key returns the same session; reusing a key with a different request body is rejected (create key already used with a different request).
  • Idempotency-Key (header) — retry-safe create. Makes a keyless create safe to retry (e.g. on a webhook redelivery) without spawning duplicates.
  • metadatarouting / app state. Opaque JSON (≤ 16 KB) echoed back on get/list and verbatim in webhooks, so your callback can route to the right record. Never use key for routing — that’s what metadata is for.

Usage and limits

Terminal turns expose active_seconds and normalized usage. A reported turn contains four disjoint token components, their tokens sum, and optional total_cost_usd. Missing cost means unknown, not zero. If only some runtime observations were trustworthy, the turn keeps that lower bound and adds complete: false; a turn with no trustworthy observation returns reported: false instead of inventing a zero. The session usage rollup contains:
If complete is false, any token or cost total present is a lower bound. Historical sessions created before usage reporting may return an empty object; clients should show that as unknown. total_cost_usd is runtime/provider- reported visibility, not the billing ledger. Cap a session at create (or default it on the agent) with limits: { tokens, turn_seconds, turns }: an observed token threshold, per-turn wall-clock limit, and auto-run count. These are runtime limits, not currency or aggregate spend controls. On built-in runtimes, limits.tokens is evaluated from committed usage before the next model turn. It does not interrupt an in-flight request and can overshoot by one turn. turn_seconds and the organization’s credit halt are separate controls. A Hook starts a fresh session, so all three limits reset on every accepted Hook POST.
Flue exposes best-effort per-session usage attribution; its agent/org gateway remains the spend-enforcement authority. The generic session limits are not enforced on the current Flue execution path, so do not use them as its deadline, turn-count, or token safety boundary.

Model

A session runs the model pinned in its agent snapshot. Pass model at create to run this one session on a different model — omit it and the session inherits the agent’s model (the default). The override is the same provider/model form as the agent’s model, and its provider must match the agent’s runtime (e.g. anthropic/… for a claude agent — a mismatched prefix is rejected at create, a model the provider doesn’t recognize fails on the first turn). Like the rest of the snapshot it’s pinned for the session’s life — there’s no mid-session model switch; start another session to run another model. Not available for Flue agents: their model is fixed in the deployed app, so a model on a Flue session is rejected.

Stop a session

POST /sessions/:id/cancel requests a cooperative stop: the turn ends at its next checkpoint with a turn.completed (yield_reason: "canceled"), so an in-flight model call may run to its timeout — billing for that turn stops when it actually exits, not the instant you call. POST /sessions/:id/archive cancels any active turn, then closes the session read-only. archive is not delete — the session’s log is retained, just read-only. For Flue, archive also retains the conversation in the session’s Durable Object storage. See Flue session behavior.
When the agent needs input, the turn ends with yield_reason: "needs_input" and the session status becomes awaiting_input; reply by steering.
No cross-session memory. Each session starts from the agent’s prompt + that session’s input — a durable log is session history, not memory the agent carries between sessions.