OpenMAIC Orchestration and Director Graph Implementation: Key Files Explained

OpenMAIC's multi-agent orchestration relies on a LangGraph-based state machine centered in lib/orchestration/director-graph.ts, which coordinates with prompt builders in director-prompt.ts and prompt-builder.ts, state utilities in the summarizers/ directory, and agent resolution via registry/store.ts to execute stateless, single-turn director-to-agent cycles.

OpenMAIC is an open-source framework for multi-agent conversational AI that uses a lightweight state machine to manage collaborative discussions. The orchestration logic driving these interactions resides primarily within the lib/orchestration package, implementing a deterministic director graph pattern that routes conversations between specialized agents. Understanding these key files is essential for developers extending OpenMAIC's conversational capabilities or debugging agent coordination logic.

The Director Graph State Machine (director-graph.ts)

The heart of OpenMAIC's orchestration lives in lib/orchestration/director-graph.ts, which defines the LangGraph StateGraph responsible for every conversation turn. This file implements a stateless, single-round orchestration contract where each request executes at most one director-to-agent transition.

Graph Structure and Node Definitions

The director-graph.ts file declares the OrchestratorState annotation to type the graph's state channels. It implements two primary computational nodes:

  • Director node: Determines the next speaking agent based on conversation context, available agents, and whiteboard state
  • Agent-generate node: Streams the selected agent's response using structured prompts

The graph follows a linear flow: START → director → agent_generate → END, ensuring deterministic execution for each turn.

Graph Compilation and State Initialization

Two critical factory functions manage graph lifecycle:

  • createOrchestrationGraph(): Compiles and returns the executable StateGraph instance
  • buildInitialState(): Materializes an OrchestratorState from a StatelessChatRequest, preparing the initial context for graph invocation
// Example: create an orchestration graph and run a single request
import { createOrchestrationGraph, buildInitialState } from '@/lib/orchestration/director-graph';
import { getDefaultLanguageModel } from '@/lib/providers/openai'; // (illustrative)

async function runOneTurn(request) {
  const lm = await getDefaultLanguageModel();               // LanguageModel instance
  const graph = createOrchestrationGraph();                // compiled StateGraph
  const initial = buildInitialState(request, lm);          // populate OrchestratorState

  // `graph.invoke` executes the START → director → (agent_generate) → END flow
  const result = await graph.invoke(initial);
  return result; // contains agentResponses, whiteboardLedger, etc.
}

Prompt Engineering for Multi-Agent Coordination

Effective multi-agent orchestration requires carefully constructed prompts for both the director (orchestrator) and individual agents.

Director Prompt Construction (director-prompt.ts)

The lib/orchestration/director-prompt.ts file builds the system prompt presented to the director LLM. It assembles context including available agent descriptions, prior conversation responses, whiteboard actions, discussion context, and student profile metadata.

The module exports buildDirectorPrompt() for prompt generation and parseDirectorDecision() to deserialize the LLM's JSON output into actionable routing decisions.

// Example: build the director prompt directly (useful for testing)
import { buildDirectorPrompt } from '@/lib/orchestration/director-prompt';
import { exampleAgents, exampleHistory } from '@/test/fixtures';

const prompt = buildDirectorPrompt(
  exampleAgents,
  exampleHistory.summary,
  [],               // no agents have spoken yet
  0,                // first turn
  { topic: 'Photosynthesis' },
  null,            // no trigger agent
  [],              // empty whiteboard ledger
  { nickname: 'Alice' },
  true
);
console.log(prompt); // → system prompt string passed to the LLM

Agent Prompt Generation (prompt-builder.ts)

Individual agents receive structured prompts via lib/orchestration/prompt-builder.ts. The buildStructuredPrompt() function composes each agent's context, incorporating store state, discussion history, and whiteboard ledger entries to ensure agents have complete conversational awareness.

State Management and Utilities

Supporting the core graph are specialized utilities that condense and format conversational state.

Conversation Summarization (summarizers/)

The lib/orchestration/summarizers/ directory contains essential state transformers:

Agent Registry Resolution (registry/store.ts)

The lib/orchestration/registry/store.ts file maintains the global agent registry via useAgentRegistry. It provides applyGeneratedAgentsToRegistry() for dynamic agent registration and supports agent resolution through resolveAgent(). This function checks request-scoped overrides before falling back to the shared registry, enabling flexible agent substitution without modifying global state.

Type Safety and Shared Contracts (types.ts)

The lib/orchestration/types.ts file establishes the TypeScript contracts governing the entire orchestration layer. Key definitions include:

  • AgentTurnSummary: Metadata describing an agent's participation in a turn
  • WhiteboardActionRecord: Structured representation of whiteboard modifications
  • StatelessChatRequest: The input contract for initiating orchestration cycles

These types ensure type safety across graph nodes, prompt builders, and registry operations.

Summary

  • lib/orchestration/director-graph.ts defines the LangGraph StateGraph with director and agent-generate nodes, providing createOrchestrationGraph() and buildInitialState() for execution.
  • lib/orchestration/director-prompt.ts constructs the director LLM's system prompt and parses its JSON routing decisions via buildDirectorPrompt() and parseDirectorDecision().
  • lib/orchestration/prompt-builder.ts supplies buildStructuredPrompt() for generating per-agent system prompts with full conversational context.
  • lib/orchestration/summarizers/ utilities condense chat history, convert message formats, and manage whiteboard state for prompt injection.
  • lib/orchestration/registry/store.ts manages agent registration through useAgentRegistry and agent resolution via resolveAgent() with support for request-scoped overrides.
  • lib/orchestration/types.ts exports shared TypeScript definitions including OrchestratorState, AgentTurnSummary, and StatelessChatRequest that bind the orchestration layer together.

Frequently Asked Questions

What is the role of the director node in OpenMAIC's graph?

The director node is the decision-making component within lib/orchestration/director-graph.ts that determines which agent should speak next based on the current conversation state. It receives the assembled prompt from director-prompt.ts, queries the LLM, and parses the response to identify the target agent for the current turn.

How does OpenMAIC maintain state across multiple conversation turns?

OpenMAIC implements a stateless, single-round orchestration contract where the server does not maintain session state between requests. The client serializes the conversation history and whiteboard ledger, passing them in each StatelessChatRequest. The buildInitialState() function materializes the full OrchestratorState from this request payload, allowing the graph to execute deterministically without server-side persistence.

Can I override specific agents for a single request without modifying the global registry?

Yes. The resolveAgent() function in lib/orchestration/registry/store.ts first checks for request-scoped agent overrides before falling back to the global registry accessed via useAgentRegistry. This enables temporary agent substitution for specific conversation turns while leaving the shared registry unchanged.

What data structure carries conversation context between the director and agent nodes?

The OrchestratorState annotation, defined in lib/orchestration/director-graph.ts and typed in types.ts, carries all context including conversation history, whiteboard actions, agent responses, and student profiles. The summarizers in lib/orchestration/summarizers/ condense this state into prompts suitable for LLM consumption.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →