Executing Patterns
This guide covers how to execute patterns using the Parallax client SDK.
Basic Execution
import { ParallaxClient } from '@parallax/sdk-typescript';
const client = new ParallaxClient({
url: 'http://localhost:8080',
});
const result = await client.executePattern('sentiment-analysis', {
text: 'This product exceeded my expectations!',
});
console.log(result);
// { sentiment: 'positive', confidence: 0.92 }
Execution Options
Timeout
const result = await client.executePattern('analysis', input, {
timeout: 60000, // 60 second timeout
});
Version Selection
// Exact version
const result = await client.executePattern('analysis', input, {
version: '2.1.0',
});
// Version range
const result = await client.executePattern('analysis', input, {
version: '2.x', // Any 2.x version
});
// Latest
const result = await client.executePattern('analysis', input, {
version: 'latest',
});
Priority
const result = await client.executePattern('analysis', input, {
priority: 'high', // 'low', 'normal', 'high', 'critical'
});
Metadata
const result = await client.executePattern('analysis', input, {
metadata: {
userId: 'user-123',
requestId: 'req-456',
source: 'api',
},
});
Streaming Execution
For long-running patterns, stream results as they become available:
const stream = client.streamPattern('research-pipeline', {
query: 'quantum computing applications',
});
// Progress updates
stream.on('progress', (progress) => {
console.log(`Step ${progress.step}: ${progress.message}`);
console.log(`Progress: ${progress.percent}%`);
});
// Partial results
stream.on('partial', (data) => {
console.log('Intermediate result:', data);
});
// Final result
stream.on('complete', (result) => {
console.log('Final result:', result);
});
// Errors
stream.on('error', (error) => {
console.error('Execution failed:', error);
});
Stream Control
const stream = client.streamPattern('analysis', input);
// Cancel execution
stream.cancel();
// Check status
console.log(stream.status); // 'running', 'completed', 'cancelled', 'error'
// Wait for completion
const result = await stream.wait();
Batch Execution
Execute a pattern with multiple inputs:
const inputs = [
{ text: 'Great product!' },
{ text: 'Terrible experience.' },
{ text: 'It was okay.' },
];
const results = await client.executeBatch('sentiment-analysis', inputs, {
concurrency: 5, // Max concurrent executions
stopOnError: false, // Continue even if some fail
});
for (const result of results) {
if (result.success) {
console.log(result.output);
} else {
console.error(result.error);
}
}
Batch with Progress
const batch = client.executeBatch('analysis', inputs);
batch.on('progress', (progress) => {
console.log(`Completed ${progress.completed}/${progress.total}`);
});
batch.on('result', (index, result) => {
console.log(`Input ${index}:`, result);
});
const results = await batch.wait();
Async Execution
For patterns that take a long time, execute asynchronously:
// Start execution without waiting
const execution = await client.executePatternAsync('long-analysis', input);
console.log('Execution started:', execution.id);
// Poll for status
const status = await client.getExecution(execution.id);
console.log('Status:', status.status); // 'pending', 'running', 'completed', 'failed'
// Wait for completion later
const result = await client.waitForExecution(execution.id, {
timeout: 300000, // 5 minute timeout
pollInterval: 5000, // Check every 5 seconds
});
Webhooks
Receive results via webhook:
const execution = await client.executePatternAsync('analysis', input, {
webhook: {
url: 'https://your-server.com/webhook',
headers: {
'Authorization': 'Bearer your-token',
},
events: ['completed', 'failed'], // Which events to send
},
});
Execution Management
Get Execution Details
const execution = await client.getExecution(executionId);
console.log({
id: execution.id,
pattern: execution.pattern,
status: execution.status,
progress: execution.progress,
startedAt: execution.startedAt,
completedAt: execution.completedAt,
result: execution.result,
error: execution.error,
});
List Executions
const executions = await client.listExecutions({
pattern: 'sentiment-analysis',
status: 'completed',
from: new Date('2024-01-01'),
to: new Date(),
limit: 100,
offset: 0,
});
for (const exec of executions.items) {
console.log(`${exec.id}: ${exec.status}`);
}
Cancel Execution
await client.cancelExecution(executionId);
Retry Failed Execution
const newExecution = await client.retryExecution(executionId);
Input Validation
The client validates inputs before sending:
try {
const result = await client.executePattern('sentiment-analysis', {
// Missing required 'text' field
});
} catch (error) {
if (error instanceof ValidationError) {
console.error('Invalid input:', error.errors);
// [{ field: 'text', message: 'Required field missing' }]
}
}
Pre-validate Input
const validation = await client.validateInput('sentiment-analysis', input);
if (!validation.valid) {
console.error('Validation errors:', validation.errors);
} else {
const result = await client.executePattern('sentiment-analysis', input);
}
Error Handling
Error Types
import {
ParallaxError,
ValidationError,
TimeoutError,
PatternNotFoundError,
ExecutionError,
InsufficientAgentsError,
} from '@parallax/sdk-typescript';
try {
const result = await client.executePattern('analysis', input);
} catch (error) {
if (error instanceof ValidationError) {
// Input validation failed
console.error('Invalid input:', error.errors);
} else if (error instanceof TimeoutError) {
// Execution timed out
console.error('Timed out after', error.timeout, 'ms');
} else if (error instanceof PatternNotFoundError) {
// Pattern doesn't exist
console.error('Pattern not found:', error.patternName);
} else if (error instanceof InsufficientAgentsError) {
// Not enough agents available
console.error('Need', error.required, 'agents, only', error.available, 'available');
} else if (error instanceof ExecutionError) {
// Execution failed
console.error('Execution failed:', error.reason);
console.error('Partial results:', error.partialResults);
}
}
Retry Logic
const result = await client.executePattern('analysis', input, {
retries: 3, // Number of retries
retryDelay: 1000, // Initial delay (ms)
retryBackoff: 'exponential', // 'fixed', 'linear', 'exponential'
retryOn: ['timeout', 'connection'], // Which errors to retry
});
Custom Retry Logic
import { retry } from '@parallax/sdk-typescript';
const result = await retry(
() => client.executePattern('analysis', input),
{
maxAttempts: 3,
shouldRetry: (error, attempt) => {
// Custom retry logic
if (error instanceof ValidationError) return false;
if (attempt >= 3) return false;
return true;
},
onRetry: (error, attempt) => {
console.log(`Retry ${attempt} after error:`, error.message);
},
}
);
Type Safety
Typed Patterns
interface SentimentInput {
text: string;
language?: string;
}
interface SentimentOutput {
sentiment: 'positive' | 'negative' | 'neutral';
confidence: number;
}
const result = await client.executePattern<SentimentInput, SentimentOutput>(
'sentiment-analysis',
{ text: 'Great product!' }
);
// result is typed as SentimentOutput
console.log(result.sentiment);
Generate Types from Pattern
import { generateTypes } from '@parallax/pattern-sdk';
// Generate TypeScript types from pattern YAML
const types = generateTypes(patternYaml);
// export interface SentimentAnalysisInput { text: string; language?: string; }
// export interface SentimentAnalysisOutput { sentiment: string; confidence: number; }
Execution Context
Request Tracing
const result = await client.executePattern('analysis', input, {
traceId: 'trace-123', // For distributed tracing
spanId: 'span-456',
baggage: {
userId: 'user-789',
},
});
Request Context
// Set default context for all requests
client.setContext({
tenantId: 'tenant-abc',
environment: 'production',
});
// Context is included in all executions
const result = await client.executePattern('analysis', input);
Performance
Connection Pooling
const client = new ParallaxClient({
url: 'http://localhost:8080',
pool: {
maxConnections: 10,
minConnections: 2,
idleTimeout: 30000,
},
});
Caching
const result = await client.executePattern('analysis', input, {
cache: {
enabled: true,
ttl: 3600, // Cache for 1 hour
key: 'custom-key', // Optional custom cache key
},
});
Local Execution
For patterns that can run locally:
import { LocalExecutor } from '@parallax/sdk-typescript';
const executor = new LocalExecutor({
patterns: ['./patterns'],
agents: [localAgent1, localAgent2],
});
// Execute without network round-trip
const result = await executor.execute('simple-pattern', input);
Monitoring
Execution Metrics
const result = await client.executePattern('analysis', input);
// Access execution metrics
console.log(result.$metadata);
// {
// executionId: 'exec-123',
// duration: 1500,
// agentCount: 3,
// retries: 0,
// confidence: 0.92,
// }
Client Metrics
const metrics = client.getMetrics();
// {
// totalExecutions: 1000,
// successRate: 0.98,
// avgLatency: 250,
// p95Latency: 500,
// }
Next Steps
- Patterns Concept - Understanding patterns
- Streaming - Advanced streaming patterns
- TypeScript SDK - Full SDK reference