mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-09 19:27:54 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52910f3b04 |
@@ -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)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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."
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
|
|||||||
@@ -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": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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?")]}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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"}})
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user