Workflows (/app/workflows) cover two models in one sidebar entry: (1) legacy linked-agent workflow records with a React Flow orchestration canvas, and (2) workflow chains — lightweight primitive-based orchestrations edited at /app/workflows/chains/{slug}/edit. Sidebar badge counts both. Nothing is auto-seeded.
Landing page
- Orchestrations header with primitives legend (trigger, assistant, agent, decide, webhook, schedule, notify, human).
- chain them! design cue for composing chains.
- Chain cards — GET /v1/workflow-chains: status, summary, when_label, primary_steps preview, branch previews, run stats.
- Legacy workflow cards — open full workflow shell with flow canvas.
- New chain — POST /v1/workflow-chains and open the primitive form editor.
- New graph workflow — dialog creates a legacy React Flow orchestration (PUT graph after create).
Access control
Workflow APIs use capability-based RBAC (mapped to workspace roles). Chain and graph routes no longer rely on coarse role checks alone.
| Capability | Minimum role | Used for |
|---|---|---|
| workflow.read | Viewer | List/read workflows and chains, validate-publish, paginated history |
| workflow.write | Editor | Create/update workflows, chains, save graph drafts |
| workflow.publish | Developer | Publish, delete workflows, restore versions |
| runtime.simulate | Editor | Simulator sessions, chain run/resume/ingress (studio) |
| runtime.sessions.read_all | Developer | Cross-agent session lists (assistant simulator) |
Workflow chains
Chains are edited in a dedicated form editor (not the React Flow canvas). PATCH /v1/workflow-chains/{slug} persists all fields. Run history is available per chain via GET /v1/workflow-chains/{slug}/runs and GET .../runs/{run_id}.
| Field | Description |
|---|---|
| name | Display name on the card |
| status | draft | live | paused |
| summary | One-line description on the card |
| when_label | Trigger description (e.g. On webhook received) |
| primary_steps | Ordered list of { kind, label, config } primitives |
| branches | Named branches each with their own step list |
Chain primitives
- trigger — entry condition label
- assistant — invoke a published Assistant by label/slug match
- agent — invoke an AI Agent (playground runtime) by label
- decide — branch on a condition label (substring match on running output)
- webhook — outbound HTTP POST (url, secret, retries in step config); secret also used for inbound HMAC verification
- human — pauses run as awaiting_human until POST .../runs/{run_id}/resume
- schedule — records deferred-execution intent (external scheduler)
- notify — email via Resend/SMTP/console to email_to in config
Chain run & ingress
- POST /v1/workflow-chains/{slug}/run — studio test run (runtime.simulate, rate-limited)
- POST /v1/workflow-chains/{slug}/runs/{run_id}/resume — continue awaiting_human runs
- POST /v1/workflow-chains/{slug}/ingress — authenticated inbound webhook (HMAC + runtime.simulate)
- POST /v1/public/workflow-chains/{workspace_slug}/{chain_slug}/ingress — public inbound webhook (HMAC only, no cookie)
- Sign the raw JSON body with HMAC-SHA256 using the webhook step config.secret; send header X-Chain-Signature (hex or sha256=<hex>). Body: {"message": "..."}.
Legacy workflow graph
Opening a workflow at /app/workflows/{id} shows the workflow shell rail. The Flow tab is a React Flow canvas. Draft graphs are saved with PUT /v1/workflows/{id}/graph (creates a new draft version). Publishing promotes the latest draft to a live version.
Workflow shell rail
| Tab | Route | Purpose |
|---|---|---|
| Flow | /flow | Orchestration canvas — palette + edge conditions |
| Flow agents | /flow-agents | Bind published Assistants into flow-agent nodes |
| AI agents | /ai-agents | Configure instruction-agent nodes (LLM + tools) |
| Tools | /tools | Workspace tools available to instruction-agent and tool nodes |
| Events | /events | Workflow-level welcome/fallback style events when enabled |
| Channels | /channels | Deploy workflow to external surfaces |
| Publish | /publish | Validate draft, publish, version table, compare, restore to new draft |
| History | /history | Paginated simulator sessions (limit/offset) and per-session turns |
| Analytics | /analytics | Workflow daily rollups (sessions, completion, channels). Intent/funnel views are off — those are agent-scoped. |
| Import / Export | /import, /export | Workflow JSON backup |
| Settings | /settings | Name, description, orchestration variables |
Publish & versions
- POST /v1/workflows/{id}/validate-publish — schema + runtime publish rules (Studio calls this before Publish)
- POST /v1/workflows/{id}/publish — promotes latest draft (workflow.publish)
- GET /v1/workflows/{id}/versions — list versions with limit/offset
- POST /v1/workflows/{id}/versions/{version_id}/restore — copy an older graph into a new draft
- Blocked node types at publish: script, datastore, set, human, parallel, wait
- Router/decision nodes must have at least one outgoing edge with condition.expr
Rate limits
Workspace Agent ops setting rpm_cap_per_agent applies per workflow id and per chain id for simulator starts, workflow turns, and chain run/resume/ingress (Redis-backed when Redis is available; 0 = unlimited). Additional slowapi limits apply on graph save, publish, restore, and chain endpoints.
Workflow vs single Assistant
| Assistant | Workflow | |
|---|---|---|
| Scope | One bot, intent sub-flows | Multi-bot orchestration graph or primitive chain |
| Editor | Intents + per-intent canvas | Workflow flow canvas or chain editor |
| Publish | Assistant Publish tab | Workflow Publish tab + validate-publish |
| Typical pattern | Single channel widget | Agent qualifies → Assistant runs regulated form |
API (summary)
# Workflow chains
GET/POST /v1/workflow-chains
GET/PATCH/DELETE /v1/workflow-chains/{slug}
POST /v1/workflow-chains/{slug}/run
GET /v1/workflow-chains/{slug}/runs
GET /v1/workflow-chains/{slug}/runs/{run_id}
POST /v1/workflow-chains/{slug}/runs/{run_id}/resume
POST /v1/workflow-chains/{slug}/ingress
POST /v1/public/workflow-chains/{workspace_slug}/{chain_slug}/ingress
# Legacy graph workflows
GET/POST /v1/workflows
GET/PATCH/DELETE /v1/workflows/{id}
PUT /v1/workflows/{id}/graph
POST /v1/workflows/{id}/validate-publish
POST /v1/workflows/{id}/publish
GET /v1/workflows/{id}/versions
POST /v1/workflows/{id}/versions/{version_id}/restore
# Workflow simulator & history
POST /v1/runtime/workflows/{id}/sessions
POST /v1/runtime/workflows/sessions/{session_id}/turns
GET /v1/runtime/workflows/{id}/sessions?limit=&offset=See Workflow canvas and Chain editor pages for node types, edge routing, and simulator behavior. Public workflow channel traffic uses deployment tokens via /v1/public/runtime/* (see Channels & deploy).