Depends on #8535 `libs/checkpoint-conformance/tests/` only validates `InMemorySaver`. `checkpoint-sqlite` has had a `test_conformance_delta.py` for a while, but it guards on `importorskip("langgraph.checkpoint.conformance")` and the package was never in its test environment — so it has been skipping silently every run. `checkpoint-postgres` had no runner at all. Net effect: the shared checkpointer contract was effectively unenforced everywhere except in-memory. ### Change Adds `langgraph-checkpoint-conformance` to the `test` dependency group of both packages, with a path source like the existing `langgraph-checkpoint` entry. That alone is what makes sqlite's runner start executing. Postgres gets the equivalent runner. Both pass the `delta_channel_history` capability. ### Why it's stacked Against `main`'s Postgres, the new runner fails: ``` Capability delta_channel_history failed: test_history_migration_plain_value_as_seed ``` That is exactly the bug #8535 fixes, and it had been failing unnoticed precisely because nothing ran the suite there. So this is based on that branch rather than `main` — the diff here is the one conformance commit, and it will retarget once #8535 lands. Reasonable to read that as the change justifying itself: the first thing turning the suite on did was catch a real bug that had been sitting in `main`. ### Verified `checkpoint-postgres` 270 passed on PG 15 and 16, `checkpoint-sqlite` 118 passed, lint and `ty` clean in both. The `uv.lock` updates are the conformance package entry only. ### Note The sync `PostgresSaver` and `SqliteSaver` aren't covered — the conformance harness reports every capability as `detected=False` for them, so only the async savers are exercised. Pre-existing and not addressed here, but worth knowing the coverage isn't total.
LangGraph Prebuilt
To help you ship LangGraph apps to production faster, check out LangSmith. LangSmith is a unified developer platform for building, testing, and monitoring LLM applications.
Quick Install
uv add langgraph
🤔 What is this?
This library defines high-level APIs for creating and executing LangGraph agents and tools. It includes prebuilt components such as create_react_agent, ToolNode, validation helpers, and Agent Inbox schemas.
📖 Documentation
For full documentation, see the API reference. For conceptual guides and tutorials, see the LangGraph Docs.
Important
This library is bundled with
langgraph; most users should installlanggraphinstead of installinglanggraph-prebuiltdirectly.
Agents
langgraph-prebuilt provides an implementation of a tool-calling ReAct-style agent - create_react_agent:
uv add langchain-anthropic
from langchain_anthropic import ChatAnthropic
from langgraph.prebuilt import create_react_agent
# Define the tools for the agent to use
def search(query: str):
"""Call to surf the web."""
# This is a placeholder, but don't tell the LLM that...
if "sf" in query.lower() or "san francisco" in query.lower():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tools = [search]
model = ChatAnthropic(model="claude-3-7-sonnet-latest")
app = create_react_agent(model, tools)
# run the agent
app.invoke(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
)
Tools
ToolNode
langgraph-prebuilt provides an implementation of a node that executes tool calls - ToolNode:
from langgraph.prebuilt import ToolNode
from langchain_core.messages import AIMessage
def search(query: str):
"""Call to surf the web."""
# This is a placeholder, but don't tell the LLM that...
if "sf" in query.lower() or "san francisco" in query.lower():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tool_node = ToolNode([search])
tool_calls = [{"name": "search", "args": {"query": "what is the weather in sf"}, "id": "1"}]
ai_message = AIMessage(content="", tool_calls=tool_calls)
# execute tool call
tool_node.invoke({"messages": [ai_message]})
ValidationNode
langgraph-prebuilt provides an implementation of a node that validates tool calls against a pydantic schema - ValidationNode:
from pydantic import BaseModel, field_validator
from langgraph.prebuilt import ValidationNode
from langchain_core.messages import AIMessage
class SelectNumber(BaseModel):
a: int
@field_validator("a")
def a_must_be_meaningful(cls, v):
if v != 37:
raise ValueError("Only 37 is allowed")
return v
validation_node = ValidationNode([SelectNumber])
validation_node.invoke({
"messages": [AIMessage("", tool_calls=[{"name": "SelectNumber", "args": {"a": 42}, "id": "1"}])]
})
Agent Inbox
The library contains schemas for using the Agent Inbox with LangGraph agents. Learn more about how to use Agent Inbox here.
from langgraph.types import interrupt
from langgraph.prebuilt.interrupt import HumanInterrupt, HumanResponse
def my_graph_function():
# Extract the last tool call from the `messages` field in the state
tool_call = state["messages"][-1].tool_calls[0]
# Create an interrupt
request: HumanInterrupt = {
"action_request": {
"action": tool_call['name'],
"args": tool_call['args']
},
"config": {
"allow_ignore": True,
"allow_respond": True,
"allow_edit": False,
"allow_accept": False
},
"description": _generate_email_markdown(state) # Generate a detailed markdown description.
}
# Send the interrupt request inside a list, and extract the first response
response = interrupt([request])[0]
if response['type'] == "response":
# Do something with the response
...
📕 Releases & Versioning
See our Releases and Versioning policies.
💁 Contributing
As an open-source project in a rapidly developing field, we are extremely open to contributions, whether it be in the form of a new feature, improved infrastructure, or better documentation.
For detailed information on how to contribute, see the Contributing Guide.