Overview
The Orchestrator pattern uses:- Planner Agent: Meta-agent that coordinates the workflow
- Sub-Agents: Specialized agents for specific tasks (research, coding, review, etc.)
- Tool Exposure: Sub-agents are automatically exposed as tools to the planner
import { createAgent } from '@agentlib/core'
import { openai } from '@agentlib/openai'
import { Orchestrator } from '@agentlib/orchestrator'
import '@agentlib/reasoning'
const provider = openai({
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4o',
})
// Define specialized sub-agents
const researcher = createAgent({
name: 'researcher',
description: 'Finds detailed information about specific topics.',
systemPrompt: 'You are a researcher. Provide concise summaries of facts.',
}).provider(provider).reasoning('react')
const coder = createAgent({
name: 'coder',
description: 'Writes efficient code based on requirements.',
systemPrompt: 'You are an expert coder. Wrap code in markdown blocks.',
}).provider(provider).reasoning('react')
// Define planner
const planner = createAgent({
name: 'planner',
description: 'Main coordinator that uses sub-agents.',
systemPrompt: 'You are a project manager. Use available agents to solve tasks.',
}).provider(provider).reasoning('react')
// Initialize orchestrator
const orchestrator = new Orchestrator(planner, {
agents: { researcher, coder },
maxSteps: 10,
exposeAgentsAsTools: true,
})
await orchestrator.run('Research JavaScript frameworks and write comparison code')
Creating an Orchestrator
Define Sub-Agents
Create specialized agents for different tasks:
import { createAgent } from '@agentlib/core'
import { openai } from '@agentlib/openai'
import '@agentlib/reasoning'
const provider = openai({
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4o',
})
const researcher = createAgent({
name: 'researcher',
description: 'Finds detailed information about specific topics.',
systemPrompt: 'You are a researcher. Provide concise summaries.',
}).provider(provider).reasoning('react')
const coder = createAgent({
name: 'coder',
description: 'Writes efficient code based on requirements.',
systemPrompt: 'You are an expert coder.',
}).provider(provider).reasoning('react')
const critic = createAgent({
name: 'critic',
description: 'Reviews work and provides a score from 0 to 1.',
systemPrompt: 'You are a critical reviewer. Always end with "Score: X.X"',
}).provider(provider).reasoning('react')
Give each sub-agent a clear
name and description. The planner uses these to decide which agent to invoke.Define the Planner Agent
Create a meta-agent that coordinates the sub-agents:
const planner = createAgent({
name: 'planner',
description: 'Main coordinator that uses sub-agents to solve complex tasks.',
systemPrompt: 'You are a project manager. Use the available agents to research, code, and review.',
}).provider(provider).reasoning('react')
Initialize the Orchestrator
import { Orchestrator } from '@agentlib/orchestrator'
const orchestrator = new Orchestrator(planner, {
agents: {
researcher,
coder,
critic,
},
maxSteps: 10,
summarize: true,
exposeAgentsAsTools: true,
})
Configuration Options
new Orchestrator(planner, {
agents: { // Sub-agents available to planner
researcher,
coder,
critic,
},
maxSteps: 10, // Max orchestration steps
summarize: true, // Summarize agent outputs for context
exposeAgentsAsTools: true, // Auto-register agents as tools
context: { // Shared context for all agents
company: 'ACME Corp',
constraints: 'Budget: $10k',
},
onStep: (step) => { // Callback for each step
console.log(`Step: ${step.agent} - ${step.type}`)
if (step.error) return 'abort' // Abort on error
},
})
Orchestrator Events
Monitor orchestration with events:orchestrator.on('agent:invoke', ({ agent, prompt }) => {
console.log(`\n🚀 Invoking agent: ${agent}`)
console.log(`Prompt: ${prompt}`)
})
orchestrator.on('agent:completed', ({ agent, output }) => {
console.log(`\n✅ Agent ${agent} finished!`)
console.log(`Output: ${output.substring(0, 100)}...`)
})
orchestrator.on('step', ({ step, agent }) => {
console.log(`[${agent}] ${step.type}`)
})
orchestrator.on('error', ({ agent, error }) => {
console.error(`❌ Agent ${agent} failed:`, error)
})
Step Control with onStep
Control orchestration flow with theonStep callback:
const orchestrator = new Orchestrator(planner, {
agents: { researcher, coder, critic },
onStep: (step) => {
console.log(`[Step] Agent: ${step.agent} | Type: ${step.type}`)
// Abort if quality is too low
if (step.agent === 'critic' && step.content?.includes('Score: 0.3')) {
console.warn('Low quality detected! Aborting...')
return 'abort'
}
// Continue normally
return undefined
},
})
Step Structure
interface OrchestrationStep {
agent: string // Agent name
type: string // Step type (e.g., 'thought', 'tool_call')
content?: string // Step content
error?: string // Error message if failed
}
Accessing Agent States
Inspect the state of all agents after orchestration:const result = await orchestrator.run('Complex task')
const states = orchestrator.getAllStates()
for (const state of states) {
console.log(`\nAgent: ${state.name}`)
console.log(`Status: ${state.status}`)
console.log(`Steps: ${state.steps.length}`)
console.log(`Tokens: ${state.usage?.totalTokens}`)
}
Shared Context
Pass shared data to all agents:const orchestrator = new Orchestrator(planner, {
agents: { researcher, coder },
context: {
company: 'ACME Corp',
budget: 10_000,
deadline: '2025-06-01',
},
})
// All agents can access this context during execution
Custom Tool Integration
Combine sub-agents with regular tools:import { defineTool } from '@agentlib/core'
const searchTool = defineTool({
schema: {
name: 'search',
description: 'Search the web',
parameters: {
type: 'object',
properties: { query: { type: 'string' } },
required: ['query'],
},
},
async execute({ query }) {
return { results: [`Result for: ${query}`] }
},
})
// Add tools to planner
const planner = createAgent({
name: 'planner',
systemPrompt: 'You are a coordinator.',
})
.provider(provider)
.reasoning('react')
.tool(searchTool) // Regular tool
// Orchestrator will expose both tools and sub-agents
const orchestrator = new Orchestrator(planner, {
agents: { researcher, coder },
exposeAgentsAsTools: true,
})
Complete Example
import 'dotenv/config'
import '@agentlib/reasoning'
import { createAgent } from '@agentlib/core'
import { openai } from '@agentlib/openai'
import { Orchestrator } from '@agentlib/orchestrator'
const provider = openai({
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4o',
})
// Define sub-agents
const researcher = createAgent({
name: 'researcher',
description: 'Finds detailed information about specific topics.',
systemPrompt: 'You are a researcher. Provide concise summaries of facts.',
}).provider(provider).reasoning('react')
const coder = createAgent({
name: 'coder',
description: 'Writes efficient code based on requirements.',
systemPrompt: 'You are an expert coder. Wrap your code in markdown blocks.',
}).provider(provider).reasoning('react')
const critic = createAgent({
name: 'critic',
description: 'Reviews work and provides a score from 0 to 1.',
systemPrompt: 'You are a critical reviewer. Always end your message with "Score: X.X"',
}).provider(provider).reasoning('react')
// Define planner
const planner = createAgent({
name: 'planner',
description: 'Main coordinator that uses sub-agents to solve complex tasks.',
systemPrompt: 'You are a project manager. Use the available agents to research, code, and review.',
}).provider(provider).reasoning('react')
// Initialize orchestrator
const orchestrator = new Orchestrator(planner, {
agents: {
researcher,
coder,
critic,
},
maxSteps: 10,
summarize: true,
exposeAgentsAsTools: true,
context: {
company: 'ACME Corp',
constraints: 'You are running on ACME Corp infrastructure',
},
onStep: (step) => {
console.log(`[Step] Agent: ${step.agent} | Type: ${step.type}`)
if (step.agent === 'critic' && step.content?.includes('Score: 0.3')) {
console.warn('Low quality work detected! Aborting...')
return 'abort'
}
},
})
// Add event listeners
orchestrator.on('agent:invoke', ({ agent, prompt }) => {
console.log(`\n🚀 Invoking agent: ${agent}`)
console.log(`Prompt: ${prompt}`)
})
orchestrator.on('agent:completed', ({ agent, output }) => {
console.log(`\n✅ Agent ${agent} finished!`)
console.log(`Output: ${output.substring(0, 100)}...`)
})
// Run orchestration
console.log('--- Starting Orchestration ---')
await orchestrator.run('Design and implement a scalable image processing system.')
console.log('\n--- Orchestration Finished ---')
// Inspect final states
const states = orchestrator.getAllStates()
console.log('\nFinal States:')
for (const state of states) {
console.log(`${state.name}: ${state.status} (${state.steps.length} steps)`)
}
Use Cases
Software Development Workflow
const requirements = createAgent({
name: 'requirements',
description: 'Analyzes requirements and creates specifications.',
}).provider(provider).reasoning('planner')
const architect = createAgent({
name: 'architect',
description: 'Designs system architecture.',
}).provider(provider).reasoning('planner')
const developer = createAgent({
name: 'developer',
description: 'Implements features based on specs.',
}).provider(provider).reasoning('react')
const tester = createAgent({
name: 'tester',
description: 'Creates and runs tests.',
}).provider(provider).reasoning('react')
const orchestrator = new Orchestrator(planner, {
agents: { requirements, architect, developer, tester },
})
await orchestrator.run('Build a REST API for user management')
Research and Writing
const factChecker = createAgent({
name: 'fact_checker',
description: 'Verifies claims and finds sources.',
}).provider(provider).reasoning('react')
const writer = createAgent({
name: 'writer',
description: 'Writes engaging content.',
}).provider(provider).reasoning('cot')
const editor = createAgent({
name: 'editor',
description: 'Edits for clarity and correctness.',
}).provider(provider).reasoning('reflect')
const orchestrator = new Orchestrator(planner, {
agents: { factChecker, writer, editor },
})
await orchestrator.run('Write an article about quantum computing advancements')
Customer Support Triage
const classifier = createAgent({
name: 'classifier',
description: 'Classifies support tickets by urgency and category.',
}).provider(provider).reasoning('cot')
const technicalSupport = createAgent({
name: 'technical_support',
description: 'Handles technical issues.',
}).provider(provider).reasoning('react')
const billingSupport = createAgent({
name: 'billing_support',
description: 'Handles billing questions.',
}).provider(provider).reasoning('react')
const orchestrator = new Orchestrator(planner, {
agents: { classifier, technicalSupport, billingSupport },
})
await orchestrator.run('User cannot access their account after payment')
Next Steps
- Creating Agents - Build specialized sub-agents
- Reasoning Engines - Choose engines for each agent
- Event Handling - Monitor orchestration flow