Documentation/Agent Orchestrator
v2.0.0-beta.1Snapshot bebdcd1Markdown ↗

Agent Orchestrator

Agent Orchestrator

Create autonomous agent teams that coordinate through a shared workspace. The orchestrator is a regular Agent with special tools — no subclass needed.

Quick Start

typescript
import { createOrchestrator, Connector, Vendor } from 'oneringai';

Connector.create({
  name: 'openai',
  vendor: Vendor.OpenAI,
  auth: { type: 'api_key', apiKey: process.env.OPENAI_API_KEY! },
});

const orchestrator = await createOrchestrator({
  connector: 'openai',
  model: 'gpt-4.1',
  agentTypes: {
    architect: {
      systemPrompt: 'You are a senior software architect. Design clean, scalable systems. Use the shared workspace to publish your designs.',
      tools: [readFile, writeFile],
    },
    critic: {
      systemPrompt: 'You are a thorough code reviewer. Read artifacts from the workspace, find issues, and post your review back to the workspace.',
      tools: [readFile, grep],
    },
    developer: {
      systemPrompt: 'You are a senior developer. Read the plan from the workspace, implement it, and update the workspace with your progress.',
      tools: [readFile, writeFile, editFile, bash],
    },
  },
});

const result = await orchestrator.run('Build an auth module with JWT support');
console.log(result.output_text);

Architecture

text
┌─────────────────────────────────────────────────────────┐
│                   Orchestrator (Agent)                    │
│                                                           │
│  System prompt: auto-generated from agentTypes            │
│  Tools: 5 orchestration tools + workspace store tools     │
│                                                           │
├─────────────────────────────────────────────────────────┤
│           SharedWorkspace (shared instance)               │
│  - entries: plans, code, reviews, status                  │
│  - log: team conversation                                 │
│  - All agents read/write via store_*("workspace", ...)    │
├─────────────────────────────────────────────────────────┤
│                    Worker Agents                          │
│  - Persistent (remember reasoning across turns)           │
│  - Own context + shared workspace                         │
│  - Receive workspace delta at turn start                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐               │
│  │Architect │  │  Critic  │  │Developer │               │
│  └──────────┘  └──────────┘  └──────────┘               │
└─────────────────────────────────────────────────────────┘

OrchestratorConfig

typescript
interface OrchestratorConfig {
  connector: string;           // Connector for LLM access
  model: string;               // Model for orchestrator (default for workers too)
  systemPrompt?: string;       // Custom prompt (overrides auto-generated)
  agentTypes: Record<string, AgentTypeConfig>;  // Available worker types
  workspace?: Partial<SharedWorkspaceConfig>;    // Workspace settings
  features?: Partial<ContextFeatures>;           // Orchestrator context features
  pluginConfigs?: PluginConfigs;                 // Plugin configurations for the orchestrator
  name?: string;               // Orchestrator name (default: 'orchestrator')
  agentId?: string;            // For session persistence
  maxIterations?: number;      // Max loop iterations (default: 100)
  maxAgents?: number;          // Max worker agents (default: 20)
  skipPlanning?: boolean;      // Skip UNDERSTAND/PLAN/APPROVE phases (default: false)
  tools?: ToolFunction[];      // Tools available to the orchestrator for DIRECT-route tasks
  delegationDefaults?: DelegationDefaults; // Default delegation settings
  autoDescribe?: boolean;      // LLM-generated descriptions for agent types (default: false)
}

interface AgentTypeConfig {
  systemPrompt: string;        // Role-defining prompt
  tools?: ToolFunction[];      // Role-specific tools
  model?: string;              // Override model per type
  connector?: string;          // Override connector per type
  features?: Partial<ContextFeatures>;  // Worker context features
  plugins?: PluginConfigs;     // Worker plugin configurations
  description?: string;        // One-liner for routing (e.g., "Senior dev who writes and tests code")
  scenarios?: string[];        // When to use (e.g., ["implementing features", "fixing bugs"])
  capabilities?: string[];     // What it can do (e.g., ["read/write files", "run shell commands"])
}

3-Tier Routing

The orchestrator v2 uses a 3-tier routing model:

