diff --git a/libs/checkpoint-postgres/tests/test_async.py b/libs/checkpoint-postgres/tests/test_async.py index e342548a7..14d4508da 100644 --- a/libs/checkpoint-postgres/tests/test_async.py +++ b/libs/checkpoint-postgres/tests/test_async.py @@ -377,13 +377,13 @@ async def test_get_checkpoint_no_channel_values( async def test_delta_channel_chain_reconstruction(saver_name: str) -> None: """AsyncPostgresSaver reconstructs DeltaChannel chain via point-lookup traversal.""" pytest.importorskip( - "langgraph.channels.delta", reason="langgraph core not installed" + "langgraph.channels._delta", reason="langgraph core not installed" ) from typing import Annotated from langchain_core.messages import AIMessage, HumanMessage - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph from langgraph.graph.message import add_messages from typing_extensions import TypedDict diff --git a/libs/langgraph/langgraph/channels/__init__.py b/libs/langgraph/langgraph/channels/__init__.py index cc7fcc471..a69c230b5 100644 --- a/libs/langgraph/langgraph/channels/__init__.py +++ b/libs/langgraph/langgraph/channels/__init__.py @@ -1,7 +1,6 @@ from langgraph.channels.any_value import AnyValue from langgraph.channels.base import BaseChannel from langgraph.channels.binop import BinaryOperatorAggregate -from langgraph.channels.delta import DeltaChannel from langgraph.channels.ephemeral_value import EphemeralValue from langgraph.channels.last_value import LastValue, LastValueAfterFinish from langgraph.channels.named_barrier_value import ( @@ -21,7 +20,6 @@ __all__ = ( "UntrackedValue", "EphemeralValue", "BinaryOperatorAggregate", - "DeltaChannel", "NamedBarrierValue", "NamedBarrierValueAfterFinish", # topics diff --git a/libs/langgraph/langgraph/channels/delta.py b/libs/langgraph/langgraph/channels/_delta.py similarity index 93% rename from libs/langgraph/langgraph/channels/delta.py rename to libs/langgraph/langgraph/channels/_delta.py index e8dd955c2..3239d237b 100644 --- a/libs/langgraph/langgraph/channels/delta.py +++ b/libs/langgraph/langgraph/channels/_delta.py @@ -23,7 +23,13 @@ def _empty(typ: Any) -> Any: class DeltaChannel(Generic[Value], BaseChannel[Any, Any, Any]): - """A channel that stores only a sentinel in checkpoints; per-step writes are + """Experimental — private API, subject to change or removal without notice. + + Imported from the underscored module `langgraph.channels._delta` on purpose; + not re-exported from `langgraph.channels`. Intended for internal use only + while we validate the design on real workloads. + + A channel that stores only a sentinel in checkpoints; per-step writes are stored in checkpoint_writes and replayed through the operator at load time. Use with append-style reducers (e.g. `add_messages`) on long-running threads @@ -36,6 +42,8 @@ class DeltaChannel(Generic[Value], BaseChannel[Any, Any, Any]): Usage:: + from langgraph.channels._delta import DeltaChannel + class State(TypedDict): messages: Annotated[list[AnyMessage], DeltaChannel(add_messages)] """ diff --git a/libs/langgraph/langgraph/graph/state.py b/libs/langgraph/langgraph/graph/state.py index 78cdbb10a..a66062717 100644 --- a/libs/langgraph/langgraph/graph/state.py +++ b/libs/langgraph/langgraph/graph/state.py @@ -49,7 +49,7 @@ from langgraph._internal._runnable import coerce_to_runnable from langgraph._internal._typing import EMPTY_SEQ, MISSING, DeprecatedKwargs from langgraph.channels.base import BaseChannel from langgraph.channels.binop import BinaryOperatorAggregate, _strip_extras -from langgraph.channels.delta import DeltaChannel +from langgraph.channels._delta import DeltaChannel from langgraph.channels.ephemeral_value import EphemeralValue from langgraph.channels.last_value import LastValue, LastValueAfterFinish from langgraph.channels.named_barrier_value import ( diff --git a/libs/langgraph/langgraph/pregel/_checkpoint.py b/libs/langgraph/langgraph/pregel/_checkpoint.py index f3c7f1102..3437692be 100644 --- a/libs/langgraph/langgraph/pregel/_checkpoint.py +++ b/libs/langgraph/langgraph/pregel/_checkpoint.py @@ -9,7 +9,7 @@ from langgraph.checkpoint.base.id import uuid6 from langgraph._internal._typing import MISSING from langgraph.channels.base import BaseChannel -from langgraph.channels.delta import DeltaChannel +from langgraph.channels._delta import DeltaChannel from langgraph.managed.base import ManagedValueMapping, ManagedValueSpec LATEST_VERSION = 4 diff --git a/libs/langgraph/tests/test_channels.py b/libs/langgraph/tests/test_channels.py index 4fd3bb9d3..2b858b6a0 100644 --- a/libs/langgraph/tests/test_channels.py +++ b/libs/langgraph/tests/test_channels.py @@ -7,7 +7,7 @@ from langgraph.checkpoint.base import DELTA_SENTINEL from langgraph._internal._typing import MISSING from langgraph.channels.binop import BinaryOperatorAggregate -from langgraph.channels.delta import DeltaChannel +from langgraph.channels._delta import DeltaChannel from langgraph.channels.last_value import LastValue from langgraph.channels.topic import Topic from langgraph.channels.untracked_value import UntrackedValue @@ -127,7 +127,7 @@ def test_delta_channel_basic_two_steps() -> None: from langchain_core.messages import AIMessage, HumanMessage from langgraph.checkpoint.base import DELTA_SENTINEL - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages ch = DeltaChannel(add_messages).from_checkpoint(MISSING) @@ -152,7 +152,7 @@ def test_delta_channel_from_checkpoint_writes_list() -> None: """replay_writes on a fresh channel replays through the operator.""" from langchain_core.messages import AIMessage, HumanMessage - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages spec = DeltaChannel(add_messages) @@ -174,7 +174,7 @@ def test_delta_channel_from_checkpoint_writes_list() -> None: def test_delta_channel_from_checkpoint_backwards_compat() -> None: from langchain_core.messages import HumanMessage - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages # Old BinaryOperatorAggregate checkpoint: plain list treated as backward compat @@ -188,7 +188,7 @@ def test_delta_channel_overwrite() -> None: from langchain_core.messages import HumanMessage from langgraph.checkpoint.base import DELTA_SENTINEL - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages from langgraph.types import Overwrite @@ -207,7 +207,7 @@ def test_delta_channel_remove_message_and_replay() -> None: """RemoveMessage must round-trip correctly when writes are replayed.""" from langchain_core.messages import AIMessage, HumanMessage, RemoveMessage - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages spec = DeltaChannel(add_messages) @@ -241,7 +241,7 @@ def test_delta_channel_update_by_id_and_replay() -> None: """Updating a message by ID must round-trip correctly through writes replay.""" from langchain_core.messages import HumanMessage - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages spec = DeltaChannel(add_messages) @@ -270,7 +270,7 @@ def test_delta_channel_checkpoint_returns_sentinel() -> None: """checkpoint() always returns DELTA_SENTINEL regardless of state.""" from langgraph.checkpoint.base import DELTA_SENTINEL - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.message import add_messages ch = DeltaChannel(add_messages).from_checkpoint(MISSING) @@ -290,7 +290,7 @@ def test_delta_channel_inmemory_saver_assembles_writes() -> None: from langgraph.checkpoint.memory import InMemorySaver from typing_extensions import TypedDict - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph from langgraph.graph.message import add_messages @@ -329,7 +329,7 @@ def _delta_channel_with_type(operator, typ): """Build a DeltaChannel with an explicit type via the Annotated injection path.""" from typing import Annotated - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.state import _get_channel return _get_channel("_test", Annotated[typ, DeltaChannel(operator)]) @@ -464,7 +464,7 @@ def test_delta_channel_dict_reducer_with_notrequired_annotation() -> None: from typing_extensions import NotRequired - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph.state import _get_channel def merge_dicts(left: dict | None, right: dict) -> dict: @@ -494,7 +494,7 @@ def test_delta_channel_dict_reducer_end_to_end_filesystem() -> None: from langgraph.checkpoint.memory import InMemorySaver from typing_extensions import TypedDict - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph def merge_files(left: dict | None, right: dict) -> dict: diff --git a/libs/langgraph/tests/test_delta_channel_benchmark.py b/libs/langgraph/tests/test_delta_channel_benchmark.py index ab710ebcd..bc393d804 100644 --- a/libs/langgraph/tests/test_delta_channel_benchmark.py +++ b/libs/langgraph/tests/test_delta_channel_benchmark.py @@ -26,7 +26,7 @@ from langchain_core.messages import AIMessage, HumanMessage from langgraph.checkpoint.memory import MemorySaver from typing_extensions import TypedDict -from langgraph.channels.delta import DeltaChannel +from langgraph.channels._delta import DeltaChannel from langgraph.graph import END, StateGraph from langgraph.graph.message import add_messages diff --git a/libs/langgraph/tests/test_delta_channel_migration.py b/libs/langgraph/tests/test_delta_channel_migration.py index 72286522f..bdaa1e6ea 100644 --- a/libs/langgraph/tests/test_delta_channel_migration.py +++ b/libs/langgraph/tests/test_delta_channel_migration.py @@ -50,7 +50,7 @@ from langgraph.checkpoint.memory import InMemorySaver from typing_extensions import TypedDict from langgraph.channels.binop import BinaryOperatorAggregate -from langgraph.channels.delta import DeltaChannel +from langgraph.channels._delta import DeltaChannel from langgraph.graph import END, START, StateGraph pytestmark = pytest.mark.anyio diff --git a/libs/langgraph/tests/test_pregel.py b/libs/langgraph/tests/test_pregel.py index 9ca522bd8..474e08c51 100644 --- a/libs/langgraph/tests/test_pregel.py +++ b/libs/langgraph/tests/test_pregel.py @@ -9407,7 +9407,7 @@ async def test_delta_channel_end_to_end_inmemory() -> None: from langchain_core.messages import AIMessage, HumanMessage from langgraph.checkpoint.memory import InMemorySaver - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph from langgraph.graph.message import add_messages @@ -9449,7 +9449,7 @@ async def test_delta_channel_time_travel() -> None: from langchain_core.messages import AIMessage, HumanMessage from langgraph.checkpoint.memory import InMemorySaver - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph from langgraph.graph.message import add_messages @@ -9507,7 +9507,7 @@ async def test_delta_channel_remove_message_end_to_end() -> None: from langchain_core.messages import AIMessage, HumanMessage, RemoveMessage from langgraph.checkpoint.memory import InMemorySaver - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph from langgraph.graph.message import add_messages @@ -9554,7 +9554,7 @@ async def test_delta_channel_update_by_id_end_to_end() -> None: from langchain_core.messages import HumanMessage from langgraph.checkpoint.memory import InMemorySaver - from langgraph.channels.delta import DeltaChannel + from langgraph.channels._delta import DeltaChannel from langgraph.graph import START, StateGraph from langgraph.graph.message import add_messages