diff --git a/tutorial/markdown/generated/vector-search-cookbook/couchbase_presistence_langgraph.md b/tutorial/markdown/generated/vector-search-cookbook/couchbase_presistence_langgraph.md deleted file mode 100644 index 2f846ac..0000000 --- a/tutorial/markdown/generated/vector-search-cookbook/couchbase_presistence_langgraph.md +++ /dev/null @@ -1,316 +0,0 @@ ---- -# frontmatter -path: "/tutorial-langgraph-persistence-checkpoint" -title: Persist LangGraph State with Couchbase Checkpointer -short_title: Persist LangGraph State with Couchbase -description: - - Learn how to use Checkpointer Library for LangGraph - - Use Couchbase to store the LangGraph states -content_type: tutorial -filter: sdk -technology: - - kv -tags: - - Artificial Intelligence - - LangGraph -sdk_language: - - python -length: 20 Mins ---- - - - - - -[View Source](https://github.com/couchbase-examples/vector-search-cookbook/tree/main/langgraph/couchbase_presistence_langgraph.ipynb) - -# LangGraph Persistence with Couchbase - -### LangGraph - -LangGraph is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows. Compared to other LLM frameworks, it offers these core benefits: cycles, controllability, and persistence. LangGraph allows you to define flows that involve cycles, essential for most agentic architectures, differentiating it from DAG-based solutions. This tutorial focuses on showcasing persisting state of [LangGraph](https://github.com/langchain-ai/langgraph) with Couchbase. - -### Checkpointer - -Checkpointers in LangGraph save snapshots of graph state at each execution step, enabling memory between interactions, human-in-the-loop workflows, and fault tolerance. By organizing states into "threads" with unique IDs - `thread_id`, they preserve conversation history and allow time travel debugging. Checkpointers implement methods to store, retrieve, and list checkpoints, with various backend options (in-memory, Couchbase, SQLite) to suit different application needs. This persistence layer is what enables agents to maintain context across multiple user interactions and recover gracefully from failures. - -### Couchbase as a Checkpointer - -This tutorial focuses on implementing a LangGraph checkpointer with Couchbase, leveraging Couchbase's distributed architecture, JSON document model, and high availability to provide robust persistence for agent workflows. Couchbase's scalability and flexible query capabilities make it an ideal backend for managing complex conversation states across multiple users and sessions. - -# How to use Couchbase Checkpointer - - - -This tutorial focuses on using a LangGraph checkpointer with Couchbase using the dedicated [langgraph-checkpointer-couchbase](https://pypi.org/project/langgraph-checkpointer-couchbase/) package. - -This package provides a seamless way to persist LangGraph agent states in Couchbase, enabling: - -- State persistence across application restarts -- Retrieval of historical conversation steps -- Continued conversations from previous checkpoints -- Both synchronous and asynchronous interfaces - -## Setup environment - -Requires Couchbase Python SDK and langgraph package - - -```python -%%capture --no-stderr -%pip install -U langgraph==0.3.22 langgraph-checkpointer-couchbase -``` - -This particular example uses OpenAI's GPT 4.1-mini as the model - - -```python -import getpass -import os - - -def _set_env(var: str): - if not os.environ.get(var): - os.environ[var] = getpass.getpass(f"{var}: ") - - -_set_env("OPENAI_API_KEY") -``` - -## Setup model and tools for the graph - -We will be creating a [ReAct Agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/) for this demo. Let's create a custom tool which our agent can call to get more information. - -We are using a tool `get_weather` which gives the weather information based on the city. This tool gives weather information based on the city. We are also setting up the ChatGPT model here. - - -```python -from typing import Literal -from langchain_core.tools import tool -from langchain_openai import ChatOpenAI -from langgraph.prebuilt import create_react_agent - - -@tool -def get_weather(city: Literal["nyc", "sf"]): - """Use this to get weather information.""" - if city == "nyc": - return "It might be cloudy in nyc" - elif city == "sf": - return "It's always sunny in sf" - else: - raise AssertionError("Unknown city") - - -tools = [get_weather] -model = ChatOpenAI(model_name="gpt-4.1-mini", temperature=0) -``` - -### Couchbase Connection and intialization - -There are 2 ways to initialize a saver. - -1. `from_conn_info` - Provide details of the connection string, username, password. The package will handle connection itself. -2. `from_cluster` - Provide a connected Couchbase.Cluster object. - -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 - - -## Use sync connection (CouchbaseSaver) - -Below is usage of CouchbaseSaver (for synchronous use of graph, i.e. `.invoke()`, `.stream()`). CouchbaseSaver implements four methods that are required for any checkpointer: - -- `.put` - Store a checkpoint with its configuration and metadata. -- `.put_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes). -- `.get_tuple` - Fetch a checkpoint tuple using a given configuration (`thread_id` and `checkpoint_id`). -- `.list` - List checkpoints that match a given configuration and filter criteria. - -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. - -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. - -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 - - -```python -from langgraph_checkpointer_couchbase import CouchbaseSaver - -with CouchbaseSaver.from_conn_info( - cb_conn_str="couchbase://localhost", - cb_username="Administrator", - cb_password="password", - bucket_name="test", - scope_name="langgraph", -) as checkpointer: - graph = create_react_agent(model, tools=tools, checkpointer=checkpointer) - config = {"configurable": {"thread_id": "1"}} - res = graph.invoke({"messages": [("human", "what's the weather in sf")]}, config) - - latest_checkpoint = checkpointer.get(config) - latest_checkpoint_tuple = checkpointer.get_tuple(config) - checkpoint_tuples = list(checkpointer.list(config)) -``` - - -```python -latest_checkpoint -``` - - - - - {'v': 2, - 'ts': '2025-04-22T04:38:11.363745+00:00', - 'id': '1f01f339-8ab3-6ce0-8003-a475eb1c8337', - 'channel_values': {'messages': [HumanMessage(content="what's the weather in sf", additional_kwargs={}, response_metadata={}, id='f8fdddb2-5a72-4bf6-84d9-1576d48d6a45'), - AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'function': {'arguments': '{"city":"sf"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 57, 'total_tokens': 72, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgXgi0qlJYegX2Mtz8KC3r9YsD8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-94b537ab-dcb7-4776-804d-087bf476761a-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 15, 'total_tokens': 72, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), - ToolMessage(content="It's always sunny in sf", name='get_weather', id='15c7d895-1e5a-4edf-9dfc-5a5f363d6111', tool_call_id='call_zRq0TmgKvcfoaiaRQxd1YlXe'), - AIMessage(content='The weather in San Francisco is always sunny.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 84, 'total_tokens': 95, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgYLdRzuTyLsLvAc3MDV90N8Y9F', 'finish_reason': 'stop', 'logprobs': None}, id='run-8ee450ec-4a15-4ceb-b4ed-49a98c7f9ab5-0', usage_metadata={'input_tokens': 84, 'output_tokens': 11, 'total_tokens': 95, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}, - 'channel_versions': {'__start__': 2, - 'messages': 5, - 'branch:to:agent': 5, - 'branch:to:tools': 4}, - 'versions_seen': {'__input__': {}, - '__start__': {'__start__': 1}, - 'agent': {'branch:to:agent': 4}, - 'tools': {'branch:to:tools': 3}}, - 'pending_sends': []} - - - - -```python -latest_checkpoint_tuple -``` - - - - - CheckpointTuple(config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8ab3-6ce0-8003-a475eb1c8337'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:11.363745+00:00', 'id': '1f01f339-8ab3-6ce0-8003-a475eb1c8337', 'channel_values': {'messages': [HumanMessage(content="what's the weather in sf", additional_kwargs={}, response_metadata={}, id='f8fdddb2-5a72-4bf6-84d9-1576d48d6a45'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'function': {'arguments': '{"city":"sf"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 57, 'total_tokens': 72, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgXgi0qlJYegX2Mtz8KC3r9YsD8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-94b537ab-dcb7-4776-804d-087bf476761a-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 15, 'total_tokens': 72, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content="It's always sunny in sf", name='get_weather', id='15c7d895-1e5a-4edf-9dfc-5a5f363d6111', tool_call_id='call_zRq0TmgKvcfoaiaRQxd1YlXe'), AIMessage(content='The weather in San Francisco is always sunny.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 84, 'total_tokens': 95, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgYLdRzuTyLsLvAc3MDV90N8Y9F', 'finish_reason': 'stop', 'logprobs': None}, id='run-8ee450ec-4a15-4ceb-b4ed-49a98c7f9ab5-0', usage_metadata={'input_tokens': 84, 'output_tokens': 11, 'total_tokens': 95, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}, 'channel_versions': {'__start__': 2, 'messages': 5, 'branch:to:agent': 5, 'branch:to:tools': 4}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 4}, 'tools': {'branch:to:tools': 3}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='The weather in San Francisco is always sunny.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 84, 'total_tokens': 95, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgYLdRzuTyLsLvAc3MDV90N8Y9F', 'finish_reason': 'stop', 'logprobs': None}, id='run-8ee450ec-4a15-4ceb-b4ed-49a98c7f9ab5-0', usage_metadata={'input_tokens': 84, 'output_tokens': 11, 'total_tokens': 95, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}, 'step': 3, 'parents': {}, 'thread_id': '1'}, parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8237-6166-8002-ac95e49f67e4'}}, pending_writes=[]) - - - - -```python -checkpoint_tuples -``` - - - - - [CheckpointTuple(config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8ab3-6ce0-8003-a475eb1c8337'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:11.363745+00:00', 'id': '1f01f339-8ab3-6ce0-8003-a475eb1c8337', 'channel_values': {'messages': [HumanMessage(content="what's the weather in sf", additional_kwargs={}, response_metadata={}, id='f8fdddb2-5a72-4bf6-84d9-1576d48d6a45'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'function': {'arguments': '{"city":"sf"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 57, 'total_tokens': 72, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgXgi0qlJYegX2Mtz8KC3r9YsD8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-94b537ab-dcb7-4776-804d-087bf476761a-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 15, 'total_tokens': 72, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content="It's always sunny in sf", name='get_weather', id='15c7d895-1e5a-4edf-9dfc-5a5f363d6111', tool_call_id='call_zRq0TmgKvcfoaiaRQxd1YlXe'), AIMessage(content='The weather in San Francisco is always sunny.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 84, 'total_tokens': 95, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgYLdRzuTyLsLvAc3MDV90N8Y9F', 'finish_reason': 'stop', 'logprobs': None}, id='run-8ee450ec-4a15-4ceb-b4ed-49a98c7f9ab5-0', usage_metadata={'input_tokens': 84, 'output_tokens': 11, 'total_tokens': 95, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}, 'channel_versions': {'__start__': 2, 'messages': 5, 'branch:to:agent': 5, 'branch:to:tools': 4}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 4}, 'tools': {'branch:to:tools': 3}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='The weather in San Francisco is always sunny.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 84, 'total_tokens': 95, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgYLdRzuTyLsLvAc3MDV90N8Y9F', 'finish_reason': 'stop', 'logprobs': None}, id='run-8ee450ec-4a15-4ceb-b4ed-49a98c7f9ab5-0', usage_metadata={'input_tokens': 84, 'output_tokens': 11, 'total_tokens': 95, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}, 'step': 3, 'parents': {}, 'thread_id': '1'}, parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8237-6166-8002-ac95e49f67e4'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8237-6166-8002-ac95e49f67e4'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:10.473797+00:00', 'id': '1f01f339-8237-6166-8002-ac95e49f67e4', 'channel_values': {'messages': [HumanMessage(content="what's the weather in sf", additional_kwargs={}, response_metadata={}, id='f8fdddb2-5a72-4bf6-84d9-1576d48d6a45'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'function': {'arguments': '{"city":"sf"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 57, 'total_tokens': 72, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgXgi0qlJYegX2Mtz8KC3r9YsD8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-94b537ab-dcb7-4776-804d-087bf476761a-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 15, 'total_tokens': 72, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content="It's always sunny in sf", name='get_weather', id='15c7d895-1e5a-4edf-9dfc-5a5f363d6111', tool_call_id='call_zRq0TmgKvcfoaiaRQxd1YlXe')], 'branch:to:agent': None}, 'channel_versions': {'__start__': 2, 'messages': 4, 'branch:to:agent': 4, 'branch:to:tools': 4}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 2}, 'tools': {'branch:to:tools': 3}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'tools': {'messages': [ToolMessage(content="It's always sunny in sf", name='get_weather', id='15c7d895-1e5a-4edf-9dfc-5a5f363d6111', tool_call_id='call_zRq0TmgKvcfoaiaRQxd1YlXe')]}}, 'step': 2, 'parents': {}, 'thread_id': '1'}, parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8230-6028-8001-76f23dc92abc'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-8230-6028-8001-76f23dc92abc'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:10.470894+00:00', 'id': '1f01f339-8230-6028-8001-76f23dc92abc', 'channel_values': {'messages': [HumanMessage(content="what's the weather in sf", additional_kwargs={}, response_metadata={}, id='f8fdddb2-5a72-4bf6-84d9-1576d48d6a45'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'function': {'arguments': '{"city":"sf"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 57, 'total_tokens': 72, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgXgi0qlJYegX2Mtz8KC3r9YsD8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-94b537ab-dcb7-4776-804d-087bf476761a-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 15, 'total_tokens': 72, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})], 'branch:to:tools': None}, 'channel_versions': {'__start__': 2, 'messages': 3, 'branch:to:agent': 3, 'branch:to:tools': 3}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 2}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'function': {'arguments': '{"city":"sf"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 57, 'total_tokens': 72, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzgXgi0qlJYegX2Mtz8KC3r9YsD8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-94b537ab-dcb7-4776-804d-087bf476761a-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_zRq0TmgKvcfoaiaRQxd1YlXe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 15, 'total_tokens': 72, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}, 'step': 1, 'parents': {}, 'thread_id': '1'}, parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-6f17-6fe0-8000-bd10177d2f78'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-6f17-6fe0-8000-bd10177d2f78'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:08.468774+00:00', 'id': '1f01f339-6f17-6fe0-8000-bd10177d2f78', 'channel_values': {'messages': [HumanMessage(content="what's the weather in sf", additional_kwargs={}, response_metadata={}, id='f8fdddb2-5a72-4bf6-84d9-1576d48d6a45')], 'branch:to:agent': None}, 'channel_versions': {'__start__': 2, 'messages': 2, 'branch:to:agent': 2}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': None, 'step': 0, 'parents': {}, 'thread_id': '1'}, parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-6f15-6664-bfff-0d88597e0554'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f01f339-6f15-6664-bfff-0d88597e0554'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:08.467717+00:00', 'id': '1f01f339-6f15-6664-bfff-0d88597e0554', 'channel_values': {'__start__': {'messages': [['human', "what's the weather in sf"]]}}, 'channel_versions': {'__start__': 1}, 'versions_seen': {'__input__': {}}, 'pending_sends': []}, metadata={'source': 'input', 'writes': {'__start__': {'messages': [['human', "what's the weather in sf"]]}}, 'step': -1, 'parents': {}, 'thread_id': '1'}, parent_config=None, pending_writes=None)] - - - -## Use async connection (AsyncCouchbaseSaver) - -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 - -- `.aput` - Store a checkpoint with its configuration and metadata. -- `.aput_writes` - Store intermediate writes linked to a checkpoint (i.e. pending writes). -- `.aget_tuple` - Fetch a checkpoint tuple using a given configuration (`thread_id` and `checkpoint_id`). -- `.alist` - List checkpoints that match a given configuration and filter criteria. - -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. - -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 - - -```python -# Create Couchbase Cluster Connection -from acouchbase.cluster import Cluster as ACluster -from couchbase.auth import PasswordAuthenticator -from couchbase.options import ClusterOptions - -cb_conn_str = "couchbase://localhost" -cb_username = "Administrator" -cb_password = "password" - -auth = PasswordAuthenticator(cb_username, cb_password) -options = ClusterOptions(auth) -cb_cluster = await ACluster.connect(cb_conn_str, options) -``` - - -```python -from langgraph_checkpointer_couchbase import AsyncCouchbaseSaver - -async with AsyncCouchbaseSaver.from_cluster( - cluster=cb_cluster, - bucket_name="test", - scope_name="langgraph", -) as checkpointer: - graph = create_react_agent(model, tools=tools, checkpointer=checkpointer) - config = {"configurable": {"thread_id": "2"}} - res = await graph.ainvoke( - {"messages": [("human", "what's the weather in nyc")]}, config - ) - - latest_checkpoint = await checkpointer.aget(config) - latest_checkpoint_tuple = await checkpointer.aget_tuple(config) - checkpoint_tuples = [c async for c in checkpointer.alist(config)] -``` - - -```python -latest_checkpoint -``` - - - - - {'v': 2, - 'ts': '2025-04-22T04:38:51.638880+00:00', - 'id': '1f01f33b-0acb-6cce-8003-7a4f1a2cf90e', - 'channel_values': {'messages': [HumanMessage(content="what's the weather in nyc", additional_kwargs={}, response_metadata={}, id='9475ef5c-67f8-4fa7-b3f4-606b2d74391d'), - AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'function': {'arguments': '{"city":"nyc"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 58, 'total_tokens': 74, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhByznAjlt4j32zfgqTRXfmqNIN', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-d299d9a0-000f-4a4d-a135-373289ffc9b9-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 16, 'total_tokens': 74, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), - ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='54b58baa-d179-496f-a84c-f55a340874cc', tool_call_id='call_haxMoLeSz5hkuUXcerR45Kqt'), - AIMessage(content="The weather in NYC might be cloudy. Is there anything else you'd like to know?", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 88, 'total_tokens': 107, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhCjd46jhDUvB2B01WHfyikY6he', 'finish_reason': 'stop', 'logprobs': None}, id='run-15e27c46-8433-443e-9909-7eea9a1ab2dc-0', usage_metadata={'input_tokens': 88, 'output_tokens': 19, 'total_tokens': 107, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}, - 'channel_versions': {'__start__': 2, - 'messages': 5, - 'branch:to:agent': 5, - 'branch:to:tools': 4}, - 'versions_seen': {'__input__': {}, - '__start__': {'__start__': 1}, - 'agent': {'branch:to:agent': 4}, - 'tools': {'branch:to:tools': 3}}, - 'pending_sends': []} - - - - -```python -latest_checkpoint_tuple -``` - - - - - CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0acb-6cce-8003-7a4f1a2cf90e'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:51.638880+00:00', 'id': '1f01f33b-0acb-6cce-8003-7a4f1a2cf90e', 'channel_values': {'messages': [HumanMessage(content="what's the weather in nyc", additional_kwargs={}, response_metadata={}, id='9475ef5c-67f8-4fa7-b3f4-606b2d74391d'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'function': {'arguments': '{"city":"nyc"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 58, 'total_tokens': 74, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhByznAjlt4j32zfgqTRXfmqNIN', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-d299d9a0-000f-4a4d-a135-373289ffc9b9-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 16, 'total_tokens': 74, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='54b58baa-d179-496f-a84c-f55a340874cc', tool_call_id='call_haxMoLeSz5hkuUXcerR45Kqt'), AIMessage(content="The weather in NYC might be cloudy. Is there anything else you'd like to know?", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 88, 'total_tokens': 107, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhCjd46jhDUvB2B01WHfyikY6he', 'finish_reason': 'stop', 'logprobs': None}, id='run-15e27c46-8433-443e-9909-7eea9a1ab2dc-0', usage_metadata={'input_tokens': 88, 'output_tokens': 19, 'total_tokens': 107, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}, 'channel_versions': {'__start__': 2, 'messages': 5, 'branch:to:agent': 5, 'branch:to:tools': 4}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 4}, 'tools': {'branch:to:tools': 3}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content="The weather in NYC might be cloudy. Is there anything else you'd like to know?", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 88, 'total_tokens': 107, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhCjd46jhDUvB2B01WHfyikY6he', 'finish_reason': 'stop', 'logprobs': None}, id='run-15e27c46-8433-443e-9909-7eea9a1ab2dc-0', usage_metadata={'input_tokens': 88, 'output_tokens': 19, 'total_tokens': 107, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}, 'step': 3, 'parents': {}, 'thread_id': '2'}, parent_config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0138-6a22-8002-a9a8ec4b7e4e'}}, pending_writes=[]) - - - - -```python -checkpoint_tuples -``` - - - - - [CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0acb-6cce-8003-7a4f1a2cf90e'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:51.638880+00:00', 'id': '1f01f33b-0acb-6cce-8003-7a4f1a2cf90e', 'channel_values': {'messages': [HumanMessage(content="what's the weather in nyc", additional_kwargs={}, response_metadata={}, id='9475ef5c-67f8-4fa7-b3f4-606b2d74391d'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'function': {'arguments': '{"city":"nyc"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 58, 'total_tokens': 74, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhByznAjlt4j32zfgqTRXfmqNIN', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-d299d9a0-000f-4a4d-a135-373289ffc9b9-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 16, 'total_tokens': 74, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='54b58baa-d179-496f-a84c-f55a340874cc', tool_call_id='call_haxMoLeSz5hkuUXcerR45Kqt'), AIMessage(content="The weather in NYC might be cloudy. Is there anything else you'd like to know?", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 88, 'total_tokens': 107, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhCjd46jhDUvB2B01WHfyikY6he', 'finish_reason': 'stop', 'logprobs': None}, id='run-15e27c46-8433-443e-9909-7eea9a1ab2dc-0', usage_metadata={'input_tokens': 88, 'output_tokens': 19, 'total_tokens': 107, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}, 'channel_versions': {'__start__': 2, 'messages': 5, 'branch:to:agent': 5, 'branch:to:tools': 4}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 4}, 'tools': {'branch:to:tools': 3}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content="The weather in NYC might be cloudy. Is there anything else you'd like to know?", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 88, 'total_tokens': 107, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhCjd46jhDUvB2B01WHfyikY6he', 'finish_reason': 'stop', 'logprobs': None}, id='run-15e27c46-8433-443e-9909-7eea9a1ab2dc-0', usage_metadata={'input_tokens': 88, 'output_tokens': 19, 'total_tokens': 107, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}, 'step': 3, 'parents': {}, 'thread_id': '2'}, parent_config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0138-6a22-8002-a9a8ec4b7e4e'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0138-6a22-8002-a9a8ec4b7e4e'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:50.634902+00:00', 'id': '1f01f33b-0138-6a22-8002-a9a8ec4b7e4e', 'channel_values': {'messages': [HumanMessage(content="what's the weather in nyc", additional_kwargs={}, response_metadata={}, id='9475ef5c-67f8-4fa7-b3f4-606b2d74391d'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'function': {'arguments': '{"city":"nyc"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 58, 'total_tokens': 74, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhByznAjlt4j32zfgqTRXfmqNIN', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-d299d9a0-000f-4a4d-a135-373289ffc9b9-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 16, 'total_tokens': 74, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}), ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='54b58baa-d179-496f-a84c-f55a340874cc', tool_call_id='call_haxMoLeSz5hkuUXcerR45Kqt')], 'branch:to:agent': None}, 'channel_versions': {'__start__': 2, 'messages': 4, 'branch:to:agent': 4, 'branch:to:tools': 4}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 2}, 'tools': {'branch:to:tools': 3}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'tools': {'messages': [ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='54b58baa-d179-496f-a84c-f55a340874cc', tool_call_id='call_haxMoLeSz5hkuUXcerR45Kqt')]}}, 'step': 2, 'parents': {}, 'thread_id': '2'}, parent_config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0134-6404-8001-5d2722d53ba0'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33b-0134-6404-8001-5d2722d53ba0'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:50.633105+00:00', 'id': '1f01f33b-0134-6404-8001-5d2722d53ba0', 'channel_values': {'messages': [HumanMessage(content="what's the weather in nyc", additional_kwargs={}, response_metadata={}, id='9475ef5c-67f8-4fa7-b3f4-606b2d74391d'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'function': {'arguments': '{"city":"nyc"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 58, 'total_tokens': 74, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhByznAjlt4j32zfgqTRXfmqNIN', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-d299d9a0-000f-4a4d-a135-373289ffc9b9-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 16, 'total_tokens': 74, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})], 'branch:to:tools': None}, 'channel_versions': {'__start__': 2, 'messages': 3, 'branch:to:agent': 3, 'branch:to:tools': 3}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}, 'agent': {'branch:to:agent': 2}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'function': {'arguments': '{"city":"nyc"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 58, 'total_tokens': 74, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4.1-mini-2025-04-14', 'system_fingerprint': 'fp_79b79be41f', 'id': 'chatcmpl-BOzhByznAjlt4j32zfgqTRXfmqNIN', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-d299d9a0-000f-4a4d-a135-373289ffc9b9-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_haxMoLeSz5hkuUXcerR45Kqt', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 16, 'total_tokens': 74, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}}, 'step': 1, 'parents': {}, 'thread_id': '2'}, parent_config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33a-f6f8-65bc-8000-46d63ff6f934'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33a-f6f8-65bc-8000-46d63ff6f934'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:49.559999+00:00', 'id': '1f01f33a-f6f8-65bc-8000-46d63ff6f934', 'channel_values': {'messages': [HumanMessage(content="what's the weather in nyc", additional_kwargs={}, response_metadata={}, id='9475ef5c-67f8-4fa7-b3f4-606b2d74391d')], 'branch:to:agent': None}, 'channel_versions': {'__start__': 2, 'messages': 2, 'branch:to:agent': 2}, 'versions_seen': {'__input__': {}, '__start__': {'__start__': 1}}, 'pending_sends': []}, metadata={'source': 'loop', 'writes': None, 'step': 0, 'parents': {}, 'thread_id': '2'}, parent_config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33a-f6f5-6790-bfff-47d3da71ee7e'}}, pending_writes=None), - CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1f01f33a-f6f5-6790-bfff-47d3da71ee7e'}}, checkpoint={'v': 2, 'ts': '2025-04-22T04:38:49.558819+00:00', 'id': '1f01f33a-f6f5-6790-bfff-47d3da71ee7e', 'channel_values': {'__start__': {'messages': [['human', "what's the weather in nyc"]]}}, 'channel_versions': {'__start__': 1}, 'versions_seen': {'__input__': {}}, 'pending_sends': []}, metadata={'source': 'input', 'writes': {'__start__': {'messages': [['human', "what's the weather in nyc"]]}}, 'step': -1, 'parents': {}, 'thread_id': '2'}, parent_config=None, pending_writes=None)] - - - - -```python - -```