# Understanding the LangGraph Director Graph in OpenMAIC

> Discover the LangGraph Director Graph in OpenMAIC. Learn how this stateless StateGraph orchestrates multi-agent conversations by directing requests to agents, users, or ending the chat.

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

---

**The LangGraph Director Graph in OpenMAIC is a stateless StateGraph defined in [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts) that orchestrates multi-agent conversations by routing each request through a director node, which decides whether to invoke an agent, prompt the user, or end the conversation.**

OpenMAIC is an open-source multi-agent conversation framework developed by THU-MAIC. At its core, the **LangGraph Director Graph** serves as the deterministic orchestration engine that coordinates which participant—whether AI agent or human user—should act next in a single conversational turn.

## What Is the LangGraph Director Graph?

The director graph is the central orchestration layer built using LangGraph’s `StateGraph` primitive. Unlike persistent workflow engines, this implementation operates as a **stateless, single-round processor**: it accepts a request, executes at most one `director → agent` cycle, and returns the result without maintaining server-side history between calls.

According to the OpenMAIC source code, the graph is constructed in [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts) and is responsible for:
- Maintaining structured conversation state via `OrchestratorState`
- Determining the next speaker through the `director` node
- Conditionally routing to agent execution or termination

## Graph Topology and Execution Flow

### Static Graph Structure

The director graph employs a fixed topology optimized for deterministic routing:

```text
START → director ──(end)──→ END
        │
        └─(next)→ agent_generate ──→ END

```

This structure, documented in the file header at lines 4–9 of [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts), ensures that every request enters through the `director` node and exits through `END`, optionally passing through `agent_generate` if the director decides an agent should speak.

### State Definition with OrchestratorState

All data flowing through the graph is strictly typed via the `OrchestratorState` interface (lines 48–77). This state object includes:

- **Immutable context**: Incoming messages, `availableAgentIds`, the `languageModel` instance, and turn counters
- **Mutable routing fields**: `currentAgentId` (which agent is selected), `agentResponses` (accumulated outputs), and `shouldEnd` (termination flag)

By annotating these fields, the graph ensures type safety while allowing the director node to modify routing decisions dynamically.

## The Director Node Decision Logic

The `director` node (implemented around line 91) contains the core intelligence for orchestration, with distinct optimization paths for different scenario sizes.

### Single-Agent Fast Path

When only one agent is configured, the director bypasses LLM calls entirely to reduce latency. As implemented in lines 91–100:

```typescript
if (state.availableAgentIds.length <= 1) {
  const agentId = state.availableAgentIds[0] ?? 'default-1';
  if (state.turnCount === 0) {
    // Dispatch the sole agent without an LLM call
    return { currentAgentId: agentId, shouldEnd: false };
  }
  // After the agent responded, cue the user and finish
  return { shouldEnd: true };
}

```

This hardcoded logic eliminates unnecessary model inference for simple, single-agent workflows.

### Multi-Agent LLM Routing

For multi-agent scenarios, the director constructs a comprehensive prompt using `buildDirectorPrompt()` and queries the language model via `AISdkLangGraphAdapter` (lines 150–190). The prompt includes:

- Agent descriptions and capabilities
- Conversation summaries
- Previous agent responses
- Turn count and discussion context
- Whiteboard state and user profile

The LLM returns a structured decision parsed by `parseDirectorDecision()`, indicating which agent should speak, whether to prompt the user, or if the conversation should conclude.

## Building and Executing the Graph

The `createOrchestrationGraph()` function (lines 84–95) wires the nodes together using `directorCondition` to determine conditional edges. This compiled graph is then invoked in [`lib/orchestration/stateless-generate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/stateless-generate.ts):

```typescript
const graph = createOrchestrationGraph();            // ← director graph
const state = buildInitialState(request, llm);      // inject LM + config
const result = await graph.invoke(state);           // runs START → director → (agent_generate) → END

```

This execution pattern (shown in lines 25–30 of [`stateless-generate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/stateless-generate.ts)) demonstrates the stateless nature of the orchestration: the graph is instantiated, invoked once with fresh state, and discarded.

## Summary

- The **LangGraph Director Graph** is defined in [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts) as a deterministic StateGraph that processes one conversational turn per request.
- It uses a static topology (`START → director → END`) with conditional routing to `agent_generate` only when required.
- **OrchestratorState** (lines 48–77) provides type-safe data flow, tracking immutable context and mutable routing fields like `currentAgentId`.
- Single-agent deployments use a fast-path code branch avoiding LLM latency, while multi-agent scenarios leverage sophisticated prompt engineering and the `AISdkLangGraphAdapter`.
- Stateless execution occurs through `graph.invoke()` in [`stateless-generate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/stateless-generate.ts), making the architecture serverless and scalable.

## Frequently Asked Questions

### What is the purpose of the director node in OpenMAIC?

The director node serves as the central router for multi-agent conversations. It evaluates the current conversation state and decides which agent should speak next, whether to prompt the user for input, or if the interaction should terminate. This node is the only decision-making point in the graph topology, ensuring predictable control flow.

### How does the director graph handle single-agent versus multi-agent scenarios?

For **single-agent** configurations, the director implements a fast-path optimization that assigns the sole agent to speak without invoking an LLM, reducing latency and token costs. For **multi-agent** configurations, the director builds a detailed system prompt containing agent capabilities, conversation history, and context, then queries the language model through `AISdkLangGraphAdapter` to intelligently select the next participant.

### Is the LangGraph Director Graph in OpenMAIC stateful or stateless?

The director graph is **stateless**. Each invocation processes exactly one conversational turn. The [`stateless-generate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/stateless-generate.ts) entry point builds fresh state from the incoming `StatelessChatRequest`, passes it through the graph once via `graph.invoke()`, and returns the result without persisting memory between requests. This design enables horizontal scaling and serverless deployment patterns.

### Which source files are essential for understanding the director graph implementation?

The primary implementation resides in [`lib/orchestration/director-graph.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-graph.ts), which defines the `OrchestratorState` interface, the director node logic, and `createOrchestrationGraph()`. Execution wiring appears in [`lib/orchestration/stateless-generate.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/stateless-generate.ts), while [`lib/orchestration/ai-sdk-adapter.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/ai-sdk-adapter.ts) provides the bridge to language models. Supporting logic for prompt construction exists in [`lib/orchestration/director-prompt.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/orchestration/director-prompt.ts).