Vizra.ai |

Documentation

🔄

Workflow Class Reference

Orchestrate agents like a conductor! 🎼 The BaseWorkflowAgent turns you into a master of AI coordination - chain agents together, create complex flows, and build intelligent automation pipelines that would make any DevOps engineer jealous!

Class Overview

namespace Vizra\VizraADK\Agents;

abstract class BaseWorkflowAgent extends BaseAgent
{
    // Workflow agents extend this class
}

BaseWorkflowAgent Properties

Property Type Default Description
$steps array [] Array of workflow steps
$results array [] Step execution results
$timeout int 300 Workflow timeout (seconds)
$retryAttempts int 0 Default retry attempts
$retryDelay int 1000 Retry delay (milliseconds)

Key Methods

executeWorkflow()

abstract protected function executeWorkflow(mixed $input, AgentContext $context): mixed

Each workflow type must implement this method to define its execution logic.

addAgent()

public function addAgent(
    string $agentClass,
    mixed $params = null,
    array $options = []
): static

Add an agent step to the workflow using the agent class name.

Workflow Methods

Configuration Methods

// Set timeout for the entire workflow
$workflow->timeout(300); // 5 minutes

// Set retry policy
$workflow->retryOnFailure(3, 1000); // 3 attempts, 1s delay

// Set callbacks
$workflow->onSuccess(function($result, $stepResults) {
    Log::info('Success!', ['result' => $result]);
});

$workflow->onFailure(function(\Throwable $e, $stepResults) {
    Log::error('Failed: ' . $e->getMessage());
});

$workflow->onComplete(function($result, $success, $stepResults) {
    // Always runs
});

Result Access Methods

// Get all results
$allResults = $workflow->getResults();

// Get specific step result
$stepResult = $workflow->getStepResult(DataProcessor::class);

// Reset workflow for reuse
$workflow->reset();

Workflow Types

Sequential Workflow

use Vizra\VizraADK\Agents\SequentialWorkflow;
use App\Agents\AnalyzerAgent;
use App\Agents\ProcessorAgent;
use App\Agents\ValidatorAgent;
use App\Agents\CleanupAgent;

$workflow = new SequentialWorkflow();

// Add steps in sequence
$workflow
    ->start(AnalyzerAgent::class, 'Analyze input')
    ->then(ProcessorAgent::class, fn($prev) => "Process: " . $prev)
    ->when(ValidatorAgent::class, fn($input, $results) =>
        $results[ProcessorAgent::class]['status'] === 'needs_validation'
    )
    ->finally(CleanupAgent::class); // Always runs

// Execute
$result = $workflow->execute('Input data');

Parallel Workflow

use Vizra\VizraADK\Agents\ParallelWorkflow;
use App\Agents\EmailSender;
use App\Agents\SmsSender;
use App\Agents\WebhookCaller;

$workflow = new ParallelWorkflow();
$workflow
    ->agents([
        EmailSender::class => 'Send email notification',
        SmsSender::class => 'Send SMS',
        WebhookCaller::class => 'Call webhook'
    ])
    ->waitForAll(); // or waitForAny()

Conditional Workflow

use Vizra\VizraADK\Agents\ConditionalWorkflow;
use App\Agents\UrgentHandler;
use App\Agents\SupportAgent;
use App\Agents\DefaultHandler;

$workflow = new ConditionalWorkflow();
$workflow
    ->when(
        fn($input) => $input['priority'] === 'high',
        UrgentHandler::class
    )
    ->when(
        fn($input) => $input['type'] === 'support',
        SupportAgent::class
    )
    ->otherwise(DefaultHandler::class);

Loop Workflow

use Vizra\VizraADK\Agents\LoopWorkflow;
use App\Agents\ProcessorAgent;
use App\Agents\ItemProcessor;

// While loop
$workflow = new LoopWorkflow();
$workflow->while(
    ProcessorAgent::class,
    fn($result) => $result['continue'] === true,
    10 // max iterations
);

// For each loop
$items = ['item1', 'item2', 'item3'];
$workflow = new LoopWorkflow();
$workflow->forEach(ItemProcessor::class, $items);

Step Parameters

Dynamic Parameters

// Static parameters
$workflow->addAgent('agent_name', 'Static input');

// Dynamic parameters with closure
$workflow->addAgent(
    'processor',
    fn($input, $results, $context) => [
        'data' => $results['previous_agent'],
        'mode' => $context->getState('processing_mode')
    ]
);

// Step options
$workflow->addAgent('risky_agent', 'Input', [
    'retries' => 5,
    'timeout' => 60,
    'condition' => fn() => config('app.env') === 'production'
]);

Creating Custom Workflows

use App\Agents\FirstAgent;

class CustomWorkflow extends BaseWorkflowAgent
{
    protected string $name = 'custom_workflow';
    protected string $description = 'Custom workflow implementation';

