Skip to main content

Workflows

Create and execute reusable multi-step workflows, similar to Windsurf’s Workflows feature. Define complex task sequences in markdown files and execute them programmatically.

Quick Start

from praisonaiagents import Agent
from praisonaiagents.memory import WorkflowManager

agent = Agent(name="Assistant")
manager = WorkflowManager()

# Execute a workflow
result = manager.execute(
    "deploy",
    executor=lambda prompt: agent.chat(prompt),
    variables={"environment": "production"}
)

if result["success"]:
    print("Workflow completed successfully!")
    for step_result in result["results"]:
        print(f"  {step_result['step']}: {step_result['status']}")

Workflow File Format

Workflows are defined in markdown files with YAML frontmatter:
---
name: Deploy to Production
description: Deploy the application to production environment
variables:
  environment: production
  branch: main
---

## Step 1: Run Tests
Ensure all tests pass before deployment.

```action
Run the complete test suite with pytest. 
Fail the workflow if any tests fail.

Step 2: Build Application

Build the application for production.
Build the application with production settings.
Environment: {{environment}}
Branch: {{branch}}

Step 3: Deploy

Deploy to the production server.
Deploy the built application to {{environment}}.
Verify the deployment is successful.

Step 4: Notify

Send deployment notification.
Send a notification that deployment to {{environment}} is complete.

## Storage Structure

project/ ├── .praison/ │ └── workflows/ │ ├── deploy.md # Deployment workflow │ ├── test.md # Testing workflow │ ├── review.md # Code review workflow │ └── release.md # Release workflow

## Variable Substitution

Use `{{variable}}` syntax for dynamic values:

```python
from praisonaiagents.memory import WorkflowManager

manager = WorkflowManager()

# Variables defined in workflow file are defaults
# Override at execution time
result = manager.execute(
    "deploy",
    executor=lambda prompt: agent.chat(prompt),
    variables={
        "environment": "staging",  # Override default
        "branch": "feature/new-ui",
        "version": "1.2.3"  # Additional variable
    }
)

Conditional Steps

Add conditions to skip steps based on context:
## Step 3: Deploy to Staging
Only deploy to staging for non-production.

```condition
{{environment}} != production
Deploy to staging environment.

## Callbacks

Monitor workflow execution with callbacks:

```python
from praisonaiagents.memory import WorkflowManager

manager = WorkflowManager()

def on_step(step, index):
    print(f"Starting step {index + 1}: {step.name}")

def on_result(step, result):
    print(f"Completed {step.name}: {result[:100]}...")

result = manager.execute(
    "deploy",
    executor=lambda prompt: agent.chat(prompt),
    on_step=on_step,
    on_result=on_result
)

Error Handling

Configure how steps handle errors:
---
name: Resilient Workflow
---

## Step 1: Optional Cleanup
This step can fail without stopping the workflow.

```action
on_error: continue
max_retries: 2
Clean up temporary files.

Step 2: Critical Build

This step must succeed.
on_error: stop
Build the application.

| Error Mode | Behavior |
|------------|----------|
| `stop` | Stop workflow on failure (default) |
| `continue` | Continue to next step on failure |
| `retry` | Retry the step up to `max_retries` times |

## Programmatic API

```python
from praisonaiagents.memory import WorkflowManager, Workflow, WorkflowStep

manager = WorkflowManager(workspace_path="/path/to/project")

# Get a specific workflow
workflow = manager.get_workflow("deploy")
print(f"Workflow: {workflow.name}")
print(f"Steps: {[s.name for s in workflow.steps]}")

# Get statistics
stats = manager.get_stats()
print(f"Total workflows: {stats['total_workflows']}")
print(f"Total steps: {stats['total_steps']}")

# Reload workflows from disk
manager.reload()

Best Practices

Each step should do one thing well. Break complex tasks into multiple steps for better error handling and visibility.
Step names appear in logs and callbacks. Use clear, descriptive names like “Run Unit Tests” instead of “Step 1”.
Use on_error: continue for optional steps and on_error: stop for critical steps that must succeed.
Add descriptions to workflows and steps. They help users understand what each workflow does.

See Also