# OpenMAIC Orchestration and Director Graph Implementation: Key Files Explained

> Explore OpenMAIC orchestration and director graph implementation. Understand key files like director-graph.ts and prompt-builder.ts to manage multi-agent systems effectively.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: internals
- Published: 2026-09-04

---

**OpenMAIC's multi-agent orchestration relies on a LangGraph-based state machine centered in [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts), which coordinates with prompt builders in [`director-prompt.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/director-prompt.ts) and [`prompt-builder.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/prompt-builder.ts), state utilities in the `summarizers/` directory, and agent resolution via [`registry/store.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/director-graph.ts))

The heart of OpenMAIC's orchestration lives in [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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

```typescript
// 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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/director-prompt.ts))

The [`lib/orchestration/director-prompt.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.

```typescript
// 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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/prompt-builder.ts))

Individual agents receive structured prompts via [`lib/orchestration/prompt-builder.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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:

- [`conversation-summary.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/conversation-summary.ts): Condenses chat history into concise summaries for the director prompt
- [`message-converter.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/message-converter.ts): Transforms internal message objects into OpenAI-compatible message structures
- [`whiteboard-ledger.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/whiteboard-ledger.ts): Exposes whiteboard-specific context and action records
- [`state-context.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/state-context.ts): Manages general state serialization for graph transitions

### Agent Registry Resolution ([`registry/store.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/registry/store.ts))

The [`lib/orchestration/registry/store.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/types.ts))

The [`lib/orchestration/types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts) and typed in [`types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.