feat(checkpoint/serde): serialize DiffDelta as 'diff' type tag

Add serde support for DiffDelta by implementing dump/load for the "diff" type tag.
This allows the checkpoint system to efficiently store delta objects by serializing
them as msgpack-encoded dicts with {"d": delta, "p": prev_version} structure.

The implementation uses runtime type checking to avoid circular imports and
leverages the existing msgpack ext hooks for proper deserialization of complex
types like LangChain messages.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Sydney Runkle
2026-04-17 14:21:40 -04:00
co-authored by Claude Sonnet 4.5
parent 4d1f4086eb
commit 9e40dee07f
2 changed files with 42 additions and 0 deletions
@@ -239,6 +239,12 @@ class JsonPlusSerializer(SerializerProtocol):
return "bytes", obj
elif isinstance(obj, bytearray):
return "bytearray", obj
elif (
type(obj).__name__ == "DiffDelta"
and hasattr(obj, "delta")
and hasattr(obj, "prev_version")
):
return "diff", _msgpack_enc({"d": obj.delta, "p": obj.prev_version})
else:
try:
return "msgpack", _msgpack_enc(obj)
@@ -261,6 +267,10 @@ class JsonPlusSerializer(SerializerProtocol):
return ormsgpack.unpackb(
data_, ext_hook=self._unpack_ext_hook, option=ormsgpack.OPT_NON_STR_KEYS
)
elif type_ == "diff":
return ormsgpack.unpackb(
data_, ext_hook=self._unpack_ext_hook, option=ormsgpack.OPT_NON_STR_KEYS
)
elif self.pickle_fallback and type_ == "pickle":
return pickle.loads(data_)
else:
+32
View File
@@ -983,3 +983,35 @@ def test_msgpack_nested_pydantic_serializes_as_dict(
# No blocking should occur - inner is serialized as dict, not ext
assert "blocked" not in caplog.text.lower()
assert result == obj
def test_diff_delta_serde_round_trip() -> None:
from langgraph.checkpoint.base import DiffDelta
serde = JsonPlusSerializer()
prev = "00000000000000000000000000000001.1234567890123456"
delta = DiffDelta(
delta=[HumanMessage(content="hello", id="msg-1")],
prev_version=prev,
)
type_tag, blob = serde.dumps_typed(delta)
assert type_tag == "diff"
result = serde.loads_typed(("diff", blob))
assert isinstance(result, dict)
assert result["p"] == prev
assert len(result["d"]) == 1
assert result["d"][0].content == "hello"
def test_diff_delta_serde_root_blob() -> None:
from langgraph.checkpoint.base import DiffDelta
serde = JsonPlusSerializer()
delta = DiffDelta(delta=[], prev_version=None)
type_tag, blob = serde.dumps_typed(delta)
assert type_tag == "diff"
result = serde.loads_typed(("diff", blob))
assert result["p"] is None
assert result["d"] == []