🔄
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