AgentFlow

Step-based workflow execution with routing and context

AgentFlow enables complex multi-step pipelines with routing, parallel execution, and context sharing between steps.

Diagram

AgentFlow

📋 Step 1

⚙️ Step 2

✅ Step 3

📥 Input

📤 Output

Quick Start

  1. Simple Usage
    bash
    npm install praisonai
  2. With Configuration
    typescript
    import { Agent, AgentFlow } from 'praisonai';
    
    const researcher = new Agent({
      instructions: 'Research the topic'
    });
    
    const writer = new Agent({
      instructions: 'Write based on research'
    });
    
    const flow = new AgentFlow('content-pipeline')
      .agent(researcher, 'Research AI trends')
      .agent(writer, 'Write article based on research');
    
    const { output } = await flow.run('AI in 2025');

How It Works

Diagram
ContextStep2Step1AgentFlowUserContextStep2Step1AgentFlowUserrun(input)execute(input)set(‘step1’, result)output1execute(output1, context)get(‘step1’)output2{ output, results }
ComponentDescription
StepsIndividual processing units (agents or functions)
ContextShared state between steps
OutputFinal result from the last step
ResultsAll intermediate step results

Configuration Options

Step Configuration

typescript
flow.addStep({
  name: 'process',
  execute: async (input, context) => {
    return processData(input);
  },
  condition: (context) => context.get('shouldRun'),
  onError: 'retry',
  maxRetries: 3
});
OptionTypeDefaultDescription
namestringrequiredStep identifier
executefunctionrequiredAsync function to process input
conditionfunctionundefinedCondition to run the step
onError`’fail’ \‘skip’ \‘retry’`'fail'Error handling behavior
maxRetriesnumber0Maximum retry attempts

Common Patterns

Agent Steps

typescript
import { Agent, AgentFlow } from 'praisonai';

const researcher = new Agent({ instructions: 'Research topics' });
const writer = new Agent({ instructions: 'Write content' });

const flow = new AgentFlow('research-pipeline')
  .agent(researcher, 'Research the topic')
  .agent(writer, 'Write based on research');

const { output } = await flow.run('AI trends');

Custom Steps

typescript
const flow = new AgentFlow('data-pipeline')
  .step('fetch', async (input) => {
    return await fetchData(input);
  })
  .step('process', async (data) => {
    return processData(data);
  })
  .step('save', async (result) => {
    return await saveResult(result);
  });

const { output } = await flow.run(inputData);

With Context

typescript
const flow = new AgentFlow('analysis')
  .step('analyze', async (input, context) => {
    const result = await agent.chat(input);
    context.set('analysis', result);
    return result;
  })
  .step('report', async (input, context) => {
    const analysis = context.get('analysis');
    return generateReport(analysis, input);
  });

Conditional Steps

typescript
const flow = new AgentFlow('conditional')
  .addStep({
    name: 'primary',
    execute: async (input) => primaryAgent.chat(input),
    onError: 'skip'
  })
  .addStep({
    name: 'fallback',
    condition: (context) => context.get('primary') === undefined,
    execute: async (input) => fallbackAgent.chat(input)
  });

Workflow Helpers

Parallel Execution

typescript
import { parallel } from 'praisonai';

const [sentiment, summary, keywords] = await parallel([
  async () => sentimentAgent.chat(document),
  async () => summaryAgent.chat(document),
  async () => keywordAgent.chat(document)
]);

Conditional Routing

typescript
import { route } from 'praisonai';

const result = await route([
  {
    condition: () => query.includes('technical'),
    execute: async () => techAgent.chat(query)
  },
  {
    condition: () => query.includes('billing'),
    execute: async () => billingAgent.chat(query)
  }
], async () => generalAgent.chat(query));  // Default fallback

Loop Pattern

typescript
import { loop } from 'praisonai';

const result = await loop(
  async (context) => improverAgent.chat(context.get('draft')),
  (result) => result.includes('DONE'),  // Condition to stop
  { maxIterations: 5 }
);

Best Practices

Use context for data sharing

Store intermediate results in context rather than return values.

typescript
context.set('research', researchData);
// Later steps can access via context.get('research')
Handle errors gracefully

Use onError and maxRetries for resilient flows.

typescript
.addStep({
  name: 'api-call',
  execute: async (input) => callApi(input),
  onError: 'retry',
  maxRetries: 3
})
Use conditions for branching

Skip steps conditionally based on context state.

typescript
.addStep({
  name: 'optional',
  condition: (ctx) => ctx.get('needsProcessing'),
  execute: async (input) => process(input)
})

Backward Compatibility

typescript
// All of these are equivalent
import { AgentFlow, Workflow, Pipeline } from 'praisonai';

const flow1 = new AgentFlow('my-flow');
const flow2 = new Workflow('my-flow');
const flow3 = new Pipeline('my-flow');

// They are the same class
console.log(AgentFlow === Workflow);   // true
console.log(AgentFlow === Pipeline);   // true

Related