From 0425d4e65d62fb87540e79bbfbe2ba6cfc04e6ba Mon Sep 17 00:00:00 2001 From: Nuno Campos Date: Mon, 31 Mar 2025 16:29:07 -0700 Subject: [PATCH] Update --- libs/langgraph/langgraph/channels/any_value.py | 2 +- libs/langgraph/langgraph/channels/binop.py | 2 +- .../langgraph/channels/dynamic_barrier_value.py | 3 ++- libs/langgraph/langgraph/channels/ephemeral_value.py | 2 +- libs/langgraph/langgraph/channels/last_value.py | 2 +- libs/langgraph/langgraph/channels/named_barrier_value.py | 3 ++- libs/langgraph/langgraph/channels/topic.py | 3 ++- libs/langgraph/langgraph/pregel/manager.py | 5 +++-- libs/langgraph/tests/test_channels.py | 9 +++++---- libs/langgraph/tests/test_pregel.py | 8 ++++---- libs/langgraph/tests/test_pregel_async.py | 8 ++++---- 11 files changed, 26 insertions(+), 21 deletions(-) diff --git a/libs/langgraph/langgraph/channels/any_value.py b/libs/langgraph/langgraph/channels/any_value.py index 35452084f..412436d4f 100644 --- a/libs/langgraph/langgraph/channels/any_value.py +++ b/libs/langgraph/langgraph/channels/any_value.py @@ -33,7 +33,7 @@ class AnyValue(Generic[Value], BaseChannel[Value, Value, Value]): def from_checkpoint(self, checkpoint: Optional[Value]) -> Self: empty = self.__class__(self.typ) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: empty.value = checkpoint return empty diff --git a/libs/langgraph/langgraph/channels/binop.py b/libs/langgraph/langgraph/channels/binop.py index 413e0b91a..9ed2f0ca5 100644 --- a/libs/langgraph/langgraph/channels/binop.py +++ b/libs/langgraph/langgraph/channels/binop.py @@ -75,7 +75,7 @@ class BinaryOperatorAggregate(Generic[Value], BaseChannel[Value, Value, Value]): def from_checkpoint(self, checkpoint: Optional[Value]) -> Self: empty = self.__class__(self.typ, self.operator) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: empty.value = checkpoint return empty diff --git a/libs/langgraph/langgraph/channels/dynamic_barrier_value.py b/libs/langgraph/langgraph/channels/dynamic_barrier_value.py index 155c65446..d9ea1ba8b 100644 --- a/libs/langgraph/langgraph/channels/dynamic_barrier_value.py +++ b/libs/langgraph/langgraph/channels/dynamic_barrier_value.py @@ -3,6 +3,7 @@ from typing import Any, Generic, NamedTuple, Optional, Sequence, Type, Union from typing_extensions import Self from langgraph.channels.base import BaseChannel, Value +from langgraph.constants import MISSING from langgraph.errors import EmptyChannelError, InvalidUpdateError @@ -54,7 +55,7 @@ class DynamicBarrierValue( ) -> Self: empty = self.__class__(self.typ) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: names, seen = checkpoint empty.names = names if names is not None else None empty.seen = seen diff --git a/libs/langgraph/langgraph/channels/ephemeral_value.py b/libs/langgraph/langgraph/channels/ephemeral_value.py index 29a9a698c..23e80c017 100644 --- a/libs/langgraph/langgraph/channels/ephemeral_value.py +++ b/libs/langgraph/langgraph/channels/ephemeral_value.py @@ -33,7 +33,7 @@ class EphemeralValue(Generic[Value], BaseChannel[Value, Value, Value]): def from_checkpoint(self, checkpoint: Optional[Value]) -> Self: empty = self.__class__(self.typ, self.guard) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: empty.value = checkpoint return empty diff --git a/libs/langgraph/langgraph/channels/last_value.py b/libs/langgraph/langgraph/channels/last_value.py index 61669d390..dd67872b8 100644 --- a/libs/langgraph/langgraph/channels/last_value.py +++ b/libs/langgraph/langgraph/channels/last_value.py @@ -37,7 +37,7 @@ class LastValue(Generic[Value], BaseChannel[Value, Value, Value]): def from_checkpoint(self, checkpoint: Optional[Value]) -> Self: empty = self.__class__(self.typ) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: empty.value = checkpoint return empty diff --git a/libs/langgraph/langgraph/channels/named_barrier_value.py b/libs/langgraph/langgraph/channels/named_barrier_value.py index 553316e19..4402dce95 100644 --- a/libs/langgraph/langgraph/channels/named_barrier_value.py +++ b/libs/langgraph/langgraph/channels/named_barrier_value.py @@ -3,6 +3,7 @@ from typing import Generic, Optional, Sequence, Type from typing_extensions import Self from langgraph.channels.base import BaseChannel, Value +from langgraph.constants import MISSING from langgraph.errors import EmptyChannelError, InvalidUpdateError @@ -38,7 +39,7 @@ class NamedBarrierValue(Generic[Value], BaseChannel[Value, Value, set[Value]]): def from_checkpoint(self, checkpoint: Optional[set[Value]]) -> Self: empty = self.__class__(self.typ, self.names) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: empty.seen = checkpoint return empty diff --git a/libs/langgraph/langgraph/channels/topic.py b/libs/langgraph/langgraph/channels/topic.py index 5b081ee4c..2f3e73955 100644 --- a/libs/langgraph/langgraph/channels/topic.py +++ b/libs/langgraph/langgraph/channels/topic.py @@ -3,6 +3,7 @@ from typing import Any, Generic, Iterator, Optional, Sequence, Type, Union from typing_extensions import Self from langgraph.channels.base import BaseChannel, Value +from langgraph.constants import MISSING from langgraph.errors import EmptyChannelError @@ -55,7 +56,7 @@ class Topic( def from_checkpoint(self, checkpoint: Optional[list[Value]]) -> Self: empty = self.__class__(self.typ, self.accumulate) empty.key = self.key - if checkpoint is not None: + if checkpoint is not MISSING: if isinstance(checkpoint, tuple): empty.values = checkpoint[1] else: diff --git a/libs/langgraph/langgraph/pregel/manager.py b/libs/langgraph/langgraph/pregel/manager.py index 641e1d8fe..b117e830c 100644 --- a/libs/langgraph/langgraph/pregel/manager.py +++ b/libs/langgraph/langgraph/pregel/manager.py @@ -4,6 +4,7 @@ from typing import AsyncIterator, Iterator, Mapping, Union from langgraph.channels.base import BaseChannel from langgraph.checkpoint.base import Checkpoint +from langgraph.constants import MISSING from langgraph.managed.base import ( ConfiguredManagedValue, ManagedValueMapping, @@ -36,7 +37,7 @@ def ChannelsManager( with ExitStack() as stack: yield ( { - k: v.from_checkpoint(checkpoint["channel_values"].get(k)) + k: v.from_checkpoint(checkpoint["channel_values"].get(k, MISSING)) for k, v in channel_specs.items() }, ManagedValueMapping( @@ -90,7 +91,7 @@ async def AsyncChannelsManager( yield ( # channels: enter each channel with checkpoint { - k: v.from_checkpoint(checkpoint["channel_values"].get(k)) + k: v.from_checkpoint(checkpoint["channel_values"].get(k, MISSING)) for k, v in channel_specs.items() }, # managed: build mapping from spec to result diff --git a/libs/langgraph/tests/test_channels.py b/libs/langgraph/tests/test_channels.py index 7c6fb162b..b65036e54 100644 --- a/libs/langgraph/tests/test_channels.py +++ b/libs/langgraph/tests/test_channels.py @@ -6,13 +6,14 @@ import pytest from langgraph.channels.binop import BinaryOperatorAggregate from langgraph.channels.last_value import LastValue from langgraph.channels.topic import Topic +from langgraph.constants import MISSING from langgraph.errors import EmptyChannelError, InvalidUpdateError pytestmark = pytest.mark.anyio def test_last_value() -> None: - channel = LastValue(int).from_checkpoint(None) + channel = LastValue(int).from_checkpoint(MISSING) assert channel.ValueType is int assert channel.UpdateType is int @@ -31,7 +32,7 @@ def test_last_value() -> None: def test_topic() -> None: - channel = Topic(str).from_checkpoint(None) + channel = Topic(str).from_checkpoint(MISSING) assert channel.ValueType is Sequence[str] assert channel.UpdateType is Union[str, list[str]] @@ -55,7 +56,7 @@ def test_topic() -> None: def test_topic_accumulate() -> None: - channel = Topic(str, accumulate=True).from_checkpoint(None) + channel = Topic(str, accumulate=True).from_checkpoint(MISSING) assert channel.ValueType is Sequence[str] assert channel.UpdateType is Union[str, list[str]] @@ -73,7 +74,7 @@ def test_topic_accumulate() -> None: def test_binop() -> None: - channel = BinaryOperatorAggregate(int, operator.add).from_checkpoint(None) + channel = BinaryOperatorAggregate(int, operator.add).from_checkpoint(MISSING) assert channel.ValueType is int assert channel.UpdateType is int diff --git a/libs/langgraph/tests/test_pregel.py b/libs/langgraph/tests/test_pregel.py index 34549caf4..2264ec756 100644 --- a/libs/langgraph/tests/test_pregel.py +++ b/libs/langgraph/tests/test_pregel.py @@ -1310,8 +1310,8 @@ def test_pending_writes_resume( }, "channel_values": { "value": 1, - "branch:to:one": "__start__", - "branch:to:two": "__start__", + "branch:to:one": None, + "branch:to:two": None, }, }, metadata={ @@ -1363,8 +1363,8 @@ def test_pending_writes_resume( parent_config=None, pending_writes=UnsortedSequence( (AnyStr(), "value", 1), - (AnyStr(), "branch:to:one", "__start__"), - (AnyStr(), "branch:to:two", "__start__"), + (AnyStr(), "branch:to:one", None), + (AnyStr(), "branch:to:two", None), ), ) diff --git a/libs/langgraph/tests/test_pregel_async.py b/libs/langgraph/tests/test_pregel_async.py index d50589a24..e5b94ac60 100644 --- a/libs/langgraph/tests/test_pregel_async.py +++ b/libs/langgraph/tests/test_pregel_async.py @@ -2146,8 +2146,8 @@ async def test_pending_writes_resume( }, "channel_values": { "value": 1, - "branch:to:one": "__start__", - "branch:to:two": "__start__", + "branch:to:one": None, + "branch:to:two": None, }, }, metadata={ @@ -2201,8 +2201,8 @@ async def test_pending_writes_resume( parent_config=None, pending_writes=UnsortedSequence( (AnyStr(), "value", 1), - (AnyStr(), "branch:to:one", "__start__"), - (AnyStr(), "branch:to:two", "__start__"), + (AnyStr(), "branch:to:one", None), + (AnyStr(), "branch:to:two", None), ), )