Workflows API
Sol's workflow engine orchestrates multi-step agent tasks using gen_statem instances with compensation, branching, and tree operations. This API covers the full workflow lifecycle.
Create Workflow
POST /api/v1/workflowsCreate a new workflow from a template or inline definition.
curl -X POST https://api.nonsense.ws/api/v1/workflows \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "code-review",
"steps": [
{"name": "analyze", "prompt": "Analyze the code for issues", "mode": "review"},
{"name": "fix", "prompt": "Fix the identified issues", "mode": "build"},
{"name": "verify", "prompt": "Run tests to verify fixes", "mode": "build"}
]
}'Response:
{
"ok": true,
"id": "wf-1744730000000",
"status": "pending"
}List Workflows
GET /api/v1/workflowsList all workflows with their current status.
curl -H "Authorization: Bearer $TOKEN" \
https://api.nonsense.ws/api/v1/workflowsGet Workflow
GET /api/v1/workflows/:idGet workflow details including step statuses and results.
curl -H "Authorization: Bearer $TOKEN" \
https://api.nonsense.ws/api/v1/workflows/wf-1744730000000Response:
{
"id": "wf-1744730000000",
"name": "code-review",
"status": "running",
"steps": [
{"name": "analyze", "status": "completed", "result": "..."},
{"name": "fix", "status": "running"},
{"name": "verify", "status": "pending"}
]
}Cancel Workflow
POST /api/v1/workflows/:id/cancelCancel a running workflow. Triggers compensation for completed steps.
Delete Workflow
DELETE /api/v1/workflows/:idRemove a completed or cancelled workflow.
Workflow Lifecycle
Workflows use gen_statem for state management:
pending -> running -> completed
\-> failed
\-> cancelled| State | Description |
|---|---|
pending | Created, not yet started |
running | Executing steps |
completed | All steps finished successfully |
failed | A step failed (compensation triggered) |
cancelled | User cancelled (compensation triggered) |
Step Lifecycle
Each step within a workflow follows its own state machine:
pending -> running -> completed
\-> failed
\-> skippedMulti-Step Execution
Workflows execute steps sequentially by default. Each step receives:
- The original prompt
- Results from previous steps
- Step-specific configuration (mode, tools, timeout)
The user_uuid is propagated from the HTTP request through each step dispatch, ensuring multi-tenant isolation.
Step Configuration
| Field | Type | Description |
|---|---|---|
name | string | Step identifier |
prompt | string | Task prompt for the step |
mode | string | Agent mode (build/plan/explore/review/general/coordinate) |
tools | array | Restricted tool set (optional) |
timeout | number | Step timeout in seconds (optional) |
condition | string | Execution condition (optional) |
Compensation Events
When a step fails or the workflow is cancelled, the workflow engine triggers compensation events:
- Completed steps receive a
compensateevent in reverse order - Each step can define a compensation action (rollback, cleanup, notification)
- Compensation failures are logged but do not block other compensations
- The workflow transitions to
failedorcancelledafter all compensations complete
This ensures resources are cleaned up even on partial failures.
Branching
Workflows support branching for conditional execution paths:
{
"name": "conditional-review",
"steps": [
{"name": "check", "prompt": "Check if tests pass", "mode": "build"},
{
"name": "branch",
"type": "branch",
"conditions": {
"pass": {"match": "{{check.result}}", "pattern": ".*passed.*", "then": "deploy"},
"fail": {"then": "fix"}
}
},
{"name": "deploy", "prompt": "Deploy to production", "mode": "build"},
{"name": "fix", "prompt": "Fix the failing tests", "mode": "build"}
]
}Tree Operations
Workflows can be organized as trees for complex orchestration:
- Parent-child relationships between workflow instances
- Spawn child workflows from a parent step
- Aggregate results from child workflows
- Tree-level cancellation propagates to all children
Workflow Templates
Reusable workflow templates can be stored and instantiated:
curl -X POST https://api.nonsense.ws/api/v1/workflows/templates \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "standard-review",
"steps": [...]
}'Instantiate from a template:
curl -X POST https://api.nonsense.ws/api/v1/workflows \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"template": "standard-review", "variables": {"project": "my-app"}}'Streaming Workflow Events
Workflow state changes are broadcast via SSE:
curl -N https://api.nonsense.ws/api/v1/events \
-H "Authorization: Bearer $TOKEN"Event types:
| Event | Description |
|---|---|
workflow:started | Workflow execution began |
workflow:step:started | A step began executing |
workflow:step:completed | A step completed |
workflow:step:failed | A step failed |
workflow:completed | Workflow finished |
workflow:failed | Workflow failed |
workflow:cancelled | Workflow was cancelled |
workflow:compensating | Compensation in progress |
Event Store Integration
Workflow events are stored in the Mnesia-backed event store (35 event types). Pre- and post-hooks enable:
- Audit logging of all workflow mutations
- Real-time notifications via the PUB/SUB event bridge
- Plugin reactions to workflow state changes
- Historical replay for debugging
The workflow bridge subscribes to the event store and dispatches step tasks to workers via ZMQ, propagating user_uuid for multi-tenant isolation.