Open the console

Concepts

Agents and workflows

An agent is one model loop with tools: it decides what to do next. A workflow is a graph of nodes with a declared shape: it is told. Both are targets — deployed the same way, started by the same route, and addressed by their own name.

Which one to write

Write an agent when the path depends on the conversation — when you cannot say in advance which tool is needed, or how many times. Write a workflow when you already know the steps and want each one to be separately observable, retryable and resumable. A workflow is not a faster agent; it is a different promise about what will happen.

Nothing about the choice is visible to a caller. Both are invoked with POST /v1/invocations, both emit the same event stream, and a target's kind is in the manifest facts GET /v1/agents reports, if you need to know.

What a graph is made of

Nodes, of two kinds that behave differently enough to matter. A model node calls a model. A function node runs your Python. Edges wire them together, and an edge can branch: a node names a route and the edge maps route names to the next node, with a default for anything unnamed — so an unexpected answer falls to the branch you chose rather than to whichever was listed first. Along every edge, each node receives the previous node's output as its input — which is the single fact most worth holding on to, because two of the surprises below follow from it.

A workflow has no model of its own; each model node takes one. And it has no conversation compaction, because the framework builds its summarizer from the root agent's model and a graph's root is never a model node.

Put the models at the end

A model node between two function nodes hands the second one a sentence where it expected a structured value. The graph builds, the run starts, and the failure is a type error deep inside your own code rather than anything naming the model. If a function node needs data, it should be fed by something that returns data.

A function node at the end returns nothing to the caller

A tool call's result is the last content the callee produced, and a function node's return value is carried as an output rather than as content. So a graph whose final node is a function node answers its caller with nothing — unless that node returns an event carrying explicit content.

A workflow declares what it is launched with

An agent takes a message. A workflow takes named inputs, declared in its manifest, and those declarations become the graph's state schema. That is what turns a whole class of mistake into a build-time error: a graph whose function node asks for a parameter the schema does not declare refuses to be constructed, rather than raising halfway through a run in front of a user.

The same reasoning is why an optional input must declare a default, and is refused without one. A node reads its parameters out of session state, where a missing key raises rather than arriving as None — so every declared input is made to resolve to a value, and a caller never has to send nulls to make that true.

Pausing, and what a resume replays

A workflow is the thing that pauses most: a node can stop and ask a person for an approval or a value. A target that should be able to do this declares itself resumable.

  1. A node pauses. The run stops there — deliberately, because a human can outlast any delivery deadline. It emits no terminal event; read the interrupt id instead.
  2. You answer it on the resume route, with the decision and, if the node asked for one, a value.
  3. The prefix replays. The run keeps its invocation id and the nodes that already completed are re-emitted without being re-run — no extra model calls, and nothing is charged twice.

The replay looks like re-execution, and it has a trap

A replayed node keeps its path but gets a fresh event id. A client that deduplicates on the id therefore renders the entire pre-pause run a second time. Deduplicate on the node path.

A pause is answered without a person in exactly one case: its node is declared at tier t2 in the manifest's per-node settings. A stored policy cannot make a gate delegable that the graph never offered, because a pause written into a graph is authority its author placed there. A workflow that is not resumable also keeps no per-node checkpoint, so a run view has to infer each step's status from its events.

Node identity is the path, not the author

Only model nodes set an event author; a function node is invisible there, and so is the replay, which is authored by the workflow rather than by the node. Group a trace by the node path or every function node in the graph folds into one unnamed bucket.

Calling a workflow from an agent

An agent can be handed a workflow as a tool, and the model is then offered the workflow's declared inputs as typed parameters. It goes through the platform's WorkflowTool, not the framework's own agent tool, which cannot wrap a graph — it probes for sub-agents a graph does not have and raises, once when the tool is declared and again in front of a user.

A nested run like that fires no plugin callbacks. That is what keeps billing from opening a second deposit for the inner run, and it has a consequence for policy worth knowing separately: an autonomy tier governs the graph at its boundary — the one tool call into it — and not per tool inside it.

Where to go next

Building a workflow is the hands-on version of this page. The invocations API shows a sample of each shape — an agent and a workflow — side by side on the start endpoint. Sessions and runs covers what a run goes through, and the sessions API has the per-node projection that answers “where did this workflow get to” after a reload.

Reading this as a model? llms.txt indexes every page, and each page has a “Copy for AI” control.