Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 36 additions & 53 deletions langgraph/couchbase_persistence_langgraph.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Requires Couchbase Python SDK and langgraph package"
"Requires Couchbase Python SDK, LangGraph, and langchain-openai.\n",
"\n",
"Set `OPENAI_API_KEY` before running. For local Couchbase runs, this notebook also reads `CB_CONN_STR`, `CB_USER`, `CB_PASS`, `CB_BUCKET_NAME`, and `CB_SCOPE_NAME` from the environment.\n",
"\n",
"For the local example below, create bucket `test`, scope `langgraph`, and the `checkpoints` / `checkpoint_writes` collections first, or provide equivalent names through the environment variables. The default `CB_*` values shown later are for local development only.\n"
]
},
{
Expand All @@ -67,7 +71,7 @@
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install -U langgraph==0.3.22 langgraph-checkpointer-couchbase "
"%pip install -U langgraph==1.1.10 langgraph-checkpointer-couchbase langchain-openai\n"
]
},
{
Expand All @@ -88,11 +92,21 @@
"\n",
"\n",
"def _set_env(var: str):\n",
" if not os.environ.get(var):\n",
" os.environ[var] = getpass.getpass(f\"{var}: \")\n",
" if os.environ.get(var):\n",
" return os.environ[var]\n",
Comment thread
dex-the-ai marked this conversation as resolved.
" value = getpass.getpass(f\"{var}: \")\n",
" if not value:\n",
" raise RuntimeError(f\"{var} must be set before running this notebook\")\n",
" os.environ[var] = value\n",
" return value\n",
"\n",
"\n",
"_set_env(\"OPENAI_API_KEY\")"
"_set_env(\"OPENAI_API_KEY\")\n",
"CB_CONN_STR = os.environ.get(\"CB_CONN_STR\", \"couchbase://localhost\")\n",
"CB_USERNAME = os.environ.get(\"CB_USER\", \"Administrator\")\n",
"CB_PASSWORD = os.environ.get(\"CB_PASS\", \"password\")\n",
"CB_BUCKET_NAME = os.environ.get(\"CB_BUCKET_NAME\", \"test\")\n",
"CB_SCOPE_NAME = os.environ.get(\"CB_SCOPE_NAME\", \"langgraph\")\n"
Comment thread
dex-the-ai marked this conversation as resolved.
]
},
{
Expand Down Expand Up @@ -120,7 +134,7 @@
"from typing import Literal\n",
"from langchain_core.tools import tool\n",
"from langchain_openai import ChatOpenAI\n",
"from langgraph.prebuilt import create_react_agent\n",
"from langchain.agents import create_agent\n",
"\n",
"\n",
"@tool\n",
Expand All @@ -142,14 +156,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Couchbase Connection and intialization\n",
"\n",
"There are 2 ways to initialize a saver.\n",
"\n",
"1. `from_conn_info` - Provide details of the connection string, username, password. The package will handle connection itself.\n",
"2. `from_cluster` - Provide a connected Couchbase.Cluster object. \n",
"\n",
"We will be using `from_conn_info` in the sync tutorial and `from_cluster` in the async one, but any of the above can be used as per requirements\n"
"### Couchbase Connection and initialization\n\nThere are 2 ways to initialize a saver.\n\n1. `from_conn_info` - Provide details of the connection string, username, password. The package will handle connection itself.\n2. `from_cluster` - Provide a connected Couchbase.Cluster object. \n\nWe will be using `from_conn_info` in the sync tutorial and `from_cluster` in the async one, but any of the above can be used as per requirements\n"
]
},
{
Expand All @@ -163,18 +170,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Below is usage of CouchbaseSaver (for synchronous use of graph, i.e. `.invoke()`, `.stream()`). CouchbaseSaver implements four methods that are required for any checkpointer:\n",
"\n",
"- `.put` - Store a checkpoint with its configuration and metadata.\n",
"- `.put_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes).\n",
"- `.get_tuple` - Fetch a checkpoint tuple using a given configuration (`thread_id` and `checkpoint_id`).\n",
"- `.list` - List checkpoints that match a given configuration and filter criteria.\n",
"\n",
"Here we will create a Couchbase connection. We are using local setup with bucket `test`, `langgraph` scope. You may change bucket and scope if required. We will also require `checkpoints` and `checkpoint_writes` as collections inside.\n",
"\n",
"Then a [ReAct Agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/) is created with GPT Model, weather tool and Couchbase checkpointer.\n",
"\n",
"LangGraph's graph is invoked with message for GPT, storing all the state in Couchbase. We use get, get_tuple and list methods to fetch the states again"
"Below is usage of CouchbaseSaver (for synchronous use of graph, i.e. `.invoke()`, `.stream()`). CouchbaseSaver implements four methods that are required for any checkpointer:\n\n- `.put` - Store a checkpoint with its configuration and metadata.\n- `.put_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes).\n- `.get_tuple` - Fetch a checkpoint tuple using a given configuration (`thread_id` and `checkpoint_id`).\n- `.list` - List checkpoints that match a given configuration and filter criteria.\n\nHere we will create a Couchbase connection. We are using local setup with bucket `test`, `langgraph` scope. You may change bucket and scope if required. We will also require `checkpoints` and `checkpoint_writes` as collections inside the configured scope.\n\nThen a [ReAct Agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/) is created with GPT Model, weather tool and Couchbase checkpointer.\n\nLangGraph's graph is invoked with message for GPT, storing all the state in Couchbase. We use get, get_tuple and list methods to fetch the states again"
]
},
{
Expand All @@ -186,19 +182,19 @@
"from langgraph_checkpointer_couchbase import CouchbaseSaver\n",
"\n",
"with CouchbaseSaver.from_conn_info(\n",
" cb_conn_str=\"couchbase://localhost\",\n",
" cb_username=\"Administrator\",\n",
" cb_password=\"password\",\n",
" bucket_name=\"test\",\n",
" scope_name=\"langgraph\",\n",
" cb_conn_str=CB_CONN_STR,\n",
" cb_username=CB_USERNAME,\n",
" cb_password=CB_PASSWORD,\n",
" bucket_name=CB_BUCKET_NAME,\n",
" scope_name=CB_SCOPE_NAME,\n",
") as checkpointer:\n",
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
" graph = create_agent(model, tools=tools, checkpointer=checkpointer)\n",
" config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
" res = graph.invoke({\"messages\": [(\"human\", \"what's the weather in sf\")]}, config)\n",
" \n",
" latest_checkpoint = checkpointer.get(config)\n",
" latest_checkpoint_tuple = checkpointer.get_tuple(config)\n",
" checkpoint_tuples = list(checkpointer.list(config))"
" checkpoint_tuples = list(checkpointer.list(config))\n"
]
},
{
Expand Down Expand Up @@ -291,16 +287,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"This is the asynchronous example, Here we will create a Couchbase connection. We are using local setup with bucket `test`, `langgraph` scope. We will also require `checkpoints` and `checkpoint_writes` as collections inside. These are the methods supported by the library\n",
"\n",
"- `.aput` - Store a checkpoint with its configuration and metadata.\n",
"- `.aput_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes).\n",
"- `.aget_tuple` - Fetch a checkpoint tuple using a given configuration (`thread_id` and `checkpoint_id`).\n",
"- `.alist` - List checkpoints that match a given configuration and filter criteria.\n",
"\n",
"Then a [ReAct Agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/) is created with GPT Model, weather tool and Couchbase checkpointer.\n",
"\n",
"LangGraph's graph is invoked with message for GPT, storing all the state in Couchbase. We use aget, aget_tuple and alist methods to fetch the states again"
"This is the asynchronous example, Here we will create a Couchbase connection. We are using local setup with bucket `test`, `langgraph` scope. We will also require `checkpoints` and `checkpoint_writes` as collections inside the configured scope. These are the methods supported by the library\n\n- `.aput` - Store a checkpoint with its configuration and metadata.\n- `.aput_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes).\n- `.aget_tuple` - Fetch a checkpoint tuple using a given configuration (`thread_id` and `checkpoint_id`).\n- `.alist` - List checkpoints that match a given configuration and filter criteria.\n\nThen a [ReAct Agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/) is created with GPT Model, weather tool and Couchbase checkpointer.\n\nLangGraph's graph is invoked with message for GPT, storing all the state in Couchbase. We use aget, aget_tuple and alist methods to fetch the states again"
]
},
{
Expand All @@ -314,13 +301,9 @@
"from couchbase.auth import PasswordAuthenticator\n",
"from couchbase.options import ClusterOptions\n",
"\n",
"cb_conn_str = \"couchbase://localhost\"\n",
"cb_username = \"Administrator\"\n",
"cb_password = \"password\"\n",
"\n",
"auth = PasswordAuthenticator(cb_username, cb_password)\n",
"auth = PasswordAuthenticator(CB_USERNAME, CB_PASSWORD)\n",
"options = ClusterOptions(auth)\n",
"cb_cluster = await ACluster.connect(cb_conn_str, options)"
"cb_cluster = await ACluster.connect(CB_CONN_STR, options)\n"
]
},
{
Expand All @@ -333,18 +316,18 @@
"\n",
"async with AsyncCouchbaseSaver.from_cluster(\n",
" cluster=cb_cluster,\n",
" bucket_name=\"test\",\n",
" scope_name=\"langgraph\",\n",
" bucket_name=CB_BUCKET_NAME,\n",
" scope_name=CB_SCOPE_NAME,\n",
") as checkpointer:\n",
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
" graph = create_agent(model, tools=tools, checkpointer=checkpointer)\n",
" config = {\"configurable\": {\"thread_id\": \"2\"}}\n",
" res = await graph.ainvoke(\n",
" {\"messages\": [(\"human\", \"what's the weather in nyc\")]}, config\n",
" )\n",
"\n",
" latest_checkpoint = await checkpointer.aget(config)\n",
" latest_checkpoint_tuple = await checkpointer.aget_tuple(config)\n",
" checkpoint_tuples = [c async for c in checkpointer.alist(config)]"
" checkpoint_tuples = [c async for c in checkpointer.alist(config)]\n"
]
},
{
Expand Down
Loading