Compare commits

...
Author SHA1 Message Date
William Fu-Hinthorn 52910f3b04 InMemorySaver 2024-10-06 20:49:11 -07:00
41 changed files with 181 additions and 172 deletions
+3 -3
View File
@@ -60,7 +60,7 @@ from typing import Annotated, Literal, TypedDict
from langchain_core.messages import HumanMessage from langchain_core.messages import HumanMessage
from langchain_anthropic import ChatAnthropic from langchain_anthropic import ChatAnthropic
from langchain_core.tools import tool from langchain_core.tools import tool
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph, MessagesState from langgraph.graph import END, START, StateGraph, MessagesState
from langgraph.prebuilt import ToolNode from langgraph.prebuilt import ToolNode
@@ -125,7 +125,7 @@ workflow.add_conditional_edges(
workflow.add_edge("tools", 'agent') workflow.add_edge("tools", 'agent')
# Initialize memory to persist state between graph runs # Initialize memory to persist state between graph runs
checkpointer = MemorySaver() checkpointer = InMemorySaver()
# Finally, we compile it! # Finally, we compile it!
# This compiles it into a LangChain Runnable, # This compiles it into a LangChain Runnable,
@@ -201,7 +201,7 @@ final_state["messages"][-1].content
<summary>Compile the graph.</summary> <summary>Compile the graph.</summary>
- When we compile the graph, we turn it into a LangChain [Runnable](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface), which automatically enables calling `.invoke()`, `.stream()` and `.batch()` with your inputs - When we compile the graph, we turn it into a LangChain [Runnable](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface), which automatically enables calling `.invoke()`, `.stream()` and `.batch()` with your inputs
- We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory, human-in-the-loop workflows, time travel and more. In our case we use `MemorySaver` - a simple in-memory checkpointer - We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory, human-in-the-loop workflows, time travel and more. In our case we use `InMemorySaver` - a simple in-memory checkpointer
</details> </details>
6. <details> 6. <details>
@@ -392,7 +392,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver" "from langgraph.checkpoint.memory import InMemorySaver"
] ]
}, },
{ {
@@ -402,7 +402,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"checkpointer = MemorySaver()\n", "checkpointer = InMemorySaver()\n",
"graph_with_memory = create_react_agent(model, tools, checkpointer=checkpointer)" "graph_with_memory = create_react_agent(model, tools, checkpointer=checkpointer)"
] ]
}, },
+1 -1
View File
@@ -148,7 +148,7 @@ LangGraph's [persistence layer](https://langchain-ai.github.io/langgraph/concept
```python ```python
# Compile the graph with a checkpointer # Compile the graph with a checkpointer
checkpointer = MemorySaver() checkpointer = InMemorySaver()
graph = workflow.compile(checkpointer=checkpointer) graph = workflow.compile(checkpointer=checkpointer)
# Invoke the graph with a thread ID # Invoke the graph with a thread ID
+4 -4
View File
@@ -26,7 +26,7 @@ Let's see what checkpoints are saved when a simple graph is invoked as follows:
```python ```python
from langgraph.graph import StateGraph, START, END from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from typing import Annotated from typing import Annotated
from typing_extensions import TypedDict from typing_extensions import TypedDict
from operator import add from operator import add
@@ -49,7 +49,7 @@ workflow.add_edge(START, "node_a")
workflow.add_edge("node_a", "node_b") workflow.add_edge("node_a", "node_b")
workflow.add_edge("node_b", END) workflow.add_edge("node_b", END)
checkpointer = MemorySaver() checkpointer = InMemorySaver()
graph = workflow.compile(checkpointer=checkpointer) graph = workflow.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "1"}} config = {"configurable": {"thread_id": "1"}}
@@ -220,7 +220,7 @@ The final thing you can optionally specify when calling `update_state` is `as_no
Under the hood, checkpointing is powered by checkpointer objects that conform to [BaseCheckpointSaver][langgraph.checkpoint.base.BaseCheckpointSaver] interface. LangGraph provides several checkpointer implementations, all implemented via standalone, installable libraries: Under the hood, checkpointing is powered by checkpointer objects that conform to [BaseCheckpointSaver][langgraph.checkpoint.base.BaseCheckpointSaver] interface. LangGraph provides several checkpointer implementations, all implemented via standalone, installable libraries:
* `langgraph-checkpoint`: The base interface for checkpointer savers ([BaseCheckpointSaver][langgraph.checkpoint.base.BaseCheckpointSaver]) and serialization/deserialization interface ([SerializerProtocol][langgraph.checkpoint.serde.base.SerializerProtocol]). Includes in-memory checkpointer implementation ([MemorySaver][langgraph.checkpoint.memory.MemorySaver]) for experimentation. LangGraph comes with `langgraph-checkpoint` included. * `langgraph-checkpoint`: The base interface for checkpointer savers ([BaseCheckpointSaver][langgraph.checkpoint.base.BaseCheckpointSaver]) and serialization/deserialization interface ([SerializerProtocol][langgraph.checkpoint.serde.base.SerializerProtocol]). Includes in-memory checkpointer implementation ([InMemorySaver][langgraph.checkpoint.memory.InMemorySaver]) for experimentation. LangGraph comes with `langgraph-checkpoint` included.
* `langgraph-checkpoint-sqlite`: An implementation of LangGraph checkpointer that uses SQLite database ([SqliteSaver][langgraph.checkpoint.sqlite.SqliteSaver] / [AsyncSqliteSaver][langgraph.checkpoint.sqlite.aio.AsyncSqliteSaver]). Ideal for experimentation and local workflows. Needs to be installed separately. * `langgraph-checkpoint-sqlite`: An implementation of LangGraph checkpointer that uses SQLite database ([SqliteSaver][langgraph.checkpoint.sqlite.SqliteSaver] / [AsyncSqliteSaver][langgraph.checkpoint.sqlite.aio.AsyncSqliteSaver]). Ideal for experimentation and local workflows. Needs to be installed separately.
* `langgraph-checkpoint-postgres`: An advanced checkpointer that uses Postgres database ([PostgresSaver][langgraph.checkpoint.postgres.PostgresSaver] / [AsyncPostgresSaver][langgraph.checkpoint.postgres.aio.AsyncPostgresSaver]), used in LangGraph Cloud. Ideal for using in production. Needs to be installed separately. * `langgraph-checkpoint-postgres`: An advanced checkpointer that uses Postgres database ([PostgresSaver][langgraph.checkpoint.postgres.PostgresSaver] / [AsyncPostgresSaver][langgraph.checkpoint.postgres.aio.AsyncPostgresSaver]), used in LangGraph Cloud. Ideal for using in production. Needs to be installed separately.
@@ -236,7 +236,7 @@ Each checkpointer conforms to [BaseCheckpointSaver][langgraph.checkpoint.base.Ba
If the checkpointer is used with asynchronous graph execution (i.e. executing the graph via `.ainvoke`, `.astream`, `.abatch`), asynchronous versions of the above methods will be used (`.aput`, `.aput_writes`, `.aget_tuple`, `.alist`). If the checkpointer is used with asynchronous graph execution (i.e. executing the graph via `.ainvoke`, `.astream`, `.abatch`), asynchronous versions of the above methods will be used (`.aput`, `.aput_writes`, `.aget_tuple`, `.alist`).
!!! note Note !!! note Note
For running your graph asynchronously, you can use `MemorySaver`, or async versions of Sqlite/Postgres checkpointers -- `AsyncSqliteSaver` / `AsyncPostgresSaver` checkpointers. For running your graph asynchronously, you can use `InMemorySaver`, or async versions of Sqlite/Postgres checkpointers -- `AsyncSqliteSaver` / `AsyncPostgresSaver` checkpointers.
### Serializer ### Serializer
@@ -135,9 +135,9 @@
"tools = [get_weather]\n", "tools = [get_weather]\n",
"\n", "\n",
"# We need a checkpointer to enable human-in-the-loop patterns\n", "# We need a checkpointer to enable human-in-the-loop patterns\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Define the graph\n", "# Define the graph\n",
"\n", "\n",
@@ -142,9 +142,9 @@
"\n", "\n",
"# We can add \"chat memory\" to the graph with LangGraph's checkpointer\n", "# We can add \"chat memory\" to the graph with LangGraph's checkpointer\n",
"# to retain the chat context between interactions\n", "# to retain the chat context between interactions\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Define the graph\n", "# Define the graph\n",
"\n", "\n",
@@ -154,7 +154,7 @@
"from langchain_anthropic import ChatAnthropic\n", "from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.runnables import RunnableConfig\n", "from langchain_core.runnables import RunnableConfig\n",
"from langgraph.graph import StateGraph, MessagesState, START\n", "from langgraph.graph import StateGraph, MessagesState, START\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.store.base import BaseStore\n", "from langgraph.store.base import BaseStore\n",
"\n", "\n",
"\n", "\n",
@@ -187,7 +187,7 @@
"builder.add_edge(START, \"call_model\")\n", "builder.add_edge(START, \"call_model\")\n",
"\n", "\n",
"# NOTE: we're passing the store object here when compiling the graph\n", "# NOTE: we're passing the store object here when compiling the graph\n",
"graph = builder.compile(checkpointer=MemorySaver(), store=in_memory_store)\n", "graph = builder.compile(checkpointer=InMemorySaver(), store=in_memory_store)\n",
"# If you're using LangGraph Cloud or LangGraph Studio, you don't need to pass the store or checkpointer when compiling the graph, since it's done automatically." "# If you're using LangGraph Cloud or LangGraph Studio, you don't need to pass the store or checkpointer when compiling the graph, since it's done automatically."
] ]
}, },
@@ -124,7 +124,7 @@
"source": [ "source": [
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n", "from langgraph.graph import StateGraph, START, END\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from IPython.display import Image, display\n", "from IPython.display import Image, display\n",
"\n", "\n",
"\n", "\n",
@@ -157,7 +157,7 @@
"builder.add_edge(\"step_3\", END)\n", "builder.add_edge(\"step_3\", END)\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Add\n", "# Add\n",
"graph = builder.compile(checkpointer=memory, interrupt_before=[\"step_3\"])\n", "graph = builder.compile(checkpointer=memory, interrupt_before=[\"step_3\"])\n",
@@ -270,7 +270,7 @@
"from langgraph.graph import MessagesState, START\n", "from langgraph.graph import MessagesState, START\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
"from langgraph.graph import END, StateGraph\n", "from langgraph.graph import END, StateGraph\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"\n", "\n",
"@tool\n", "@tool\n",
@@ -352,7 +352,7 @@
"workflow.add_edge(\"action\", \"agent\")\n", "workflow.add_edge(\"action\", \"agent\")\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Finally, we compile it!\n", "# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n", "# This compiles it into a LangChain Runnable,\n",
@@ -78,7 +78,7 @@
"from IPython.display import Image, display\n", "from IPython.display import Image, display\n",
"\n", "\n",
"from langgraph.graph import StateGraph, START, END\n", "from langgraph.graph import StateGraph, START, END\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.errors import NodeInterrupt\n", "from langgraph.errors import NodeInterrupt\n",
"\n", "\n",
"\n", "\n",
@@ -118,7 +118,7 @@
"builder.add_edge(\"step_3\", END)\n", "builder.add_edge(\"step_3\", END)\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Compile the graph with memory\n", "# Compile the graph with memory\n",
"graph = builder.compile(checkpointer=memory)\n", "graph = builder.compile(checkpointer=memory)\n",
@@ -126,7 +126,7 @@
"source": [ "source": [
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n", "from langgraph.graph import StateGraph, START, END\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from IPython.display import Image, display\n", "from IPython.display import Image, display\n",
"\n", "\n",
"\n", "\n",
@@ -159,7 +159,7 @@
"builder.add_edge(\"step_3\", END)\n", "builder.add_edge(\"step_3\", END)\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Add\n", "# Add\n",
"graph = builder.compile(checkpointer=memory, interrupt_before=[\"step_2\"])\n", "graph = builder.compile(checkpointer=memory, interrupt_before=[\"step_2\"])\n",
@@ -279,7 +279,7 @@
"from langchain_core.tools import tool\n", "from langchain_core.tools import tool\n",
"from langgraph.graph import MessagesState, START, END, StateGraph\n", "from langgraph.graph import MessagesState, START, END, StateGraph\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"\n", "\n",
"@tool\n", "@tool\n",
@@ -361,7 +361,7 @@
"workflow.add_edge(\"action\", \"agent\")\n", "workflow.add_edge(\"action\", \"agent\")\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Finally, we compile it!\n", "# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n", "# This compiles it into a LangChain Runnable,\n",
@@ -120,7 +120,7 @@
"source": [ "source": [
"from typing_extensions import TypedDict, Literal\n", "from typing_extensions import TypedDict, Literal\n",
"from langgraph.graph import StateGraph, START, END, MessagesState\n", "from langgraph.graph import StateGraph, START, END, MessagesState\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langchain_anthropic import ChatAnthropic\n", "from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.tools import tool\n", "from langchain_core.tools import tool\n",
"from langchain_core.messages import AIMessage\n", "from langchain_core.messages import AIMessage\n",
@@ -195,7 +195,7 @@
"builder.add_edge(\"run_tool\", \"call_llm\")\n", "builder.add_edge(\"run_tool\", \"call_llm\")\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Add\n", "# Add\n",
"graph = builder.compile(checkpointer=memory, interrupt_before=[\"human_review_node\"])\n", "graph = builder.compile(checkpointer=memory, interrupt_before=[\"human_review_node\"])\n",
@@ -115,7 +115,7 @@
"from langgraph.graph import MessagesState, START\n", "from langgraph.graph import MessagesState, START\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
"from langgraph.graph import END, StateGraph\n", "from langgraph.graph import END, StateGraph\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"\n", "\n",
"@tool\n", "@tool\n",
@@ -201,7 +201,7 @@
"workflow.add_edge(\"action\", \"agent\")\n", "workflow.add_edge(\"action\", \"agent\")\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Finally, we compile it!\n", "# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n", "# This compiles it into a LangChain Runnable,\n",
@@ -120,7 +120,7 @@
"source": [ "source": [
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.graph import StateGraph, START, END\n", "from langgraph.graph import StateGraph, START, END\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from IPython.display import Image, display\n", "from IPython.display import Image, display\n",
"\n", "\n",
"\n", "\n",
@@ -154,7 +154,7 @@
"builder.add_edge(\"step_3\", END)\n", "builder.add_edge(\"step_3\", END)\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Add\n", "# Add\n",
"graph = builder.compile(checkpointer=memory, interrupt_before=[\"human_feedback\"])\n", "graph = builder.compile(checkpointer=memory, interrupt_before=[\"human_feedback\"])\n",
@@ -475,9 +475,9 @@
"workflow.add_edge(\"ask_human\", \"agent\")\n", "workflow.add_edge(\"ask_human\", \"agent\")\n",
"\n", "\n",
"# Set up memory\n", "# Set up memory\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"# Finally, we compile it!\n", "# Finally, we compile it!\n",
"# This compiles it into a LangChain Runnable,\n", "# This compiles it into a LangChain Runnable,\n",
@@ -99,10 +99,10 @@
"\n", "\n",
"from langchain_anthropic import ChatAnthropic\n", "from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.messages import SystemMessage, RemoveMessage\n", "from langchain_core.messages import SystemMessage, RemoveMessage\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import MessagesState, StateGraph, START, END\n", "from langgraph.graph import MessagesState, StateGraph, START, END\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"# We will add a `summary` attribute (in addition to `messages` key,\n", "# We will add a `summary` attribute (in addition to `messages` key,\n",
@@ -106,11 +106,11 @@
"from langchain_anthropic import ChatAnthropic\n", "from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.tools import tool\n", "from langchain_core.tools import tool\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import MessagesState, StateGraph, START, END\n", "from langgraph.graph import MessagesState, StateGraph, START, END\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"@tool\n", "@tool\n",
@@ -97,11 +97,11 @@
"from langchain_anthropic import ChatAnthropic\n", "from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.tools import tool\n", "from langchain_core.tools import tool\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import MessagesState, StateGraph, START, END\n", "from langgraph.graph import MessagesState, StateGraph, START, END\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"@tool\n", "@tool\n",
@@ -228,11 +228,11 @@
"from langchain_anthropic import ChatAnthropic\n", "from langchain_anthropic import ChatAnthropic\n",
"from langchain_core.tools import tool\n", "from langchain_core.tools import tool\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import MessagesState, StateGraph, START\n", "from langgraph.graph import MessagesState, StateGraph, START\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"@tool\n", "@tool\n",
@@ -322,7 +322,7 @@
"source": [ "source": [
"from langchain_openai import ChatOpenAI\n", "from langchain_openai import ChatOpenAI\n",
"from langgraph.prebuilt import ToolNode, create_react_agent\n", "from langgraph.prebuilt import ToolNode, create_react_agent\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n", "model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n",
"tools = [get_context]\n", "tools = [get_context]\n",
@@ -330,7 +330,7 @@
"# ToolNode will automatically take care of injecting state into tools\n", "# ToolNode will automatically take care of injecting state into tools\n",
"tool_node = ToolNode(tools)\n", "tool_node = ToolNode(tools)\n",
"\n", "\n",
"checkpointer = MemorySaver()\n", "checkpointer = InMemorySaver()\n",
"graph = create_react_agent(model, tools, state_schema=State, checkpointer=checkpointer)" "graph = create_react_agent(model, tools, state_schema=State, checkpointer=checkpointer)"
] ]
}, },
@@ -524,7 +524,7 @@
"# ToolNode will automatically take care of injecting Store into tools\n", "# ToolNode will automatically take care of injecting Store into tools\n",
"tool_node = ToolNode(tools)\n", "tool_node = ToolNode(tools)\n",
"\n", "\n",
"checkpointer = MemorySaver()\n", "checkpointer = InMemorySaver()\n",
"# NOTE: we need to pass our store to `create_react_agent` to make sure our graph is aware of it\n", "# NOTE: we need to pass our store to `create_react_agent` to make sure our graph is aware of it\n",
"graph = create_react_agent(model, tools, checkpointer=checkpointer, store=doc_store)" "graph = create_react_agent(model, tools, checkpointer=checkpointer, store=doc_store)"
] ]
+3 -3
View File
@@ -88,7 +88,7 @@
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"name": "stdin", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"ANTHROPIC_API_KEY: ········\n" "ANTHROPIC_API_KEY: ········\n"
@@ -237,9 +237,9 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = builder.compile(checkpointer=memory)\n", "graph = builder.compile(checkpointer=memory)\n",
"# If you're using LangGraph Cloud or LangGraph Studio, you don't need to pass the checkpointer when compiling the graph, since it's done automatically." "# If you're using LangGraph Cloud or LangGraph Studio, you don't need to pass the checkpointer when compiling the graph, since it's done automatically."
] ]
+1 -1
View File
@@ -70,7 +70,7 @@
"source": [ "source": [
"from typing import Optional, Annotated\n", "from typing import Optional, Annotated\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START, END\n", "from langgraph.graph import StateGraph, START, END\n",
"\n", "\n",
"\n", "\n",
+1 -1
View File
@@ -104,7 +104,7 @@
"source": [ "source": [
"from typing import Optional, Annotated\n", "from typing import Optional, Annotated\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START, END\n", "from langgraph.graph import StateGraph, START, END\n",
"\n", "\n",
"\n", "\n",
@@ -134,10 +134,10 @@
"source": [ "source": [
"from typing import Literal\n", "from typing import Literal\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"class RouterState(MessagesState):\n", "class RouterState(MessagesState):\n",
@@ -739,10 +739,10 @@
"source": [ "source": [
"from typing import Literal\n", "from typing import Literal\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"class RouterState(MessagesState):\n", "class RouterState(MessagesState):\n",
@@ -794,9 +794,9 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"class GrandfatherState(MessagesState):\n", "class GrandfatherState(MessagesState):\n",
@@ -823,7 +823,7 @@
" \"router_node\", route_after_prediction, [\"graph\", END]\n", " \"router_node\", route_after_prediction, [\"graph\", END]\n",
")\n", ")\n",
"grandparent_graph.add_edge(\"graph\", END)\n", "grandparent_graph.add_edge(\"graph\", END)\n",
"grandparent_graph = grandparent_graph.compile(checkpointer=MemorySaver())" "grandparent_graph = grandparent_graph.compile(checkpointer=InMemorySaver())"
] ]
}, },
{ {
@@ -256,7 +256,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START\n", "from langgraph.graph import StateGraph, START\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from typing import Annotated\n", "from typing import Annotated\n",
@@ -267,7 +267,7 @@
" messages: Annotated[list, add_messages]\n", " messages: Annotated[list, add_messages]\n",
"\n", "\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"workflow = StateGraph(State)\n", "workflow = StateGraph(State)\n",
"workflow.add_node(\"info\", info_chain)\n", "workflow.add_node(\"info\", info_chain)\n",
"workflow.add_node(\"prompt\", prompt_gen_chain)\n", "workflow.add_node(\"prompt\", prompt_gen_chain)\n",
@@ -1119,7 +1119,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import END, StateGraph, START\n", "from langgraph.graph import END, StateGraph, START\n",
"from langgraph.prebuilt import tools_condition\n", "from langgraph.prebuilt import tools_condition\n",
"\n", "\n",
@@ -1139,7 +1139,7 @@
"\n", "\n",
"# The checkpointer lets the graph persist its state\n", "# The checkpointer lets the graph persist its state\n",
"# this is a complete memory for the entire graph.\n", "# this is a complete memory for the entire graph.\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"part_1_graph = builder.compile(checkpointer=memory)" "part_1_graph = builder.compile(checkpointer=memory)"
] ]
}, },
@@ -1938,7 +1938,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph\n", "from langgraph.graph import StateGraph\n",
"from langgraph.prebuilt import tools_condition\n", "from langgraph.prebuilt import tools_condition\n",
"\n", "\n",
@@ -1962,7 +1962,7 @@
")\n", ")\n",
"builder.add_edge(\"tools\", \"assistant\")\n", "builder.add_edge(\"tools\", \"assistant\")\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"part_2_graph = builder.compile(\n", "part_2_graph = builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" # NEW: The graph will always halt before executing the \"tools\" node.\n", " # NEW: The graph will always halt before executing the \"tools\" node.\n",
@@ -2524,7 +2524,7 @@
"source": [ "source": [
"from typing import Literal\n", "from typing import Literal\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph\n", "from langgraph.graph import StateGraph\n",
"from langgraph.prebuilt import tools_condition\n", "from langgraph.prebuilt import tools_condition\n",
"\n", "\n",
@@ -2568,7 +2568,7 @@
"builder.add_edge(\"safe_tools\", \"assistant\")\n", "builder.add_edge(\"safe_tools\", \"assistant\")\n",
"builder.add_edge(\"sensitive_tools\", \"assistant\")\n", "builder.add_edge(\"sensitive_tools\", \"assistant\")\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"part_3_graph = builder.compile(\n", "part_3_graph = builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" # NEW: The graph will always halt before executing the \"tools\" node.\n", " # NEW: The graph will always halt before executing the \"tools\" node.\n",
@@ -3466,7 +3466,7 @@
"source": [ "source": [
"from typing import Literal\n", "from typing import Literal\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph\n", "from langgraph.graph import StateGraph\n",
"from langgraph.prebuilt import tools_condition\n", "from langgraph.prebuilt import tools_condition\n",
"\n", "\n",
@@ -3830,7 +3830,7 @@
"builder.add_conditional_edges(\"fetch_user_info\", route_to_workflow)\n", "builder.add_conditional_edges(\"fetch_user_info\", route_to_workflow)\n",
"\n", "\n",
"# Compile graph\n", "# Compile graph\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"part_4_graph = builder.compile(\n", "part_4_graph = builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" # Let the user approve or deny the use of sensitive tools\n", " # Let the user approve or deny the use of sensitive tools\n",
+16 -16
View File
@@ -793,7 +793,7 @@
"\n", "\n",
"We will see later that **checkpointing** is _much_ more powerful than simple chat memory - it lets you save and resume complex state at any time for error recovery, human-in-the-loop workflows, time travel interactions, and more. But before we get too ahead of ourselves, let's add checkpointing to enable multi-turn conversations.\n", "We will see later that **checkpointing** is _much_ more powerful than simple chat memory - it lets you save and resume complex state at any time for error recovery, human-in-the-loop workflows, time travel interactions, and more. But before we get too ahead of ourselves, let's add checkpointing to enable multi-turn conversations.\n",
"\n", "\n",
"To get started, create a `MemorySaver` checkpointer." "To get started, create a `InMemorySaver` checkpointer."
] ]
}, },
{ {
@@ -803,9 +803,9 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"memory = MemorySaver()" "memory = InMemorySaver()"
] ]
}, },
{ {
@@ -1135,7 +1135,7 @@
"from langchain_core.messages import BaseMessage\n", "from langchain_core.messages import BaseMessage\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph\n", "from langgraph.graph import StateGraph\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode\n", "from langgraph.prebuilt import ToolNode\n",
@@ -1203,12 +1203,12 @@
"from langchain_community.tools.tavily_search import TavilySearchResults\n", "from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START\n", "from langgraph.graph import StateGraph, START\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode, tools_condition\n", "from langgraph.prebuilt import ToolNode, tools_condition\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"\n", "\n",
"\n", "\n",
"class State(TypedDict):\n", "class State(TypedDict):\n",
@@ -1456,7 +1456,7 @@
"from langchain_core.messages import BaseMessage\n", "from langchain_core.messages import BaseMessage\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph\n", "from langgraph.graph import StateGraph\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode, tools_condition\n", "from langgraph.prebuilt import ToolNode, tools_condition\n",
@@ -1491,7 +1491,7 @@
"graph_builder.add_edge(\"tools\", \"chatbot\")\n", "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
"graph_builder.set_entry_point(\"chatbot\")\n", "graph_builder.set_entry_point(\"chatbot\")\n",
"\n", "\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = graph_builder.compile(\n", "graph = graph_builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" # This is new!\n", " # This is new!\n",
@@ -1531,7 +1531,7 @@
"from langchain_community.tools.tavily_search import TavilySearchResults\n", "from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START\n", "from langgraph.graph import StateGraph, START\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode, tools_condition\n", "from langgraph.prebuilt import ToolNode, tools_condition\n",
@@ -1565,7 +1565,7 @@
")\n", ")\n",
"graph_builder.add_edge(\"tools\", \"chatbot\")\n", "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
"graph_builder.add_edge(START, \"chatbot\")\n", "graph_builder.add_edge(START, \"chatbot\")\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = graph_builder.compile(\n", "graph = graph_builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" # This is new!\n", " # This is new!\n",
@@ -2066,7 +2066,7 @@
"from langchain_community.tools.tavily_search import TavilySearchResults\n", "from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START\n", "from langgraph.graph import StateGraph, START\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode, tools_condition\n", "from langgraph.prebuilt import ToolNode, tools_condition\n",
@@ -2267,7 +2267,7 @@
"graph_builder.add_edge(\"tools\", \"chatbot\")\n", "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
"graph_builder.add_edge(\"human\", \"chatbot\")\n", "graph_builder.add_edge(\"human\", \"chatbot\")\n",
"graph_builder.add_edge(START, \"chatbot\")\n", "graph_builder.add_edge(START, \"chatbot\")\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = graph_builder.compile(\n", "graph = graph_builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" # We interrupt before 'human' here instead.\n", " # We interrupt before 'human' here instead.\n",
@@ -2542,7 +2542,7 @@
"from pydantic import BaseModel\n", "from pydantic import BaseModel\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph\n", "from langgraph.graph import StateGraph\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode, tools_condition\n", "from langgraph.prebuilt import ToolNode, tools_condition\n",
@@ -2629,7 +2629,7 @@
"graph_builder.add_edge(\"tools\", \"chatbot\")\n", "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
"graph_builder.add_edge(\"human\", \"chatbot\")\n", "graph_builder.add_edge(\"human\", \"chatbot\")\n",
"graph_builder.set_entry_point(\"chatbot\")\n", "graph_builder.set_entry_point(\"chatbot\")\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = graph_builder.compile(\n", "graph = graph_builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" interrupt_before=[\"human\"],\n", " interrupt_before=[\"human\"],\n",
@@ -2674,7 +2674,7 @@
"from pydantic import BaseModel\n", "from pydantic import BaseModel\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import StateGraph, START\n", "from langgraph.graph import StateGraph, START\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.prebuilt import ToolNode, tools_condition\n", "from langgraph.prebuilt import ToolNode, tools_condition\n",
@@ -2761,7 +2761,7 @@
"graph_builder.add_edge(\"tools\", \"chatbot\")\n", "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
"graph_builder.add_edge(\"human\", \"chatbot\")\n", "graph_builder.add_edge(\"human\", \"chatbot\")\n",
"graph_builder.add_edge(START, \"chatbot\")\n", "graph_builder.add_edge(START, \"chatbot\")\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = graph_builder.compile(\n", "graph = graph_builder.compile(\n",
" checkpointer=memory,\n", " checkpointer=memory,\n",
" interrupt_before=[\"human\"],\n", " interrupt_before=[\"human\"],\n",
@@ -322,7 +322,7 @@
"from typing import Annotated, List, Sequence\n", "from typing import Annotated, List, Sequence\n",
"from langgraph.graph import END, StateGraph, START\n", "from langgraph.graph import END, StateGraph, START\n",
"from langgraph.graph.message import add_messages\n", "from langgraph.graph.message import add_messages\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from typing_extensions import TypedDict\n", "from typing_extensions import TypedDict\n",
"\n", "\n",
"\n", "\n",
@@ -361,7 +361,7 @@
"\n", "\n",
"builder.add_conditional_edges(\"generate\", should_continue)\n", "builder.add_conditional_edges(\"generate\", should_continue)\n",
"builder.add_edge(\"reflect\", \"generate\")\n", "builder.add_edge(\"reflect\", \"generate\")\n",
"memory = MemorySaver()\n", "memory = InMemorySaver()\n",
"graph = builder.compile(checkpointer=memory)" "graph = builder.compile(checkpointer=memory)"
] ]
}, },
+2 -2
View File
@@ -1514,7 +1514,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"\n", "\n",
"builder_of_storm = StateGraph(ResearchState)\n", "builder_of_storm = StateGraph(ResearchState)\n",
"\n", "\n",
@@ -1534,7 +1534,7 @@
"\n", "\n",
"builder_of_storm.add_edge(START, nodes[0][0])\n", "builder_of_storm.add_edge(START, nodes[0][0])\n",
"builder_of_storm.add_edge(nodes[-1][0], END)\n", "builder_of_storm.add_edge(nodes[-1][0], END)\n",
"storm = builder_of_storm.compile(checkpointer=MemorySaver())" "storm = builder_of_storm.compile(checkpointer=InMemorySaver())"
] ]
}, },
{ {
+4 -4
View File
@@ -1029,7 +1029,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import END, StateGraph, START\n", "from langgraph.graph import END, StateGraph, START\n",
"\n", "\n",
"builder = StateGraph(State)\n", "builder = StateGraph(State)\n",
@@ -1053,7 +1053,7 @@
"builder.add_conditional_edges(\"evaluate\", control_edge, {END: END, \"solve\": \"solve\"})\n", "builder.add_conditional_edges(\"evaluate\", control_edge, {END: END, \"solve\": \"solve\"})\n",
"\n", "\n",
"\n", "\n",
"checkpointer = MemorySaver()\n", "checkpointer = InMemorySaver()\n",
"graph = builder.compile(checkpointer=checkpointer)" "graph = builder.compile(checkpointer=checkpointer)"
] ]
}, },
@@ -1327,7 +1327,7 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# This is all the same as before\n", "# This is all the same as before\n",
"from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.checkpoint.memory import InMemorySaver\n",
"from langgraph.graph import END, StateGraph, START\n", "from langgraph.graph import END, StateGraph, START\n",
"\n", "\n",
"builder = StateGraph(State)\n", "builder = StateGraph(State)\n",
@@ -1353,7 +1353,7 @@
"\n", "\n",
"\n", "\n",
"builder.add_conditional_edges(\"evaluate\", control_edge, {END: END, \"solve\": \"solve\"})\n", "builder.add_conditional_edges(\"evaluate\", control_edge, {END: END, \"solve\": \"solve\"})\n",
"checkpointer = MemorySaver()" "checkpointer = InMemorySaver()"
] ]
}, },
{ {
@@ -154,7 +154,7 @@
"id": "2dff2209-44c7-4e2c-b607-ba6675f9e45f", "id": "2dff2209-44c7-4e2c-b607-ba6675f9e45f",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": ["from langgraph.checkpoint.memory import MemorySaver\nfrom langgraph.graph import END, StateGraph, START\n\nbuilder = StateGraph(GraphState)\n\n# Define the nodes\nbuilder.add_node(\"generate\", generate) # generation solution\nbuilder.add_node(\"check_code\", code_check) # check code\n\n# Build graph\nbuilder.add_edge(START, \"generate\")\nbuilder.add_edge(\"generate\", \"check_code\")\nbuilder.add_conditional_edges(\n \"check_code\",\n decide_to_finish,\n {\n \"end\": END,\n \"generate\": \"generate\",\n },\n)\n\nmemory = MemorySaver()\ngraph = builder.compile(checkpointer=memory)"] "source": ["from langgraph.checkpoint.memory import InMemorySaver\nfrom langgraph.graph import END, StateGraph, START\n\nbuilder = StateGraph(GraphState)\n\n# Define the nodes\nbuilder.add_node(\"generate\", generate) # generation solution\nbuilder.add_node(\"check_code\", code_check) # check code\n\n# Build graph\nbuilder.add_edge(START, \"generate\")\nbuilder.add_edge(\"generate\", \"check_code\")\nbuilder.add_conditional_edges(\n \"check_code\",\n decide_to_finish,\n {\n \"end\": END,\n \"generate\": \"generate\",\n },\n)\n\nmemory = InMemorySaver()\ngraph = builder.compile(checkpointer=memory)"]
}, },
{ {
"cell_type": "code", "cell_type": "code",
+2 -2
View File
@@ -44,12 +44,12 @@ If the checkpointer will be used with asynchronous graph execution (i.e. executi
## Usage ## Usage
```python ```python
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}} write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}}
read_config = {"configurable": {"thread_id": "1"}} read_config = {"configurable": {"thread_id": "1"}}
checkpointer = MemorySaver() checkpointer = InMemorySaver()
checkpoint = { checkpoint = {
"v": 1, "v": 1,
"ts": "2024-07-31T20:14:19.804150+00:00", "ts": "2024-07-31T20:14:19.804150+00:00",
@@ -21,7 +21,7 @@ from langgraph.checkpoint.base import (
from langgraph.checkpoint.serde.types import TASKS, ChannelProtocol from langgraph.checkpoint.serde.types import TASKS, ChannelProtocol
class MemorySaver( class InMemorySaver(
BaseCheckpointSaver[str], AbstractContextManager, AbstractAsyncContextManager BaseCheckpointSaver[str], AbstractContextManager, AbstractAsyncContextManager
): ):
"""An in-memory checkpoint saver. """An in-memory checkpoint saver.
@@ -29,7 +29,7 @@ class MemorySaver(
This checkpoint saver stores checkpoints in memory using a defaultdict. This checkpoint saver stores checkpoints in memory using a defaultdict.
Note: Note:
Only use `MemorySaver` for debugging or testing purposes. Only use `InMemorySaver` for debugging or testing purposes.
For production use cases we recommend installing [langgraph-checkpoint-postgres](https://pypi.org/project/langgraph-checkpoint-postgres/) and using `PostgresSaver` / `AsyncPostgresSaver`. For production use cases we recommend installing [langgraph-checkpoint-postgres](https://pypi.org/project/langgraph-checkpoint-postgres/) and using `PostgresSaver` / `AsyncPostgresSaver`.
Args: Args:
@@ -39,7 +39,7 @@ class MemorySaver(
import asyncio import asyncio
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph from langgraph.graph import StateGraph
builder = StateGraph(int) builder = StateGraph(int)
@@ -47,7 +47,7 @@ class MemorySaver(
builder.set_entry_point("add_one") builder.set_entry_point("add_one")
builder.set_finish_point("add_one") builder.set_finish_point("add_one")
memory = MemorySaver() memory = InMemorySaver()
graph = builder.compile(checkpointer=memory) graph = builder.compile(checkpointer=memory)
coro = graph.ainvoke(1, {"configurable": {"thread_id": "thread-1"}}) coro = graph.ainvoke(1, {"configurable": {"thread_id": "thread-1"}})
asyncio.run(coro) # Output: 2 asyncio.run(coro) # Output: 2
@@ -73,7 +73,7 @@ class MemorySaver(
self.storage = defaultdict(lambda: defaultdict(dict)) self.storage = defaultdict(lambda: defaultdict(dict))
self.writes = defaultdict(dict) self.writes = defaultdict(dict)
def __enter__(self) -> "MemorySaver": def __enter__(self) -> "InMemorySaver":
return self return self
def __exit__( def __exit__(
@@ -84,7 +84,7 @@ class MemorySaver(
) -> Optional[bool]: ) -> Optional[bool]:
return return
async def __aenter__(self) -> "MemorySaver": async def __aenter__(self) -> "InMemorySaver":
return self return self
async def __aexit__( async def __aexit__(
@@ -135,15 +135,17 @@ class MemorySaver(
pending_writes=[ pending_writes=[
(id, c, self.serde.loads_typed(v)) for id, c, v in writes (id, c, self.serde.loads_typed(v)) for id, c, v in writes
], ],
parent_config={ parent_config=(
"configurable": { {
"thread_id": thread_id, "configurable": {
"checkpoint_ns": checkpoint_ns, "thread_id": thread_id,
"checkpoint_id": parent_checkpoint_id, "checkpoint_ns": checkpoint_ns,
"checkpoint_id": parent_checkpoint_id,
}
} }
} if parent_checkpoint_id
if parent_checkpoint_id else None
else None, ),
) )
else: else:
if checkpoints := self.storage[thread_id][checkpoint_ns]: if checkpoints := self.storage[thread_id][checkpoint_ns]:
@@ -176,15 +178,17 @@ class MemorySaver(
pending_writes=[ pending_writes=[
(id, c, self.serde.loads_typed(v)) for id, c, v in writes (id, c, self.serde.loads_typed(v)) for id, c, v in writes
], ],
parent_config={ parent_config=(
"configurable": { {
"thread_id": thread_id, "configurable": {
"checkpoint_ns": checkpoint_ns, "thread_id": thread_id,
"checkpoint_id": parent_checkpoint_id, "checkpoint_ns": checkpoint_ns,
"checkpoint_id": parent_checkpoint_id,
}
} }
} if parent_checkpoint_id
if parent_checkpoint_id else None
else None, ),
) )
def list( def list(
@@ -285,15 +289,17 @@ class MemorySaver(
"pending_sends": [self.serde.loads_typed(s) for s in sends], "pending_sends": [self.serde.loads_typed(s) for s in sends],
}, },
metadata=metadata, metadata=metadata,
parent_config={ parent_config=(
"configurable": { {
"thread_id": thread_id, "configurable": {
"checkpoint_ns": checkpoint_ns, "thread_id": thread_id,
"checkpoint_id": parent_checkpoint_id, "checkpoint_ns": checkpoint_ns,
"checkpoint_id": parent_checkpoint_id,
}
} }
} if parent_checkpoint_id
if parent_checkpoint_id else None
else None, ),
pending_writes=[ pending_writes=[
(id, c, self.serde.loads_typed(v)) for id, c, v in writes (id, c, self.serde.loads_typed(v)) for id, c, v in writes
], ],
@@ -474,3 +480,6 @@ class MemorySaver(
next_v = current_v + 1 next_v = current_v + 1
next_h = random.random() next_h = random.random()
return f"{next_v:032}.{next_h:016}" return f"{next_v:032}.{next_h:016}"
MemorySaver = InMemorySaver # Kept for backwards compatibility
+2 -2
View File
@@ -9,13 +9,13 @@ from langgraph.checkpoint.base import (
create_checkpoint, create_checkpoint,
empty_checkpoint, empty_checkpoint,
) )
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
class TestMemorySaver: class TestMemorySaver:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def setup(self) -> None: def setup(self) -> None:
self.memory_saver = MemorySaver() self.memory_saver = InMemorySaver()
# objects for test setup # objects for test setup
self.config_1: RunnableConfig = { self.config_1: RunnableConfig = {
+3 -3
View File
@@ -60,7 +60,7 @@ from typing import Annotated, Literal, TypedDict
from langchain_core.messages import HumanMessage from langchain_core.messages import HumanMessage
from langchain_anthropic import ChatAnthropic from langchain_anthropic import ChatAnthropic
from langchain_core.tools import tool from langchain_core.tools import tool
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph, MessagesState from langgraph.graph import END, START, StateGraph, MessagesState
from langgraph.prebuilt import ToolNode from langgraph.prebuilt import ToolNode
@@ -125,7 +125,7 @@ workflow.add_conditional_edges(
workflow.add_edge("tools", 'agent') workflow.add_edge("tools", 'agent')
# Initialize memory to persist state between graph runs # Initialize memory to persist state between graph runs
checkpointer = MemorySaver() checkpointer = InMemorySaver()
# Finally, we compile it! # Finally, we compile it!
# This compiles it into a LangChain Runnable, # This compiles it into a LangChain Runnable,
@@ -201,7 +201,7 @@ final_state["messages"][-1].content
<summary>Compile the graph.</summary> <summary>Compile the graph.</summary>
- When we compile the graph, we turn it into a LangChain [Runnable](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface), which automatically enables calling `.invoke()`, `.stream()` and `.batch()` with your inputs - When we compile the graph, we turn it into a LangChain [Runnable](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface), which automatically enables calling `.invoke()`, `.stream()` and `.batch()` with your inputs
- We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory, human-in-the-loop workflows, time travel and more. In our case we use `MemorySaver` - a simple in-memory checkpointer - We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory, human-in-the-loop workflows, time travel and more. In our case we use `InMemorySaver` - a simple in-memory checkpointer
</details> </details>
6. <details> 6. <details>
+15 -15
View File
@@ -8,7 +8,7 @@ from uvloop import new_event_loop
from bench.fanout_to_subgraph import fanout_to_subgraph, fanout_to_subgraph_sync from bench.fanout_to_subgraph import fanout_to_subgraph, fanout_to_subgraph_sync
from bench.react_agent import react_agent from bench.react_agent import react_agent
from bench.wide_state import wide_state from bench.wide_state import wide_state
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from langgraph.pregel import Pregel from langgraph.pregel import Pregel
@@ -55,8 +55,8 @@ benchmarks = (
), ),
( (
"fanout_to_subgraph_10x_checkpoint", "fanout_to_subgraph_10x_checkpoint",
fanout_to_subgraph().compile(checkpointer=MemorySaver()), fanout_to_subgraph().compile(checkpointer=InMemorySaver()),
fanout_to_subgraph_sync().compile(checkpointer=MemorySaver()), fanout_to_subgraph_sync().compile(checkpointer=InMemorySaver()),
{ {
"subjects": [ "subjects": [
random.choices("abcdefghijklmnopqrstuvwxyz", k=1000) for _ in range(10) random.choices("abcdefghijklmnopqrstuvwxyz", k=1000) for _ in range(10)
@@ -75,8 +75,8 @@ benchmarks = (
), ),
( (
"fanout_to_subgraph_100x_checkpoint", "fanout_to_subgraph_100x_checkpoint",
fanout_to_subgraph().compile(checkpointer=MemorySaver()), fanout_to_subgraph().compile(checkpointer=InMemorySaver()),
fanout_to_subgraph_sync().compile(checkpointer=MemorySaver()), fanout_to_subgraph_sync().compile(checkpointer=InMemorySaver()),
{ {
"subjects": [ "subjects": [
random.choices("abcdefghijklmnopqrstuvwxyz", k=1000) for _ in range(100) random.choices("abcdefghijklmnopqrstuvwxyz", k=1000) for _ in range(100)
@@ -91,8 +91,8 @@ benchmarks = (
), ),
( (
"react_agent_10x_checkpoint", "react_agent_10x_checkpoint",
react_agent(10, checkpointer=MemorySaver()), react_agent(10, checkpointer=InMemorySaver()),
react_agent(10, checkpointer=MemorySaver()), react_agent(10, checkpointer=InMemorySaver()),
{"messages": [HumanMessage("hi?")]}, {"messages": [HumanMessage("hi?")]},
), ),
( (
@@ -103,8 +103,8 @@ benchmarks = (
), ),
( (
"react_agent_100x_checkpoint", "react_agent_100x_checkpoint",
react_agent(100, checkpointer=MemorySaver()), react_agent(100, checkpointer=InMemorySaver()),
react_agent(100, checkpointer=MemorySaver()), react_agent(100, checkpointer=InMemorySaver()),
{"messages": [HumanMessage("hi?")]}, {"messages": [HumanMessage("hi?")]},
), ),
( (
@@ -125,8 +125,8 @@ benchmarks = (
), ),
( (
"wide_state_25x300_checkpoint", "wide_state_25x300_checkpoint",
wide_state(300).compile(checkpointer=MemorySaver()), wide_state(300).compile(checkpointer=InMemorySaver()),
wide_state(300).compile(checkpointer=MemorySaver()), wide_state(300).compile(checkpointer=InMemorySaver()),
{ {
"messages": [ "messages": [
{ {
@@ -157,8 +157,8 @@ benchmarks = (
), ),
( (
"wide_state_15x600_checkpoint", "wide_state_15x600_checkpoint",
wide_state(600).compile(checkpointer=MemorySaver()), wide_state(600).compile(checkpointer=InMemorySaver()),
wide_state(600).compile(checkpointer=MemorySaver()), wide_state(600).compile(checkpointer=InMemorySaver()),
{ {
"messages": [ "messages": [
{ {
@@ -189,8 +189,8 @@ benchmarks = (
), ),
( (
"wide_state_9x1200_checkpoint", "wide_state_9x1200_checkpoint",
wide_state(1200).compile(checkpointer=MemorySaver()), wide_state(1200).compile(checkpointer=InMemorySaver()),
wide_state(1200).compile(checkpointer=MemorySaver()), wide_state(1200).compile(checkpointer=InMemorySaver()),
{ {
"messages": [ "messages": [
{ {
+2 -2
View File
@@ -107,9 +107,9 @@ if __name__ == "__main__":
import uvloop import uvloop
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
graph = fanout_to_subgraph().compile(checkpointer=MemorySaver()) graph = fanout_to_subgraph().compile(checkpointer=InMemorySaver())
input = { input = {
"subjects": [ "subjects": [
random.choices("abcdefghijklmnopqrstuvwxyz", k=1000) for _ in range(1000) random.choices("abcdefghijklmnopqrstuvwxyz", k=1000) for _ in range(1000)
+2 -2
View File
@@ -68,9 +68,9 @@ if __name__ == "__main__":
import uvloop import uvloop
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
graph = react_agent(100, checkpointer=MemorySaver()) graph = react_agent(100, checkpointer=InMemorySaver())
input = {"messages": [HumanMessage("hi?")]} input = {"messages": [HumanMessage("hi?")]}
config = {"configurable": {"thread_id": "1"}, "recursion_limit": 20000000000} config = {"configurable": {"thread_id": "1"}, "recursion_limit": 20000000000}
+2 -2
View File
@@ -116,9 +116,9 @@ if __name__ == "__main__":
import uvloop import uvloop
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
graph = wide_state(1000).compile(checkpointer=MemorySaver()) graph = wide_state(1000).compile(checkpointer=InMemorySaver())
input = { input = {
"messages": [ "messages": [
{ {
+1 -1
View File
@@ -90,7 +90,7 @@ class StateGraph(Graph):
Examples: Examples:
>>> from langchain_core.runnables import RunnableConfig >>> from langchain_core.runnables import RunnableConfig
>>> from typing_extensions import Annotated, TypedDict >>> from typing_extensions import Annotated, TypedDict
>>> from langgraph.checkpoint.memory import MemorySaver >>> from langgraph.checkpoint.memory import InMemorySaver
>>> from langgraph.graph import StateGraph >>> from langgraph.graph import StateGraph
>>> >>>
>>> def reducer(a: list, b: int | None) -> list: >>> def reducer(a: list, b: int | None) -> list:
@@ -372,8 +372,8 @@ def create_react_agent(
Add thread-level "chat memory" to the graph: Add thread-level "chat memory" to the graph:
```pycon ```pycon
>>> from langgraph.checkpoint.memory import MemorySaver >>> from langgraph.checkpoint.memory import InMemorySaver
>>> graph = create_react_agent(model, tools, checkpointer=MemorySaver()) >>> graph = create_react_agent(model, tools, checkpointer=InMemorySaver())
>>> config = {"configurable": {"thread_id": "thread-1"}} >>> config = {"configurable": {"thread_id": "thread-1"}}
>>> def print_stream(graph, inputs, config): >>> def print_stream(graph, inputs, config):
... for s in graph.stream(inputs, config, stream_mode="values"): ... for s in graph.stream(inputs, config, stream_mode="values"):
@@ -408,7 +408,7 @@ def create_react_agent(
```pycon ```pycon
>>> graph = create_react_agent( >>> graph = create_react_agent(
... model, tools, interrupt_before=["tools"], checkpointer=MemorySaver() ... model, tools, interrupt_before=["tools"], checkpointer=InMemorySaver()
>>> ) >>> )
>>> config = {"configurable": {"thread_id": "thread-1"}} >>> config = {"configurable": {"thread_id": "thread-1"}}
@@ -442,10 +442,10 @@ def create_react_agent(
... system_msg = f"User memories: {', '.join(memories)}" ... system_msg = f"User memories: {', '.join(memories)}"
... return [{"role": "system", "content": system_msg)] + state["messages"] ... return [{"role": "system", "content": system_msg)] + state["messages"]
>>> from langgraph.checkpoint.memory import MemorySaver >>> from langgraph.checkpoint.memory import InMemorySaver
>>> from langgraph.store.memory import InMemoryStore >>> from langgraph.store.memory import InMemoryStore
>>> store = InMemoryStore() >>> store = InMemoryStore()
>>> graph = create_react_agent(model, [save_memory], state_modifier=prepare_model_inputs, store=store, checkpointer=MemorySaver()) >>> graph = create_react_agent(model, [save_memory], state_modifier=prepare_model_inputs, store=store, checkpointer=InMemorySaver())
>>> config = {"configurable": {"thread_id": "thread-1", "user_id": "1"}} >>> config = {"configurable": {"thread_id": "thread-1", "user_id": "1"}}
>>> inputs = {"messages": [("user", "Hey I'm Will, how's it going?")]} >>> inputs = {"messages": [("user", "Hey I'm Will, how's it going?")]}
+4 -4
View File
@@ -12,7 +12,7 @@ from langgraph.checkpoint.base import (
SerializerProtocol, SerializerProtocol,
copy_checkpoint, copy_checkpoint,
) )
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
class NoopSerializer(SerializerProtocol): class NoopSerializer(SerializerProtocol):
@@ -23,7 +23,7 @@ class NoopSerializer(SerializerProtocol):
return "type", obj return "type", obj
class MemorySaverAssertImmutable(MemorySaver): class MemorySaverAssertImmutable(InMemorySaver):
storage_for_copies: defaultdict[str, dict[str, dict[str, Checkpoint]]] storage_for_copies: defaultdict[str, dict[str, dict[str, Checkpoint]]]
def __init__( def __init__(
@@ -64,7 +64,7 @@ class MemorySaverAssertImmutable(MemorySaver):
return super().put(config, checkpoint, metadata, new_versions) return super().put(config, checkpoint, metadata, new_versions)
class MemorySaverAssertCheckpointMetadata(MemorySaver): class MemorySaverAssertCheckpointMetadata(InMemorySaver):
"""This custom checkpointer is for verifying that a run's configurable """This custom checkpointer is for verifying that a run's configurable
fields are merged with the previous checkpoint config for each step in fields are merged with the previous checkpoint config for each step in
the run. This is the desired behavior. Because the checkpointer's (a)put() the run. This is the desired behavior. Because the checkpointer's (a)put()
@@ -119,7 +119,7 @@ class MemorySaverAssertCheckpointMetadata(MemorySaver):
) )
class MemorySaverNoPending(MemorySaver): class MemorySaverNoPending(InMemorySaver):
def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]: def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
result = super().get_tuple(config) result = super().get_tuple(config)
if result: if result:
+7 -7
View File
@@ -53,7 +53,7 @@ from langgraph.checkpoint.base import (
CheckpointMetadata, CheckpointMetadata,
CheckpointTuple, CheckpointTuple,
) )
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from langgraph.constants import ERROR, PULL, PUSH from langgraph.constants import ERROR, PULL, PUSH
from langgraph.errors import InvalidUpdateError, MultipleSubgraphsError, NodeInterrupt from langgraph.errors import InvalidUpdateError, MultipleSubgraphsError, NodeInterrupt
from langgraph.graph import END, Graph from langgraph.graph import END, Graph
@@ -268,11 +268,11 @@ def test_graph_validation() -> None:
def test_checkpoint_errors() -> None: def test_checkpoint_errors() -> None:
class FaultyGetCheckpointer(MemorySaver): class FaultyGetCheckpointer(InMemorySaver):
def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]: def get_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
raise ValueError("Faulty get_tuple") raise ValueError("Faulty get_tuple")
class FaultyPutCheckpointer(MemorySaver): class FaultyPutCheckpointer(InMemorySaver):
def put( def put(
self, self,
config: RunnableConfig, config: RunnableConfig,
@@ -282,13 +282,13 @@ def test_checkpoint_errors() -> None:
) -> RunnableConfig: ) -> RunnableConfig:
raise ValueError("Faulty put") raise ValueError("Faulty put")
class FaultyPutWritesCheckpointer(MemorySaver): class FaultyPutWritesCheckpointer(InMemorySaver):
def put_writes( def put_writes(
self, config: RunnableConfig, writes: List[Tuple[str, Any]], task_id: str self, config: RunnableConfig, writes: List[Tuple[str, Any]], task_id: str
) -> RunnableConfig: ) -> RunnableConfig:
raise ValueError("Faulty put_writes") raise ValueError("Faulty put_writes")
class FaultyVersionCheckpointer(MemorySaver): class FaultyVersionCheckpointer(InMemorySaver):
def get_next_version(self, current: Optional[int], channel: BaseChannel) -> int: def get_next_version(self, current: Optional[int], channel: BaseChannel) -> int:
raise ValueError("Faulty get_next_version") raise ValueError("Faulty get_next_version")
@@ -11250,7 +11250,7 @@ def test_xray_lance(snapshot: SnapshotAssertion):
interview_builder.add_conditional_edges("answer_question", route_messages) interview_builder.add_conditional_edges("answer_question", route_messages)
# Set up memory # Set up memory
memory = MemorySaver() memory = InMemorySaver()
# Interview # Interview
interview_graph = interview_builder.compile(checkpointer=memory).with_config( interview_graph = interview_builder.compile(checkpointer=memory).with_config(
@@ -11478,7 +11478,7 @@ def test_subgraph_retries():
parent.add_edge("parent_node", "child_graph") parent.add_edge("parent_node", "child_graph")
parent.set_entry_point("parent_node") parent.set_entry_point("parent_node")
checkpointer = MemorySaver() checkpointer = InMemorySaver()
app = parent.compile(checkpointer=checkpointer) app = parent.compile(checkpointer=checkpointer)
with pytest.raises(RandomError): with pytest.raises(RandomError):
app.invoke({"count": 0}, {"configurable": {"thread_id": "foo"}}) app.invoke({"count": 0}, {"configurable": {"thread_id": "foo"}})
+5 -5
View File
@@ -49,7 +49,7 @@ from langgraph.checkpoint.base import (
CheckpointMetadata, CheckpointMetadata,
CheckpointTuple, CheckpointTuple,
) )
from langgraph.checkpoint.memory import MemorySaver from langgraph.checkpoint.memory import InMemorySaver
from langgraph.constants import ERROR, PULL, PUSH from langgraph.constants import ERROR, PULL, PUSH
from langgraph.errors import InvalidUpdateError, MultipleSubgraphsError, NodeInterrupt from langgraph.errors import InvalidUpdateError, MultipleSubgraphsError, NodeInterrupt
from langgraph.graph import END, Graph, StateGraph from langgraph.graph import END, Graph, StateGraph
@@ -89,11 +89,11 @@ pytestmark = pytest.mark.anyio
async def test_checkpoint_errors() -> None: async def test_checkpoint_errors() -> None:
class FaultyGetCheckpointer(MemorySaver): class FaultyGetCheckpointer(InMemorySaver):
async def aget_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]: async def aget_tuple(self, config: RunnableConfig) -> Optional[CheckpointTuple]:
raise ValueError("Faulty get_tuple") raise ValueError("Faulty get_tuple")
class FaultyPutCheckpointer(MemorySaver): class FaultyPutCheckpointer(InMemorySaver):
async def aput( async def aput(
self, self,
config: RunnableConfig, config: RunnableConfig,
@@ -103,13 +103,13 @@ async def test_checkpoint_errors() -> None:
) -> RunnableConfig: ) -> RunnableConfig:
raise ValueError("Faulty put") raise ValueError("Faulty put")
class FaultyPutWritesCheckpointer(MemorySaver): class FaultyPutWritesCheckpointer(InMemorySaver):
async def aput_writes( async def aput_writes(
self, config: RunnableConfig, writes: List[Tuple[str, Any]], task_id: str self, config: RunnableConfig, writes: List[Tuple[str, Any]], task_id: str
) -> RunnableConfig: ) -> RunnableConfig:
raise ValueError("Faulty put_writes") raise ValueError("Faulty put_writes")
class FaultyVersionCheckpointer(MemorySaver): class FaultyVersionCheckpointer(InMemorySaver):
def get_next_version(self, current: Optional[int], channel: BaseChannel) -> int: def get_next_version(self, current: Optional[int], channel: BaseChannel) -> int:
raise ValueError("Faulty get_next_version") raise ValueError("Faulty get_next_version")