Route When Behavior
DIRECT Simple queries, quick lookups Orchestrator handles directly using its own tools
DELEGATE User needs extended interaction with a specialist Hands user-facing session to a sub-agent via delegate_interactive
ORCHESTRATE Complex multi-step tasks Coordinates multiple workers via assign_turn + workspace

Orchestration Tools

The orchestrator gets 5 tools automatically:

Task Assignment

Tool Description
assign_turn(agent, type, instruction) Assign work to an agent. Auto-creates the agent if it doesn't exist. Always async. Optional autoDestroy to clean up after completion.
delegate_interactive(agent, type?, monitoring?, reclaimOn?, briefing?) Hand the user-facing session to a sub-agent. Supports monitoring (passive/active/event) and reclaimOn conditions (keyword, maxTurns, workspaceKey).

Team Management

Tool Description
list_agents() Returns all workers with name, model, status, plus current delegation state.
destroy_agent(name) Destroy a worker. Auto-reclaims delegation if the destroyed agent was the delegatee.

Communication

Tool Description
send_message(agent, message) Inject a message into an agent's context. If the agent is running, the message appears on its next iteration. If idle, it's seen on the next turn. Uses Agent.inject().

Workspace Delta

When a worker starts a turn, its instruction is automatically prepended with a workspace delta showing what changed since that worker's last turn:

text
[Workspace changes since your last turn]
- NEW: "auth_plan" (v1, by architect) — JWT auth design with refresh tokens
- UPDATED: "requirements" (v1→v2, by orchestrator) — Added rate limiting requirement
Recent log:
  [architect] Designed API following RESTful patterns
  [orchestrator] Added rate limiting to requirements

Design the authentication module based on the approved plan.

Workflow Examples

Sequential Review Cycle

typescript
const orchestrator = await createOrchestrator({
  connector: 'openai',
  model: 'gpt-4.1',
  agentTypes: {
    architect: { systemPrompt: 'You are a software architect...', tools: [readFile, writeFile] },
    critic: { systemPrompt: 'You are a code reviewer...', tools: [readFile] },
    developer: { systemPrompt: 'You are a developer...', tools: [readFile, writeFile, editFile, bash] },
  },
});

// The orchestrator LLM naturally follows this pattern:
// 1. assign_turn(agent="arch", type="architect", instruction="Design the auth module")
//    → auto-creates "arch" as an architect worker
// 2. assign_turn(agent="rev", type="critic", instruction="Review the architecture plan")
//    → auto-creates "rev" as a critic worker
// 3. If issues: assign_turn(agent="arch", instruction="Address reviewer feedback")
// 4. assign_turn(agent="dev", type="developer", instruction="Implement the approved plan")
// 5. assign_turn(agent="rev", instruction="Review the implementation")
// 6. If issues: assign_turn(agent="dev", instruction="Fix review comments")
// 7. Final acceptance → destroy_agent for each worker

const result = await orchestrator.run('Build a JWT auth module with refresh tokens');

Parallel Research

typescript
const orchestrator = await createOrchestrator({
  connector: 'openai',
  model: 'gpt-4.1',
  agentTypes: {
    researcher: {
      systemPrompt: 'You are a research analyst. Search the web, analyze findings, and post results to the workspace.',
      tools: [webSearchTool, webFetchTool],
    },
    synthesizer: {
      systemPrompt: 'You are an analyst. Read research findings from the workspace and produce a comprehensive summary.',
    },
  },
});

// The orchestrator will (all assign_turn calls are async/non-blocking):
// 1. assign_turn(agent="r1", type="researcher", instruction="Research competitor A")
// 2. assign_turn(agent="r2", type="researcher", instruction="Research competitor B")
// 3. assign_turn(agent="r3", type="researcher", instruction="Research competitor C")
//    → All 3 run concurrently (assign_turn is always non-blocking)
// 4. When results arrive, assign_turn(agent="synth", type="synthesizer", instruction="Combine all research")

const result = await orchestrator.run('Research the top 3 competitors in the AI agent space');

Async Execution (All assign_turn Calls Are Non-Blocking)

