Understanding the LangGraph Director Graph in OpenMAIC
The LangGraph Director Graph in OpenMAIC is a stateless StateGraph defined in 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 and is responsible for:
- Maintaining structured conversation state via
OrchestratorState - Determining the next speaker through the
directornode - 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:
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, 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, thelanguageModelinstance, and turn counters - Mutable routing fields:
currentAgentId(which agent is selected),agentResponses(accumulated outputs), andshouldEnd(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:
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:
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) 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.tsas a deterministic StateGraph that processes one conversational turn per request. - It uses a static topology (
START → director → END) with conditional routing toagent_generateonly 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()instateless-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 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, which defines the OrchestratorState interface, the director node logic, and createOrchestrationGraph(). Execution wiring appears in lib/orchestration/stateless-generate.ts, while lib/orchestration/ai-sdk-adapter.ts provides the bridge to language models. Supporting logic for prompt construction exists in lib/orchestration/director-prompt.ts.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →