mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-21 15:12:26 +02:00
## Summary Add a system-wide upper bound on supersteps-since-last-snapshot for `DeltaChannel`, preventing unbounded ancestor walks on long-lived threads where a delta channel stops receiving writes. **Problem:** If a delta channel is written a few times (below `snapshot_frequency`) and then never written again, it is never snapshotted. Every subsequent run triggers an ancestor walk that grows linearly with thread length — on long threads this becomes catastrophic. **Solution:** Track a second counter (total supersteps) per delta channel alongside the existing update count. Force a snapshot when EITHER `updates >= snapshot_frequency` OR `supersteps >= DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT` (default 5000, overridable via env `LANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT`). ### Changes - **`checkpoint` lib**: Rename metadata field `delta_updates_since_snapshot: dict[str, int]` -> `counters_since_last_snapshot: dict[str, tuple[int, int]]` where index 0 = updates, index 1 = supersteps. - **`langgraph/_internal/_config.py`**: Add `DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT` constant with env override. - **`langgraph/pregel/_checkpoint.py`**: Update `delta_channels_to_snapshot()` predicate to fire on either threshold. Rename reader helper to `read_counters_since_last_snapshot()`. - **`langgraph/pregel/_loop.py`**: Iterate all delta channels each superstep (not just updated ones) to bump the supersteps counter. Reset both counters to `(0, 0)` on snapshot. - **Tests**: Updated existing exit-mode tests for new field shape. Added 4 new tests covering forced snapshot (single run + multi-run accumulation), predicate unit test, and counter reset. ## Test plan - [x] `test_delta_channel_supersteps_bound.py` — 4 new tests all pass - [x] `test_delta_channel_exit_mode.py` — 11 existing tests updated and pass - [x] `test_delta_channel_migration.py` — 11 tests pass - [x] `test_channels.py` — 29 tests pass - [x] `test_pregel.py` — 457 tests pass - [x] `libs/checkpoint` test suite — 151 pass, 16 skipped - [x] `make lint` clean (langgraph + checkpoint)