typescript
// assign_turn is always async (blocking: false). The orchestrator naturally
// launches multiple agents concurrently:
//
// 1. assign_turn(agent="r1", type="researcher", instruction="Research competitor A")
//    → Returns immediately, r1 starts working in background
//
// 2. assign_turn(agent="r2", type="researcher", instruction="Research competitor B")
//    → Returns immediately, r2 starts working in background
//
// 3. Orchestrator continues: updates workspace, plans next steps, talks to user
//
// 4. Results arrive via autoContinue (500ms batching window):
//    → "r1 completed: Found 5 key insights..."
//    → "r2 completed: Analysis complete..."
//
// The orchestrator classifies each result: complete, question, stuck, or partial.
// 3-strike rule: after 3 failed re-assignments, try different agent type or escalate.

Interactive Delegation

typescript
// For extended interactive sessions (pair-programming, tutoring, debugging):
//
// delegate_interactive(agent="dev", type="developer",
//   monitoring="active",     // LLM reviews each turn, can intervene
//   reclaimOn={ keyword: "done", maxTurns: 20 },
//   briefing="User wants help implementing auth")
//
// User now talks directly to the "dev" agent.
// Orchestrator monitors and can inject guidance via send_message.
// Control returns when user says "done" or after 20 turns.
//
// Monitoring modes:
//   passive  — exchanges logged to workspace, reviewed when control returns
//   active   — LLM reviews each turn, can inject intervention messages
//   event    — notified when a specific workspace key appears
//
// Reclaim conditions:
//   keyword     — user says a word (regex match, e.g., "done", "back")
//   maxTurns    — auto-reclaim after N delegation turns
//   workspaceKey — reclaim when a specific workspace entry appears

Agent.inject()

The inject() method enables orchestrator-to-worker communication:

typescript
// Inject a message into a running or idle agent
agent.inject('Please also consider rate limiting in your design');
agent.inject('Switch to OAuth2 instead of JWT', 'developer');  // 'developer' role

// The message is queued and delivered on the agent's next agentic loop iteration.
// Safe to call while the agent is running.

This is used internally by the send_message orchestration tool, but can also be called directly on any Agent instance.

Worker Agent Lifecycle

Workers are persistent — they remember their reasoning across turns:

  1. Created via assign_turn(agent=name, type=type, instruction=...) — auto-creates with system prompt, tools, shared workspace
  2. Assigned turns — each subsequent assign_turn calls agent.run(instruction) on the same instance
  3. Context accumulates — the worker's context grows with each turn (compaction handles limits)
  4. Destroyed via destroy_agent(name) or when the orchestrator is destroyed

Custom System Prompt

Override the auto-generated prompt for specialized workflows:

typescript
const orchestrator = await createOrchestrator({
  connector: 'openai',
  model: 'gpt-4.1',
  systemPrompt: `You are a QA team lead. For every task:
1. assign_turn a "developer" to write code
2. assign_turn a "tester" to write tests
3. Both run concurrently (assign_turn is always async)
4. If tests fail, send_message the failure details to the developer
5. assign_turn the developer again to fix, repeat until all tests pass`,
  agentTypes: {
    developer: { systemPrompt: '...', tools: [writeFile, editFile] },
    tester: { systemPrompt: '...', tools: [readFile, bash] },
  },
});

Per-Type Configuration

Each agent type can have its own model, connector, and features:

typescript
const orchestrator = await createOrchestrator({
  connector: 'openai',
  model: 'gpt-4.1',  // Default
  agentTypes: {
    planner: {
      systemPrompt: 'You are a strategic planner...',
      model: 'gpt-4.1',      // Use the best model for planning
      connector: 'openai',
    },
    coder: {
      systemPrompt: 'You are a fast coder...',
      model: 'gpt-4o-mini',  // Use a faster/cheaper model for coding
      connector: 'openai',
      tools: [readFile, writeFile, editFile, bash],
    },
    reviewer: {
      systemPrompt: 'You are a code reviewer...',
      model: 'claude-sonnet-4-20250514',  // Different provider entirely
      connector: 'anthropic',
      tools: [readFile, grep],
    },
  },
});

Documentation snapshot · 2026-11-02Suggest a correction ↗

Search documentation

Type to search the v2 documentation.