### Description
* Fix `get_graph()` generating an unexpected conditional edge to
`__end__` when the last step has a single (non-terminal) source and the
graph is cyclic.
### Issue
* There was a fallback path that was triggered in `draw_graph()` when,
for a Pregel instance; no termini exist and there is only a single step
source (the last one). In this case an edge was added: (last source) ->
`__end__`, even when another node already had a valid edge: (node) ->
`__end__`.
See this example:
<details>
<summary>code</summary>
```python
from langgraph.graph import END, START, StateGraph
from pydantic import BaseModel
class State(TypedDict):
messages: list[str]
def chatbot_node(state: State) -> State:
return {"messages": state["messages"] + ["chatbot"]}
def tools_node(state: State) -> State:
return {"messages": state["messages"] + ["tools"]}
def human_node(state: State) -> State:
return {"messages": state["messages"] + ["human"]}
def tools_condition(_: State) -> str:
return "tools"
def end_condition(_: State) -> str:
return "chatbot"
workflow = StateGraph(State)
workflow.add_node("chatbot", chatbot_node)
workflow.add_node("tools", tools_node)
workflow.add_node("human", human_node)
workflow.add_edge(START, "human")
workflow.add_edge("tools", "chatbot")
# graph_builder.add_edge("chatbot", "human") !!!
workflow.add_conditional_edges(
"chatbot", tools_condition, {"tools": "tools", "human": "human"}
)
workflow.add_conditional_edges(
"human", end_condition, {"chatbot": "chatbot", END: END}
)
app = workflow.compile()
mermaid = app.get_graph().draw_mermaid()
```
</details>
The code above, as-is, generates the graph on the left. There is an
unexpected conditional edge: chatbot -> `__end__`. If you uncomment the
commented line and introduce a static edge: chatbot -> human,
`get_graph()` returns the correct representation:
1 Without `graph_builder.add_edge("chatbot", "human")` | 2 With
`graph_builder.add_edge("chatbot", "human")`
:-------------------------:|:-------------------------:

|

* In case 1), the graph is cyclic so termini is empty, and the last
`step_sources` set during the static walk contains only the chatbot
node, so an edge is added: chatbot -> `__end__`.
* In case 2), the graph is cyclic so termini is empty, and the last
`step_sources` set during the static walk contains only the human node,
so an edge is added: human -> `__end__`, but `add_edge()` dedups (the
edge already exists) so the graph appears correct.
### Solution
* Check that no valid edges: (node) -> `__end__` exist before triggering
the fallback path and creating an edge.
Before | After
:-------------------------:|:-------------------------:

|

After: The graph is cyclic so termini is empty, and the last
`step_sources` contains the chatbot node, but an edge already exists:
human -> `__end__`, so no more edges are added.
### Tests
* `test_get_graph_nonterminal_last_step_source()` which asserts no
unexpected edge to `__end__` is produced from the last nonterminal step
source.
### Issue
Closes #4394
---------
Co-authored-by: Sydney Runkle <sydneymarierunkle@gmail.com>
Co-authored-by: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com>
Trusted by companies shaping the future of agents – including Klarna, Replit, Elastic, and more – LangGraph is a low-level orchestration framework for building, managing, and deploying long-running, stateful agents.
Get started
Install LangGraph:
pip install -U langgraph
Then, create an agent using prebuilt components:
# pip install -qU "langchain[anthropic]" to call the model
from langgraph.prebuilt import create_react_agent
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
prompt="You are a helpful assistant"
)
# Run the agent
agent.invoke(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
)
For more information, see the Quickstart. Or, to learn how to build an agent workflow with a customizable architecture, long-term memory, and other complex task handling, see the LangGraph basics tutorials.
Core benefits
LangGraph provides low-level supporting infrastructure for any long-running, stateful workflow or agent. LangGraph does not abstract prompts or architecture, and provides the following central benefits:
- Durable execution: Build agents that persist through failures and can run for extended periods, automatically resuming from exactly where they left off.
- Human-in-the-loop: Seamlessly incorporate human oversight by inspecting and modifying agent state at any point during execution.
- Comprehensive memory: Create truly stateful agents with both short-term working memory for ongoing reasoning and long-term persistent memory across sessions.
- Debugging with LangSmith: Gain deep visibility into complex agent behavior with visualization tools that trace execution paths, capture state transitions, and provide detailed runtime metrics.
- Production-ready deployment: Deploy sophisticated agent systems confidently with scalable infrastructure designed to handle the unique challenges of stateful, long-running workflows.
LangGraph’s ecosystem
While LangGraph can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools for building agents. To improve your LLM application development, pair LangGraph with:
- LangSmith — Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
- LangGraph Platform — Deploy and scale agents effortlessly with a purpose-built deployment platform for long running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in LangGraph Studio.
- LangChain – Provides integrations and composable components to streamline LLM application development.
Note
Looking for the JS version of LangGraph? See the JS repo and the JS docs.
Additional resources
- Guides: Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.).
- Reference: Detailed reference on core classes, methods, how to use the graph and checkpointing APIs, and higher-level prebuilt components.
- Examples: Guided examples on getting started with LangGraph.
- LangChain Forum: Connect with the community and share all of your technical questions, ideas, and feedback.
- LangChain Academy: Learn the basics of LangGraph in our free, structured course.
- Templates: Pre-built reference apps for common agentic workflows (e.g. ReAct agent, memory, retrieval etc.) that can be cloned and adapted.
- Case studies: Hear how industry leaders use LangGraph to ship AI applications at scale.
Acknowledgements
LangGraph is inspired by Pregel and Apache Beam. The public interface draws inspiration from NetworkX. LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.