Orchestration
The framework ships a full orchestration layer for coordinating multiple agents. Import from personaforge/workflow or personaforge.
import {
Team, SwarmOrchestrator, createSupervisor, createHandoff,
createAgentRouter, createConsensus, createPipeline,
compose, pipe,
} from 'personaforge/workflow';compose — sequential pipeline
Chain agents sequentially. Each agent's output becomes the next agent's input.
import { compose, createAgent } from 'personaforge';
const researcher = createAgent({ name: 'researcher', instructions: 'Research the topic.', model: 'gpt-4o', apiKey: '...' });
const writer = createAgent({ name: 'writer', instructions: 'Write a clear report from the research.', model: 'gpt-4o-mini', apiKey: '...' });
const editor = createAgent({ name: 'editor', instructions: 'Edit and polish the report.', model: 'gpt-4o-mini', apiKey: '...' });
const pipeline = compose(researcher, writer, editor);
const result = await pipeline.run('Write a report on the state of quantum computing in 2026.');
console.log(result.text);pipe — functional style
import { pipe } from 'personaforge/workflow';
const process = pipe(
(input: string) => researcher.run(input),
(r) => writer.run(r.text),
(r) => editor.run(r.text),
);
const result = await process('Quantum computing 2026');Team — role-based coordination
Coordinate a team of specialist agents under a named team identity:
import { Team, createAgent } from 'personaforge';
const codeAgent = createAgent({ name: 'coder', instructions: 'Write production-quality TypeScript.', model: 'gpt-4o', apiKey: '...' });
const reviewAgent = createAgent({ name: 'reviewer', instructions: 'Review code for bugs and style.', model: 'gpt-4o-mini', apiKey: '...' });
const docsAgent = createAgent({ name: 'docs', instructions: 'Write API documentation.', model: 'gpt-4o-mini', apiKey: '...' });
const engineeringTeam = new Team({
name: 'engineering',
agents: [codeAgent, reviewAgent, docsAgent],
strategy: 'parallel', // 'parallel' | 'sequential' | 'hierarchical'
});
const result = await engineeringTeam.run('Implement a rate-limiter class with tests and docs.');
console.log(result.synthesis);createSupervisor — delegating coordinator
A supervisor agent decides which specialist to delegate each task to:
import { createSupervisor, createRole } from 'personaforge/orchestration';
import { createAgent } from 'personaforge';
const supervisor = createSupervisor({
name: 'triage',
description: 'Coordinates specialist agents to resolve each request.',
// Each sub-agent is paired with a role describing its responsibilities.
subAgents: [
{ agent: createAgent({ name: 'billing', instructions: 'Handle billing and payment questions.', model: 'gpt-4o-mini', apiKey: '...' }), role: createRole('billing', ['Handle billing and payment questions']) },
{ agent: createAgent({ name: 'tech', instructions: 'Solve technical product issues.', model: 'gpt-4o', apiKey: '...' }), role: createRole('tech', ['Solve technical product issues']) },
{ agent: createAgent({ name: 'general', instructions: 'Answer general questions.', model: 'gpt-4o-mini', apiKey: '...' }), role: createRole('general', ['Answer general questions']) },
],
guidelines: ['Assign each request to the most relevant specialist.'],
// coordinationType?: 'sequential' (default) | 'parallel'
});
const result = await supervisor.run('My invoice shows the wrong amount.');
console.log(result);createHandoff — explicit handoff protocol
Define explicit handoff conditions so agents can transfer control at runtime:
import { createHandoff, createAgent } from 'personaforge';
const triageAgent = createAgent({
name: 'triage',
instructions: 'Triage the request. Hand off to specialists when needed.',
model: 'gpt-4o-mini',
apiKey: process.env.OPENAI_API_KEY!,
});
const specialistAgent = createAgent({
name: 'specialist',
instructions: 'Handle complex technical escalations.',
model: 'gpt-4o',
apiKey: process.env.OPENAI_API_KEY!,
});
const handoff = createHandoff({
from: triageAgent,
to: { specialist: specialistAgent },
// The router receives a HandoffContext ({ prompt, fromAgent, ... }) and
// returns the key of the target agent to hand off to.
router: () => 'specialist',
maxDepth: 5,
});
const result = await handoff.execute('My database is returning corrupted data after the migration.');
console.log(result.finalOutput.result); // answered by the specialistcreateAgentRouter — capability-based routing
Route requests to agents based on declared capabilities:
import { createAgentRouter, createAgent } from 'personaforge';
const router = createAgentRouter({
strategy: 'capability-match', // 'capability-match' | 'round-robin' | 'least-loaded'
agents: {
code: { agent: createAgent({ name: 'code-agent', instructions: '...', model: 'gpt-4o', apiKey: '...' }), capabilities: ['coding', 'debugging'] },
data: { agent: createAgent({ name: 'data-agent', instructions: '...', model: 'gpt-4o', apiKey: '...' }), capabilities: ['data-analysis', 'sql'] },
write: { agent: createAgent({ name: 'write-agent', instructions: '...', model: 'gpt-4o-mini', apiKey: '...' }), capabilities: ['writing', 'editing'] },
},
});
const result = await router.route('Fix the SQL query performance issue.');createConsensus — multi-agent voting
Run multiple agents on the same prompt and pick the best answer by consensus:
import { createConsensus, createAgent } from 'personaforge';
const consensus = createConsensus({
agents: {
a: createAgent({ name: 'agent-a', instructions: 'Answer carefully.', model: 'gpt-4o', apiKey: '...' }),
b: createAgent({ name: 'agent-b', instructions: 'Answer carefully.', model: 'claude-sonnet-4-20250514', apiKey: '...' }),
c: createAgent({ name: 'agent-c', instructions: 'Answer carefully.', model: 'gpt-4o-mini', apiKey: '...' }),
},
strategy: 'majority-vote', // 'majority-vote' | 'unanimous' | 'weighted' | 'best-of-n'
quorum: 2, // minimum agents that must agree (default: ceil(n/2))
});
const result = await consensus.decide('What is the most efficient sorting algorithm for nearly-sorted data?');
console.log(result.decision); // winning answer
console.log(result.confidence); // 0-1 agreement scoreSwarmOrchestrator — dynamic agent swarm
A self-organising swarm where agents spawn sub-agents and hand off dynamically:
The swarm decomposes the task into parallelizable subtasks and dynamically instantiates specialist subagents (driven by the configured LLM) — you configure limits and the model, not a fixed agent list. Use the createSwarm factory or the SwarmOrchestrator class directly:
import { createSwarm } from 'personaforge';
const swarm = createSwarm({
maxSubagents: 12,
concurrency: 8,
subtaskTimeoutMs: 30_000,
llm: {
// A model string, a provider instance, or explicit fields — see SwarmLLMConfig.
provider: 'openrouter:meta-llama/llama-3.3-70b-instruct',
openRouterApiKey: process.env.OPENROUTER_API_KEY,
},
});
const result = await swarm.execute({
prompt: 'Produce a detailed market analysis report for the EV charging industry.',
});
console.log(result.status); // 'success' | 'partial' | 'failed'
console.log(result.aggregatedOutput); // collated subtask resultscreatePipeline — typed data pipeline
Chain agents with typed input/output contracts:
import { createPipeline } from 'personaforge';
// Agents run in order; each agent receives the previous agent's output as its input.
const pipeline = createPipeline({
name: 'etl',
agents: [extractAgent, enrichAgent, reportAgent],
});
const report = await pipeline.run('Extract, enrich, and report on the sales data.');A2A (agent-to-agent) HTTP communication
Expose an agent as an HTTP service and connect to it from another process:
import { A2AServer, createHttpA2AClient } from 'personaforge/workflow';
// Server side
const server = new A2AServer({ agent: myAgent, port: 3100 });
await server.start();
// Client side (different process / container)
const client = createHttpA2AClient({ url: 'http://agent-service:3100' });
const result = await client.run({ prompt: 'Analyse the data.' });Load balancers
import {
RoundRobinLoadBalancer,
LeastConnectionsLoadBalancer,
WeightedResponseTimeLoadBalancer,
} from 'personaforge/workflow';
const balancer = new LeastConnectionsLoadBalancer([agentA, agentB, agentC]);
const agent = balancer.pick();createGSDCoordinator — spec-driven execution (GSD)
The GSD (Get Shit Done) Protocol is a spec-driven multi-agent pattern that separates execution into three distinct phases to prevent context pollution:
- Plan: An agent analyzes the goal, creates a structured roadmap, and writes requirements.
- Execute: An execution agent completes the roadmap steps sequentially, with each task running in a clean, isolated agent session.
- Verify: A validation agent reviews the roadmap and output to verify all requirements are met.
State is kept aligned by writing to a .planning workspace folder containing REQUIREMENTS.md, ROADMAP.md, and STATE.md.
import { createGSDCoordinator, FilesystemGSDStorage } from 'personaforge/workflow';
const gsd = createGSDCoordinator({
projectDir: './my-project',
plannerAgent,
executorAgent,
verifierAgent,
// Write planning files to disk (defaults to InMemoryGSDStorage if omitted)
storage: new FilesystemGSDStorage('./my-project/.planning'),
});
// Phase 1: Create the roadmap and requirements
await gsd.plan('Implement a rate limiter class');
// Phase 2: Execute the next incomplete task (run until completed is true)
let step = await gsd.executeStep();
console.log(`Executed: ${step.taskName}`);
// Phase 3: Verify requirements are satisfied
const verification = await gsd.verify();
if (verification.success) {
console.log('Project verified successfully!');
}createRalphLoop — context-isolated cycles (RALF)
The Ralph / RALF Loop Protocol (Read-Act-Loop-Finish) runs a single agent in an iterative loop to solve complex tasks. To avoid context bloat and performance degradation, it creates a fresh session instance for each cycle while propagating concise summaries of preceding cycles in the prompt.
import { createRalphLoop } from 'personaforge/workflow';
const loop = createRalphLoop({
agent: codingAgent,
maxCycles: 5,
checkComplete: async (ctx) => {
// Return true once the task is verified (e.g. running tests or validation check)
return ctx.lastResult.includes('Tests passed');
},
});
const result = await loop.run('Fix the failing test in src/index.ts');
console.log(result.success); // true
console.log(result.cyclesRun); // e.g. 3Extended Multi-Agent Orchestration Patterns
The framework supports 9 advanced agentic interaction patterns under personaforge to orchestrate agents for specific reasoning, code execution, or tutoring tasks.
1. Mixture-of-Agents (MoA)
Combines multiple proposer agents to generate candidate responses in parallel, then refines them across rounds before a single aggregator agent synthesizes the final result.
import { createMixtureOfAgents } from 'personaforge';
const moa = createMixtureOfAgents({
name: 'MoA-Synthesizer',
proposers: [coderA, coderB, coderC],
aggregator: leadCritic,
rounds: 2,
});
const outcome = await moa.run({ prompt: 'Write an optimized matrix multiplication in TS.' });2. Actor-Critic
An Actor agent generates an answer, which a Critic agent reviews. The Actor refines the answer based on the Critic's feedback, looping until satisfying a validator or reaching maxRefinements.
import { createActorCritic } from 'personaforge';
const actorCritic = createActorCritic({
name: 'Code-Review-Loop',
actor: codeAgent,
critic: reviewerAgent,
maxRefinements: 3,
isSatisfactory: (critique) => critique.toLowerCase().includes('looks good'),
});3. Socratic Tutor
Wraps an agent to guide users conceptually without giving direct answers, forcing reflection by asking clarifying questions or pointing out contradictions.
import { createSocraticAgent } from 'personaforge';
const tutor = createSocraticAgent({
name: 'Math-Tutor',
agent: generalAgent,
topic: 'linear algebra',
instructions: 'Guide the user to solve systems of equations.',
});4. Prompt Chaining
Sequentially pipes a series of structured tasks where each agent's execution depends on the outputs of preceding agents.
import { createPromptChain } from 'personaforge';
const chain = createPromptChain({
name: 'Content-Pipeline',
steps: [
{ name: 'outline', agent: outlineAgent },
{
name: 'draft',
agent: writerAgent,
template: (input, prev) => `Outline:\n${prev.outline}\n\nWrite a post on: ${input}`
},
{ name: 'seo', agent: seoAgent },
],
});5. Program-of-Thought (PoT)
Delegates mathematical or algorithmic tasks to an agent by prompting it to write executable code (e.g. JavaScript), executes that code in a sandbox runtime, and feeds the results back to the agent to synthesize the final answer.
import { createProgramOfThought } from 'personaforge';
const pot = createProgramOfThought({
name: 'Math-PoT',
agent: codingAgent,
// Custom sandbox executor (defaults to a safe Function evaluation)
executor: async (code) => {
return { stdout: 'Result: 42', stderr: '' };
},
});6. Skeleton-of-Thought (SoT)
Speeds up long generation tasks by first generating a structured outline (skeleton), then invoking worker agents in parallel to write details for each section, finally joining the details together.
import { createSkeletonOfThought } from 'personaforge';
const sot = createSkeletonOfThought({
name: 'Article-Generator',
planner: layoutAgent,
worker: sectionWriterAgent,
parallel: true, // Generate sections concurrently
});7. Step-Back Abstraction
Prompts an agent to "step back" and analyze the underlying conceptual principle or broader context of a task first, then feeds that abstraction as context to a solver agent to resolve the original question.
import { createStepBackAgent } from 'personaforge';
const stepBack = createStepBackAgent({
name: 'Physics-Solver',
stepBackAgent: conceptualAgent,
solverAgent: mathAgent,
});8. Rejection Sampling (Best-of-N)
Generates N candidate answers in parallel and evaluates each candidate using a scoring function or a Judge agent, returning the highest-scoring candidate.
import { createRejectionSampling } from 'personaforge';
const bestOfN = createRejectionSampling({
name: 'Creative-Writer',
agent: writerAgent,
n: 3,
judge: async (candidate) => {
return candidate.includes('metaphor') ? 10 : 5; // custom score logic
},
});9. Self-Correction / Self-Debugging
Runs an agentic loop that tests the agent's output against a validator function. If the output fails validation, the agent is prompted with the errors to self-correct its answer, up to maxRetries.
import { createSelfCorrection } from 'personaforge';
const selfDebugger = createSelfCorrection({
name: 'JSON-Validator',
agent: jsonAgent,
validator: (output) => {
try {
JSON.parse(output);
return { valid: true };
} catch (e: any) {
return { valid: false, errors: [e.message] };
}
},
maxRetries: 3,
});Where to go next
- Workflows — DAG-based graph workflows with branching and retries.
- Reasoning — step-by-step reasoning loops inside an agent.
- Production — circuit breakers and health checks for distributed agent systems.