LangGraph.js: Stateful, Multi-Step Workflows
Just like its Python counterpart, LangGraph.js models a workflow as an explicit graph of typed state, nodes, and edges, instead of an implicit "loop until done." It's the tool to reach for once AgentExecutor's simple loop isn't enough, when you need branches, loops back to an earlier step, or several cooperating steps.
Defining typed state
Annotation.Root defines the shape of the state every node reads and updates, typed just like any other TypeScript object, at any point in the graph's execution, the current state is a plain, inspectable, fully-typed value.
Defining nodes
Each node is a plain async function that receives the current state and returns a partial object of updates to merge in, a real searchNode would call a search tool and answerNode would run an LCEL chain, kept as placeholders here since both need real API access.
Wiring the graph
addEdge('search', 'answer') is a fixed transition, addEdge('answer', END) marks answer as terminal, END is a special constant meaning "the graph is finished here."
Conditional edges
addConditionalEdges routes to a different next node based on a function of the current state, here looping back to search if results still look too thin, this explicit, typed branching is what a plain AgentExecutor loop doesn't give you directly.
TIP
The return type 'search' | 'answer' on needsMoreResearch is doing real work: TypeScript checks that the routing function can only return names of nodes that actually exist in the graph.