Skip to content

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/workflows

Create a new workflow from a template or inline definition.

bash
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:

json
{
  "ok": true,
  "id": "wf-1744730000000",
  "status": "pending"
}

List Workflows

GET /api/v1/workflows

List all workflows with their current status.

bash
curl -H "Authorization: Bearer $TOKEN" \
  https://api.nonsense.ws/api/v1/workflows

Get Workflow

GET /api/v1/workflows/:id

Get workflow details including step statuses and results.

bash
curl -H "Authorization: Bearer $TOKEN" \
  https://api.nonsense.ws/api/v1/workflows/wf-1744730000000

Response:

json
{
  "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/cancel

Cancel a running workflow. Triggers compensation for completed steps.

Delete Workflow

DELETE /api/v1/workflows/:id

Remove a completed or cancelled workflow.

Workflow Lifecycle

Workflows use gen_statem for state management:

pending -> running -> completed
                 \-> failed
                 \-> cancelled
StateDescription
pendingCreated, not yet started
runningExecuting steps
completedAll steps finished successfully
failedA step failed (compensation triggered)
cancelledUser cancelled (compensation triggered)

Step Lifecycle

Each step within a workflow follows its own state machine:

pending -> running -> completed
                 \-> failed
                 \-> skipped

Multi-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

FieldTypeDescription
namestringStep identifier
promptstringTask prompt for the step
modestringAgent mode (build/plan/explore/review/general/coordinate)
toolsarrayRestricted tool set (optional)
timeoutnumberStep timeout in seconds (optional)
conditionstringExecution condition (optional)

Compensation Events

When a step fails or the workflow is cancelled, the workflow engine triggers compensation events:

  1. Completed steps receive a compensate event in reverse order
  2. Each step can define a compensation action (rollback, cleanup, notification)
  3. Compensation failures are logged but do not block other compensations
  4. The workflow transitions to failed or cancelled after all compensations complete

This ensures resources are cleaned up even on partial failures.

Branching

Workflows support branching for conditional execution paths:

json
{
  "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:

bash
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:

bash
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:

bash
curl -N https://api.nonsense.ws/api/v1/events \
  -H "Authorization: Bearer $TOKEN"

Event types:

EventDescription
workflow:startedWorkflow execution began
workflow:step:startedA step began executing
workflow:step:completedA step completed
workflow:step:failedA step failed
workflow:completedWorkflow finished
workflow:failedWorkflow failed
workflow:cancelledWorkflow was cancelled
workflow:compensatingCompensation 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.

Released under the MIT License.