Workflows
Introduction
Section titled “Introduction”A workflow is a graph you define. Each node is a step, such as an HTTP call, a model call, a tool call, a condition or an approval. Edges wire one node’s output to the next node’s input. The graph fixes the order, the branching and the data. When a model is involved, it decides only inside its own node.
Use a workflow when you want the same steps in the same order every time. Use an agent when you want a model to choose which tools to call.
A complete example
Section titled “A complete example”This workflow receives a support message, asks a model whether it is urgent, and pages the on-call person only if it is. It uses a webhook trigger, an llm node, an if node and a tool node.
{ "name": "Triage support message", "nodes": [ { "id": "start", "type": "trigger.webhook", "config": {} }, { "id": "classify", "type": "llm", "config": { "profileId": "default", "system": "You triage support messages.", "prompt": "Is this message urgent? Message: {{ $input.text }}", "schema": { "type": "object", "properties": { "urgent": { "type": "boolean" }, "summary": { "type": "string" } }, "required": ["urgent", "summary"] } } }, { "id": "check", "type": "if", "config": { "conditions": [{ "left": "{{ $node.classify.urgent }}", "operator": "truthy" }] } }, { "id": "page", "type": "tool", "config": { "tool": "notify_oncall", "input": { "message": "{{ $node.classify.summary }}" } } }, { "id": "paged", "type": "output", "config": { "name": "result", "value": "Paged on-call" } }, { "id": "skipped", "type": "output", "config": { "name": "result", "value": "Not urgent" } } ], "edges": [ { "from": { "node": "start", "port": "out" }, "to": { "node": "classify", "port": "in" } }, { "from": { "node": "classify", "port": "out" }, "to": { "node": "check", "port": "in" } }, { "from": { "node": "check", "port": "true" }, "to": { "node": "page", "port": "in" } }, { "from": { "node": "page", "port": "out" }, "to": { "node": "paged", "port": "in" } }, { "from": { "node": "check", "port": "false" }, "to": { "node": "skipped", "port": "in" } } ]}profileId names a model profile on your server, and notify_oncall is a tool you registered (see Tools). The workflow reads the run input with {{ $input.text }} and a node’s output with {{ $node.classify.urgent }}.
Create the workflow and start a run:
curl -X POST $API/workflows -H 'content-type: application/json' -d @triage.json# 201 { "id": "wf_...", ... }
curl -X POST $API/workflows/$ID/runs -H 'content-type: application/json' \ -d '{"input":{"text":"Checkout is down for every customer"}}'# 201 { "id": "run_...", "status": "running", ... }
curl $API/workflows/$ID/runs/$RUN_ID# { "status": "finished", "output": { "result": "Paged on-call" }, ... }The server mints the workflow id, so the definition you post has none. Add your usual authorization header to each call.
Turn the feature on
Section titled “Turn the feature on”PilotooModule.forRoot({ workflowSandbox: sandbox, // only if you use `code` nodes workflowTools: true, // lets agents list and run workflows});WORKFLOW_ROLES=member,ownerAll options are in Server integration.
Next steps
Section titled “Next steps”- Building workflows: the format, every node kind, expressions and validation.
- Running workflows: start runs, follow events, answer approvals.
- Triggers: start a workflow by hand, from a webhook or on a schedule.
- Server integration: module options, REST routes, the visual builder and agent tools.