Skip to Content
Platform

Tasks

A task is one durable execution of a runtime: a single agent conversation you can stream, steer, and revisit.

A task is one execution of a runtime: a single agent conversation from start to finish. Every task runs in its own isolated sandbox, so executions never share filesystem, process, or memory state, and one user’s run can never touch another’s.

Tasks come in two shapes:

  • Interactive: a live session you send follow-up messages to. Between turns the session can sit idle, holding its sandbox open and waiting for the next message until an idle timeout tears it down.
  • One-shot: a single prompt that runs to completion and ends.

Once a task finishes, its replayable record lives on as a conversation, the unit you investigate, judge, and experiment over.

Lifecycle

A task moves through a well-defined set of statuses:

StatusMeaning
pendingCreated, not yet accepted for execution.
queuedAccepted and waiting for a sandbox.
scheduledAssigned to run; sandbox is being provisioned.
runningThe agent is actively working.
awaiting_userThe agent paused on an interrupt (for example a tool permission) and is waiting for the caller to resume.
idleInteractive session is alive and waiting for the next message.
completedFinished successfully.
failedEnded with an error.
cancellingA cancel was requested; the task is winding down.
cancelledCancelled and stopped.

One-shot tasks typically run queuedscheduledrunningcompleted. Interactive tasks return to idle between turns and pick up again at running when you send a new message.

A run can also pause for a human in the loop. When the agent hits an interrupt (for example a tool that needs permission), the task moves to awaiting_user and surfaces what it is blocked on: the task’s metadata lists its pending interrupts until they are answered. The caller answers each interrupt as resolved (optionally with a payload) or cancelled, and the task continues. Resolving every pending interrupt returns the task to running; answering only some keeps it awaiting_user. Resuming is idempotent — re-sending an already-resolved batch is a no-op rather than an error. See the SDK pages (JavaScript, Python) for the resume API.

Each task gets its own isolated sandbox, and there is exactly one task per sandbox. An interactive task’s sandbox stays alive across the idle window so follow-up turns reuse the same filesystem and context.

Task runs

Within a task, a task run is a segment of work opened against a runtime (or against an experiment). A single task can span several runs; each follow-up turn opens a new one.

A run carries a kind that expresses your intent:

KindWhat it does
promptOpens a fresh turn from a prompt.
steerInjects guidance into the turn that’s already in progress. Falls back to prompt if no turn is active.
clearResets context: starts a new conversation in the same task sandbox. Takes no prompt text.

Because runs are the unit of streaming and cancellation, you can watch a run’s output live and cancel a run mid-flight without discarding the task.

A run request with no prompt and no kind is a provision call: on a task that has already finished (completed or failed), it restarts the sandbox without opening a turn and returns the task to pending, so the environment is warm before the next prompt arrives. On a task that is still active it’s a no-op that reports the current status.

Cancelling a run

Cancellation has two modes:

ModeWhat it does
abort (default)Interrupts the in-flight turn immediately and keeps the sandbox warm. The task drops back to idle and the next prompt reuses the same container — what an interactive “stop” button wants. A bodyless cancel aborts.
drainLets the active turn finish and return control, then tears the sandbox down at the next settle boundary. The task lands cancelled and the next prompt cold-boots on a fresh sandbox — the release path. Pass drain_within_seconds to force teardown if the task doesn’t settle in time.

Draining a task that is awaiting_user keeps its pending interrupts in the task metadata, so the human-in-the-loop question survives the teardown: a later resume rehydrates it on a fresh sandbox instead of losing the exchange.

Resumable streams

A run’s live stream can be severed (a network blip, a gateway idle timeout) without losing anything. Re-attach with the last event id you saw (the SSE Last-Event-ID header or a ?since= cursor) and the run replays its recent frames; anything older than the replay window can be hydrated from the task’s conversation record, deduplicating by item id. If you re-attach before the run is live (its sandbox is still provisioning), pass wait_for_start=0 to get a 429 with a Retry-After hint instead of holding the connection open — back off and retry.

Working with tasks in code

The platform task API is available in the SDKs and CLI. JavaScript is shown first; select CLI for the equivalent shell flow.

import { IntrospectionClient } from "@introspection-sdk/introspection-node"; const client = new IntrospectionClient({ token: process.env.INTROSPECTION_TOKEN, }); // Open a runner against a named runtime, bound to an end-user identity. const runner = await client.runtimes("support-agent").run({ identity: { user_id: "user_123" }, }); // Start a task, returns a handle on its initial run. const run = await runner.tasks.start({ prompt: "Summarize my open tickets" }); // Stream the run as typed AG-UI events. for await (const ev of run.stream()) console.log(ev); await runner.close(); await client.shutdown();

A run can be streamed or cancelled mid-flight:

// Cancel an in-progress run. The default aborts the turn and keeps the // sandbox warm, so the task returns to `idle` and stays resumable. await run.cancel();

To release the sandbox after the active turn settles, request drain mode explicitly:

await run.cancel({ mode: "drain", drain_within_seconds: 60 });

The Python SDK accepts the equivalent dictionary, and Rust uses TaskCancelOptions::Drain. Bodyless cancellation remains the backwards-compatible abort path.

For an interactive task, send a follow-up turn by opening another run on the same task. For example, a steer run nudges the agent while it works, or a clear run resets context in the same sandbox.

A RunHandle exposes stream() for the live event feed and cancel() to stop the run. See the API Reference for the full task and run surface, including listing, retrieving, and resuming tasks.

  • Runtimes: the deployable agent version a task executes.
  • Conversations: the immutable, replayable record a task leaves behind.
  • Experiments: A/B tests that runs can be opened against.
  • API Reference: the full task and run API.
Last updated on