    protected function executeWorkflow(mixed $input, AgentContext $context): mixed
    {
        // Custom workflow logic
        $result1 = $this->executeStep([
            'agent' => 'first_agent',
            'params' => $input,
            'retries' => 2
        ], $input, $context);

        // Access previous results
        $allResults = $this->getResults();

        return [
            'workflow_type' => 'custom',
            'results' => $allResults
        ];
    }
}

Running Workflows

Basic Execution

// Workflows are agents, so they run like any agent
$workflow = new SequentialWorkflow();
$workflow
    ->then('agent1')
    ->then('agent2');

// Execute with input
$result = $workflow->execute('Process this data');

// Or with context
use Vizra\VizraADK\System\AgentContext;

$context = new AgentContext('session-123');
$result = $workflow->run('Input data', $context);

Using the Workflow Facade

use Vizra\VizraADK\Facades\Workflow;

// Create and execute in one go
$result = Workflow::sequential('agent1', 'agent2', 'agent3')
    ->execute('Input data');

// With callbacks
$workflow = Workflow::sequential('agent1', 'agent2')
    ->onSuccess(function($result) {
        Log::info('Workflow completed!', ['result' => $result]);
    });

$result = $workflow->execute('Start');

Workflow Results

Sequential Workflow Results

// Sequential workflow returns
{
    'final_result': 'Last agent output',
    'step_results': {
        'agent1': 'First result',
        'agent2': 'Second result'
    },
    'workflow_type': 'sequential'
}

Parallel Workflow Results

// Parallel workflow returns
{
    'results': {
        'agent1': 'Result 1',
        'agent2': 'Result 2'
    },
    'completed': ['agent1', 'agent2'],
    'workflow_type': 'parallel'
}

Error Handling

// Set retry policy for all steps
$workflow->retryOnFailure(3, 1000);

// Handle errors with callbacks
$workflow->onFailure(function(\Throwable $e, $stepResults) {
    // Log the error
    Log::error('Workflow failed', [
        'error' => $e->getMessage(),
        'completed_steps' => array_keys($stepResults)
    ]);

    // Perform cleanup
    CleanupService::rollback($stepResults);
});

Complete Example

<?php

namespace App\Workflows;

use Vizra\VizraADK\Agents\SequentialWorkflow;
use Vizra\VizraADK\System\AgentContext;
use App\Agents\OrderValidator;
use App\Agents\InventoryChecker;
use App\Agents\PaymentProcessor;
use App\Agents\ShippingCreator;
use App\Agents\NotificationSender;
use App\Agents\OrderLogger;

class OrderProcessingWorkflow extends SequentialWorkflow
{
    protected string $name = 'order_processor';
    protected string $description = 'Process customer orders through fulfillment';

    public function __construct()
    {
        parent::__construct();

        // Configure workflow
        $this->timeout(300) // 5 minutes
             ->retryOnFailure(2, 2000); // 2 retries, 2s delay

        // Define the workflow steps
        $this
            ->start(OrderValidator::class, fn($input) => [
                'order_id' => $input['order_id']
            ])
            ->then(InventoryChecker::class, fn($prevResult) =>
                $prevResult['items']
            )
            ->when(
                PaymentProcessor::class,
                fn($input, $results) =>
                    $results[InventoryChecker::class]['available'] === true,
                fn($input, $results) => [
                    'amount' => $results[OrderValidator::class]['total'],
                    'payment_method' => $input['payment_method']
                ]
            )
            ->then(ShippingCreator::class)
            ->then(NotificationSender::class, 'Send order confirmation')
            ->finally(OrderLogger::class); // Always runs

        // Set callbacks
        $this->onSuccess(function($result, $stepResults) {
            Log::info('Order processed successfully', [
                'order_id' => $stepResults[OrderValidator::class]['order_id']
            ]);
        });

        $this->onFailure(function(\Throwable $e, $stepResults) {
            // Rollback any completed steps
            if (isset($stepResults[PaymentProcessor::class])) {
                PaymentService::refund(
                    $stepResults[PaymentProcessor::class]['transaction_id']
                );
            }
        });
    }
}

💡 Workflow Best Practices

  • Workflows are agents - they extend BaseWorkflowAgent
  • Use the appropriate workflow type for your use case
  • Set reasonable timeouts and retry limits
  • Leverage callbacks for monitoring and debugging
  • Pass results between steps using closures
  • Handle errors at both step and workflow levels
  • Test workflows with various input scenarios

Ready for Professional AI Agent Evaluation? 🚀

Evaluate and debug your Vizra ADK agents with professional cloud tools. Get early access to Vizra Cloud and be among the first to experience advanced evaluation and trace analysis at scale.

Cloud evaluation runs
Trace visualization
Team collaboration

Join other developers already on the waitlist. No spam, just launch updates.