From 9032a3f90a7b96fb6f4ef49f9bf84615b77e5780 Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Thu, 7 May 2026 06:44:54 -0400 Subject: [PATCH] docs(checkpoint): mark DeltaChannel and delta-history APIs as beta (#7732) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Adds a Beta admonition to the `DeltaChannel` surface area so users can distinguish stable from in-progress contracts. Single-sourced on the base class; subclass overrides in `checkpoint-postgres` / `checkpoint-sqlite` / memory inherit the marker via their existing references back to the base. Touched: - `DeltaChannel` (`libs/langgraph/langgraph/channels/delta.py`) - `BaseCheckpointSaver.get_delta_channel_history` and `aget_delta_channel_history` (`libs/checkpoint/.../base/__init__.py`) - `DeltaChannelHistory` TypedDict - `CheckpointMetadata.delta_updates_since_snapshot` ## Why docstring admonitions, not `@beta` The base `get_delta_channel_history` methods are designed to be overridden by savers. Wrapping with `@beta` (from `langchain_core._api`) would emit warnings whenever a subclass called `super().get_delta_channel_history(...)` or whenever the default ancestor walk fired. Docstring-only keeps the signal advisory and noise-free. `_DeltaSnapshot` is already leading-underscore-private, so it implicitly signals "internal." ## Versioning note This intentionally stays a **minor** bump for the checkpoint releases (4.0 → 4.1, 3.0 → 3.1): - The new methods are strictly additive — defaults provided on the base, no signatures changed, no removed APIs. Third-party savers keep working without overriding anything. - The beta marker and the version bump do orthogonal jobs: semver answers "is this a breaking change?" (no), the marker answers "is this contract stable?" (no). - Bumping major now would consume the lever you want available for when the delta contract actually changes in a breaking way. ## Test plan - [ ] Docstring-only — no behavioral change - [x] `make format && make lint` clean in `libs/checkpoint` and `libs/langgraph` --- .../langgraph/checkpoint/base/__init__.py | 26 ++++++++++++++++++- libs/langgraph/langgraph/channels/delta.py | 9 +++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/libs/checkpoint/langgraph/checkpoint/base/__init__.py b/libs/checkpoint/langgraph/checkpoint/base/__init__.py index b34509f00..b88df0f70 100644 --- a/libs/checkpoint/langgraph/checkpoint/base/__init__.py +++ b/libs/checkpoint/langgraph/checkpoint/base/__init__.py @@ -63,6 +63,11 @@ class CheckpointMetadata(TypedDict, total=False): delta_updates_since_snapshot: dict[str, int] """Per-channel update count since the last `_DeltaSnapshot` was written. + !!! warning "Beta" + + This metadata field backs `DeltaChannel` (beta). The key name and + contents may change while the delta-channel design stabilizes. + Maps channel name → number of supersteps that wrote to this channel since its last snapshot blob. Used by `pregel.create_checkpoint` to decide when to write the next snapshot (when the count reaches the @@ -135,6 +140,11 @@ class CheckpointTuple(NamedTuple): class DeltaChannelHistory(TypedDict): """Per-channel result entry from `BaseCheckpointSaver.get_delta_channel_history`. + !!! warning "Beta" + + Part of the `DeltaChannel` support surface; in beta. Field names and + semantics may change. + Storage-level view of what one channel contributed across the ancestor chain of a target checkpoint: @@ -497,6 +507,14 @@ class BaseCheckpointSaver(Generic[V]): ) -> Mapping[str, DeltaChannelHistory]: """Walk the parent chain returning per-channel writes + seed. + !!! warning "Beta" + + This method is part of the `DeltaChannel` support surface and is + in beta. The signature, return shape (`DeltaChannelHistory`), and + interaction with `_DeltaSnapshot` blobs may change. Override at + your own risk; the default implementation will continue to work + against the public `BaseCheckpointSaver` contract. + For each requested channel, walks ancestors of the checkpoint identified by `config` (following `parent_config`) and accumulates `pending_writes` for that channel. The walk terminates per-channel @@ -556,7 +574,13 @@ class BaseCheckpointSaver(Generic[V]): async def aget_delta_channel_history( self, *, config: RunnableConfig, channels: Sequence[str] ) -> Mapping[str, DeltaChannelHistory]: - """Async version of `get_delta_channel_history`.""" + """Async version of `get_delta_channel_history`. + + !!! warning "Beta" + + This method is part of the `DeltaChannel` support surface and is + in beta. See `get_delta_channel_history` for caveats. + """ if not channels: return {} collected_by_ch: dict[str, list[PendingWrite]] = {c: [] for c in channels} diff --git a/libs/langgraph/langgraph/channels/delta.py b/libs/langgraph/langgraph/channels/delta.py index ac1962e97..00ecd4212 100644 --- a/libs/langgraph/langgraph/channels/delta.py +++ b/libs/langgraph/langgraph/channels/delta.py @@ -26,6 +26,15 @@ class DeltaChannel(Generic[Value], BaseChannel[Any, Any, Any]): """Reducer channel that stores only a sentinel in checkpoint blobs and reconstructs state by replaying ancestor writes through the reducer. + !!! warning "Beta" + + `DeltaChannel` is in beta. The API and on-disk representation may + change in future releases. Threads written with `DeltaChannel` today + are expected to remain readable, but the surrounding contract + (`BaseCheckpointSaver.get_delta_channel_history`, the + `_DeltaSnapshot` blob shape, the `delta_updates_since_snapshot` + metadata field) is not yet stable. + The reducer receives the current accumulated value and a batch of writes in one call: `reducer(state, [write1, write2, ...]) -> new_state`.