Commit Graph

547 Commits

Author SHA1 Message Date
github-actions[bot] 659d628d19 chore: version packages (#2704)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph@1.4.11

### Patch Changes

- [#2706](https://github.com/langchain-ai/langgraphjs/pull/2706)
[`eaa5472`](https://github.com/langchain-ai/langgraphjs/commit/eaa5472fa480fad2671659d1c9ed0686a55d42bd)
Thanks [@zduric-langchain](https://github.com/zduric-langchain)! -
fix(langgraph): dedupe merged callback handlers by identity

`mergeCallbacks` concatenated `handlers` and `inheritableHandlers` while
deduping `tags`, so a handler inherited by both the ambient and the
explicit
config picked up an extra registration at every graph boundary. With
tracing
  on, a nested `streamMode: "messages"` run delivered every token twice.

- Updated dependencies
[[`3ce9f8d`](https://github.com/langchain-ai/langgraphjs/commit/3ce9f8d11dd64b1d091a25162603c49e6f4a426f),
[`51b4202`](https://github.com/langchain-ai/langgraphjs/commit/51b42020f7c730a15193aa907056881e3d961924),
[`a86f813`](https://github.com/langchain-ai/langgraphjs/commit/a86f813954e010fbf30711c37baa5c53444613d5)]:
  - @langchain/langgraph-sdk@1.9.30
## @langchain/langgraph-sdk@1.9.30

### Patch Changes

- [#2691](https://github.com/langchain-ai/langgraphjs/pull/2691)
[`3ce9f8d`](https://github.com/langchain-ai/langgraphjs/commit/3ce9f8d11dd64b1d091a25162603c49e6f4a426f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): clear messages on hydrate(null) with a pending interrupt

  Teardown awaited the paused root pump, so threadId went null while
  the old conversation stayed on screen. Reset the snapshot first.

- [#2703](https://github.com/langchain-ai/langgraphjs/pull/2703)
[`51b4202`](https://github.com/langchain-ai/langgraphjs/commit/51b42020f7c730a15193aa907056881e3d961924)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): keep isLoading true across interrupt→running hydration

Deferred terminal resets no longer clear isLoading when a newer running
lifecycle has already arrived (HITL resume / SSE replay).

- [#2692](https://github.com/langchain-ai/langgraphjs/pull/2692)
[`a86f813`](https://github.com/langchain-ai/langgraphjs/commit/a86f813954e010fbf30711c37baa5c53444613d5)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): adopt server metadata on same-id optimistic message echo

  When a `values` snapshot echoes an optimistic human with the same
  content plus committed `additional_kwargs` (e.g. attachment paths),
  `stream.messages` now takes the server copy instead of keeping the
  plain optimistic message until hydration. Preferring is asymmetric:
  lagging or poorer values snapshots do not strip richer current
  metadata. In-flight AI token streaming is unchanged: streamed content
  still wins when it has moved past the snapshot.
## @langchain/angular@1.0.31

### Patch Changes

- Updated dependencies
[[`3ce9f8d`](https://github.com/langchain-ai/langgraphjs/commit/3ce9f8d11dd64b1d091a25162603c49e6f4a426f),
[`51b4202`](https://github.com/langchain-ai/langgraphjs/commit/51b42020f7c730a15193aa907056881e3d961924),
[`a86f813`](https://github.com/langchain-ai/langgraphjs/commit/a86f813954e010fbf30711c37baa5c53444613d5)]:
  - @langchain/langgraph-sdk@1.9.30
## @langchain/react@1.0.31

### Patch Changes

- Updated dependencies
[[`3ce9f8d`](https://github.com/langchain-ai/langgraphjs/commit/3ce9f8d11dd64b1d091a25162603c49e6f4a426f),
[`51b4202`](https://github.com/langchain-ai/langgraphjs/commit/51b42020f7c730a15193aa907056881e3d961924),
[`a86f813`](https://github.com/langchain-ai/langgraphjs/commit/a86f813954e010fbf30711c37baa5c53444613d5)]:
  - @langchain/langgraph-sdk@1.9.30
## @langchain/svelte@1.0.31

### Patch Changes

- Updated dependencies
[[`3ce9f8d`](https://github.com/langchain-ai/langgraphjs/commit/3ce9f8d11dd64b1d091a25162603c49e6f4a426f),
[`51b4202`](https://github.com/langchain-ai/langgraphjs/commit/51b42020f7c730a15193aa907056881e3d961924),
[`a86f813`](https://github.com/langchain-ai/langgraphjs/commit/a86f813954e010fbf30711c37baa5c53444613d5)]:
  - @langchain/langgraph-sdk@1.9.30
## @langchain/vue@1.0.31

### Patch Changes

- Updated dependencies
[[`3ce9f8d`](https://github.com/langchain-ai/langgraphjs/commit/3ce9f8d11dd64b1d091a25162603c49e6f4a426f),
[`51b4202`](https://github.com/langchain-ai/langgraphjs/commit/51b42020f7c730a15193aa907056881e3d961924),
[`a86f813`](https://github.com/langchain-ai/langgraphjs/commit/a86f813954e010fbf30711c37baa5c53444613d5)]:
  - @langchain/langgraph-sdk@1.9.30

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-19 12:36:59 -07:00
Zlatko Duric eaa5472fa4 fix(langgraph): dedupe merged callback handlers by identity (#2706)
This fixes a double-streaming bug in certain nested graph case
scenarios.

`mergeCallbacks` concatenated `handlers` and `inheritableHandlers` while
deduping tags, so a handler inherited by both the parent and nested
config (in nested graphs) picked up an extra registration at every
nesting level with tracing on. With tracing on, a nested streamMode:
"messages" run delivered every token twice or more.

---------

Co-authored-by: Christian Bromann <git@bromann.dev>
2026-08-19 12:14:22 -07:00
Christian Bromann a86f813954 fix(sdk): adopt server metadata on same-id optimistic message echo (#2692)
## Summary

Optimistic humans kept winning over the values echo, so committed
additional_kwargs (e.g. attachment paths) stayed off stream.messages
until hydration. Prefer the server copy when content matches; streamed
tokens still win when they have moved past the snapshot.

- Same-id `values` echoes of an optimistic human now take
server-authored metadata (`additional_kwargs`, etc.) on
`stream.messages` instead of keeping the plain optimistic copy until
reload.
- In-flight AI token streaming is unchanged: streamed content still wins
when it has moved past the snapshot.
2026-08-18 22:29:39 -07:00
Christian Bromann 3ce9f8d11d fix(sdk): clear messages on hydrate(null) with a pending interrupt (#2691)
## Summary

Teardown awaited the paused root pump, so threadId went null while the
old conversation stayed on screen. Reset the snapshot first.

- Starting a new chat (`threadId` → undefined) on a reused `useStream`
left the previous thread's messages on screen when that thread was
sitting on a pending interrupt. The snapshot now clears before teardown
finishes waiting on the paused pump.
2026-08-18 21:27:17 -07:00
Christian Bromann 51b42020f7 fix(sdk): keep isLoading true across interrupt→running hydration (#2703)
After a HITL interrupt is answered, replaying `interrupted` → `running`
on hydrate could leave `useStream().isLoading` stuck `false`: the
deferred interrupt reset fired after the later `running` and stomped it.
Deferred terminal resets now skip clearing when a newer `running` seq
has already been seen.


<!--
Thank you for contributing to LangGraph.js! Your PR will appear in our
next release under the title you set above. Please make sure it
highlights your valuable contribution.

To help streamline the review process, please make sure you read our
contribution guidelines:
https://github.com/langchain-ai/langgraphjs/blob/main/CONTRIBUTING.md

Replace this block with a description of the change, the issue it fixes
(if applicable), and relevant context.

Finally, we'd love to show appreciation for your contribution - if you'd
like us to shout you out on Twitter, please also include your handle
below!
-->

<!-- Remove if not applicable -->

Fixes # (issue)
2026-08-18 16:35:33 -07:00
github-actions[bot] f6b41bf486 chore: version packages (#2698)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph@1.4.10

### Patch Changes

- [#2690](https://github.com/langchain-ai/langgraphjs/pull/2690)
[`00f68a1`](https://github.com/langchain-ai/langgraphjs/commit/00f68a1b002d820b95129bcdaf387d2678ead6f0)
Thanks
[@saad-supports-langchain](https://github.com/saad-supports-langchain)!
- fix(langgraph): keep `context` values out of tracer-derived metadata

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-14 15:36:37 -04:00
Saad Farooq 00f68a1b00 fix(langgraph): keep context values out of tracer-derived metadata (#2690)
Values passed via `context` were reaching LangSmith as `extra.metadata`.
On Platform the Agent Server mirrors `context` into `configurable`
(`run.py`, *"keep config and context in sync for user provided
params"*), and `_getTracingMetadataDefaults` promoted every
`configurable` entry whose value passes the primitive-type check in
`_excludeAsMetadata` — so data callers deliberately routed through the
non-persisted, non-traced channel was traced anyway, on the root run and
on `__start__` and every node run.

## Changes

- `_getTracingMetadataDefaults` now recognizes context aliases: a
`configurable` entry that is an own property of `config.context` with an
`Object.is`-equal value is treated as context-provenance, not user
metadata.
- Aliased keys emit `metadata[key] = undefined` rather than being
omitted. `LangChainTracer` merges tracing metadata first-wins, so the
root marker also stops `@langchain/core`'s own configurable promotion
from re-adding the key on child task and node runs — the path that
actually leaked. `undefined` drops out on serialization.
- Widened the helper's parameter to `LangGraphRunnableConfig` so
`config.context` is visible; internal `__`-prefixed keys are never
marked.
- Configurable-only values, values that differ from their context
counterpart, explicit `metadata`, and the platform identity keys
(`thread_id`, `run_id`, `assistant_id`, `graph_id`) are all unaffected.

## Testing

Replaced the tracing tests' `FakeTracer` with a `LangChainTracer` backed
by a stubbed client that captures real `createRun` payloads.
`tracerInheritableMetadata` is only applied to `LangChainTracer`
instances, so a `BaseTracer` subclass cannot observe this channel at all
— the assertions now run against the same metadata LangSmith would
receive, across all three runs (`LangGraph`, `__start__`, node).

## Follow-up required — this half is inert alone

Verified end-to-end against the public
`langchain/langgraphjs-api:0.12.2-node24` image with this build
installed in the deployed graph:

| Configuration | context delivered | tracer metadata leak |
|---|---|---|
| public image, this fix | no — sidecar strips `context` | n/a,
suppression cannot fire |
| public image + sidecar forwarding `context`, this fix | yes | absent |
| public image + sidecar forwarding `context`, published `1.3.7` | yes |
present on `__start__` and node runs |

The sidecar's `StreamEventsPayload` (`langgraph_api/js/client.mts`) has
no `context` field, so zod strips it and `config.context` is `undefined`
inside the graph. A matching `langgraph-api` change is needed for this
fix to take effect in production; it will be opened separately.

Separately out of scope: the Python `run.py` backfill still mirrors
`context` into `configurable`, and that mirrored copy is persisted in
thread state and checkpoint metadata. Different channel, pre-existing by
design.
2026-08-14 14:28:36 -04:00
github-actions[bot] 9320c37da2 chore: version packages (#2674)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-sdk@1.9.29

### Patch Changes

- [#2668](https://github.com/langchain-ai/langgraphjs/pull/2668)
[`f9c0e88`](https://github.com/langchain-ai/langgraphjs/commit/f9c0e885e25149fe614d7d2002c884b80ab54484)
Thanks [@edenbuilds](https://github.com/edenbuilds)! - Always attach the
underlying Response on HTTPError.

- [#2675](https://github.com/langchain-ai/langgraphjs/pull/2675)
[`3958305`](https://github.com/langchain-ai/langgraphjs/commit/3958305d3ee89419abc496f28602cf4b38f2a6b3)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): deliver input channel events on the root-bus fast path

`channelProjection` with `replay: false` (the `useChannelEffect`
default) compared `event.method` to channel names, so `input.requested`
never matched `"input"`. Match via `inferChannel` instead, same as the
slow path.

- [#2677](https://github.com/langchain-ai/langgraphjs/pull/2677)
[`4c0fd78`](https://github.com/langchain-ai/langgraphjs/commit/4c0fd78485e1778234ddb56c7579f8d823946f18)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): defer stream join until lazy thread create commits

Hydrating an externally-minted thread id that 404s still opened
`/stream/events` before `POST /commands` created the row. On
langgraph_api's in-mem runtime that join is accepted but dead, so the
first run delivered nothing until idle reconnect. Treat missing threads
like client-minted ones and start the root pump only after dispatch
succeeds.

- [#2672](https://github.com/langchain-ai/langgraphjs/pull/2672)
[`5be518f`](https://github.com/langchain-ai/langgraphjs/commit/5be518fe18f2497a28957dfec85522997e6df4f3)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): surface nested interrupts on stream.interrupts

`input.requested` events from subgraphs/subagents were dropped live by a
root-only filter, while hydrate seeded them from `state.tasks`, so HITL
UIs saw nested interrupts only after reload. Mirror every namespace onto
`rootStore.interrupts` (with `Interrupt.namespace`), and resolve that
namespace in `respond({ interruptId })` when callers omit it.

- [#2676](https://github.com/langchain-ai/langgraphjs/pull/2676)
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): resolve respond() namespace from interrupt id

  When callers pass `{ interruptId }` without `namespace`, look the
  namespace up on `thread.interrupts` instead of defaulting to root.
## @langchain/angular@1.0.30

### Patch Changes

- [#2676](https://github.com/langchain-ai/langgraphjs/pull/2676)
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): resolve respond() namespace from interrupt id

  When callers pass `{ interruptId }` without `namespace`, look the
  namespace up on `thread.interrupts` instead of defaulting to root.

- Updated dependencies
[[`f9c0e88`](https://github.com/langchain-ai/langgraphjs/commit/f9c0e885e25149fe614d7d2002c884b80ab54484),
[`3958305`](https://github.com/langchain-ai/langgraphjs/commit/3958305d3ee89419abc496f28602cf4b38f2a6b3),
[`4c0fd78`](https://github.com/langchain-ai/langgraphjs/commit/4c0fd78485e1778234ddb56c7579f8d823946f18),
[`5be518f`](https://github.com/langchain-ai/langgraphjs/commit/5be518fe18f2497a28957dfec85522997e6df4f3),
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)]:
  - @langchain/langgraph-sdk@1.9.29
## @langchain/react@1.0.30

### Patch Changes

- [#2676](https://github.com/langchain-ai/langgraphjs/pull/2676)
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): resolve respond() namespace from interrupt id

  When callers pass `{ interruptId }` without `namespace`, look the
  namespace up on `thread.interrupts` instead of defaulting to root.

- Updated dependencies
[[`f9c0e88`](https://github.com/langchain-ai/langgraphjs/commit/f9c0e885e25149fe614d7d2002c884b80ab54484),
[`3958305`](https://github.com/langchain-ai/langgraphjs/commit/3958305d3ee89419abc496f28602cf4b38f2a6b3),
[`4c0fd78`](https://github.com/langchain-ai/langgraphjs/commit/4c0fd78485e1778234ddb56c7579f8d823946f18),
[`5be518f`](https://github.com/langchain-ai/langgraphjs/commit/5be518fe18f2497a28957dfec85522997e6df4f3),
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)]:
  - @langchain/langgraph-sdk@1.9.29
## @langchain/svelte@1.0.30

### Patch Changes

- [#2676](https://github.com/langchain-ai/langgraphjs/pull/2676)
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): resolve respond() namespace from interrupt id

  When callers pass `{ interruptId }` without `namespace`, look the
  namespace up on `thread.interrupts` instead of defaulting to root.

- Updated dependencies
[[`f9c0e88`](https://github.com/langchain-ai/langgraphjs/commit/f9c0e885e25149fe614d7d2002c884b80ab54484),
[`3958305`](https://github.com/langchain-ai/langgraphjs/commit/3958305d3ee89419abc496f28602cf4b38f2a6b3),
[`4c0fd78`](https://github.com/langchain-ai/langgraphjs/commit/4c0fd78485e1778234ddb56c7579f8d823946f18),
[`5be518f`](https://github.com/langchain-ai/langgraphjs/commit/5be518fe18f2497a28957dfec85522997e6df4f3),
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)]:
  - @langchain/langgraph-sdk@1.9.29
## @langchain/vue@1.0.30

### Patch Changes

- [#2676](https://github.com/langchain-ai/langgraphjs/pull/2676)
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): resolve respond() namespace from interrupt id

  When callers pass `{ interruptId }` without `namespace`, look the
  namespace up on `thread.interrupts` instead of defaulting to root.

- Updated dependencies
[[`f9c0e88`](https://github.com/langchain-ai/langgraphjs/commit/f9c0e885e25149fe614d7d2002c884b80ab54484),
[`3958305`](https://github.com/langchain-ai/langgraphjs/commit/3958305d3ee89419abc496f28602cf4b38f2a6b3),
[`4c0fd78`](https://github.com/langchain-ai/langgraphjs/commit/4c0fd78485e1778234ddb56c7579f8d823946f18),
[`5be518f`](https://github.com/langchain-ai/langgraphjs/commit/5be518fe18f2497a28957dfec85522997e6df4f3),
[`b3c1ceb`](https://github.com/langchain-ai/langgraphjs/commit/b3c1ceb2cc16dcb15e7a9c1178fe6ddb98e5a93f)]:
  - @langchain/langgraph-sdk@1.9.29

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-10 20:39:44 -07:00
Christian Bromann b3c1ceb2cc fix(sdk): resolve respond() namespace from interrupt id (#2676)
`respond(response, { interruptId })` was sending resumes with the root
namespace whenever `namespace` was omitted. For subgraph interrupts that
mis-targets the resume even though the id already uniquely identifies
the pending interrupt on the thread.
Look the namespace up from `thread.interrupts` by id (same as
`respondAll` / the no-arg path). An explicit `namespace` still
overrides; unknown ids still fall back to root.
2026-08-10 20:33:27 -07:00
Christian Bromann 4c0fd78485 fix(sdk): defer stream join until lazy thread create commits (#2677)
Hydrating an externally-minted thread id that 404s still opened
`/stream/events` before `POST /commands` created the row. On
langgraph_api's in-mem runtime that join is accepted but dead, so the
first run delivered nothing until idle reconnect. Treat missing threads
like client-minted ones and start the root pump only after dispatch
succeeds.
2026-08-10 20:14:42 -07:00
Christian Bromann 3958305d3e fix(sdk): deliver input channel events on the root-bus fast path (#2675)
`channelProjection` with `replay: false` (the `useChannelEffect`
default) matched root-bus events by comparing `event.method` to channel
names. That works for `values` / `messages` / etc., but input events are
`input.requested`, so subscribers to `["input"]` got nothing and no
error.

The fast path now classifies with `inferChannel`, same as the slow
subscription path.

## Test plan
- [x] `pnpm exec vitest run src/stream/projections/channel.test.ts
src/client/stream/subscription.test.ts
src/stream/projections/channel-effect.test.ts` (from `libs/sdk`)
- [x] Changeset added for affected package(s)
- [ ] `useChannelEffect(stream, ["input"], { onEvent })` on a graph that
`interrupt()`s — callback fires without needing `replay: true`
2026-08-10 16:39:12 -07:00
Christian Bromann 5be518fe18 fix(sdk): surface nested interrupts on stream.interrupts (#2672)
Nested `interrupt()` calls (subgraphs / createDeepAgent subagents) never
showed up on `useStream().interrupts` while the run was live —
`#recordRootInterrupt` early-returned on non-root namespaces — but
hydrate seeded them from `state.tasks`, so the same interrupt appeared
after a reload. Mirror every `input.requested` onto
`rootStore.interrupts` with `Interrupt.namespace`, and look that
namespace up in `respond({ interruptId })` when it isn't passed
explicitly.
2026-08-10 16:38:49 -07:00
edenbuilds f9c0e885e2 fix(sdk): always attach Response on HTTPError (#2668)
## Summary
- Always pass `includeResponse: true` when converting failed `Response`
objects to `HTTPError`, so `error.response` is available without
registering `onFailedResponseHook`.

## Test plan
- [x] New unit test `should attach error.response without
onFailedResponseHook` passes with the fix
- [x] Same test fails with `response: undefined` when the fix is stashed
(`git stash` A/B)
- [x] Changeset for `@langchain/langgraph-sdk`

Fixes #2632

Co-authored-by: edenbuilds <279970382+edenbuilds@users.noreply.github.com>
2026-08-10 12:11:59 -07:00
github-actions[bot] 5f9915234a chore: version packages (#2655)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-api@1.4.4

### Patch Changes

- [#2645](https://github.com/langchain-ai/langgraphjs/pull/2645)
[`059f3b8`](https://github.com/langchain-ai/langgraphjs/commit/059f3b8200d1f2f6bd701eb26bac24675395918a)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-api): stop wiping graph recursionLimit with undefined

  When a run omitted `config.recursion_limit`, the server still passed
`recursionLimit: undefined` into `streamEvents`. Pregel spreads that
over the
graph's `withConfig` default, so agents fell back to langchain-core's
25.
  Omit undefined keys so bound limits (and deepagents' 10000) stick.

- Updated dependencies
[[`059f3b8`](https://github.com/langchain-ai/langgraphjs/commit/059f3b8200d1f2f6bd701eb26bac24675395918a)]:
  - @langchain/langgraph-ui@1.4.4
## @langchain/langgraph-cli@1.4.4

### Patch Changes

- [#2645](https://github.com/langchain-ai/langgraphjs/pull/2645)
[`059f3b8`](https://github.com/langchain-ai/langgraphjs/commit/059f3b8200d1f2f6bd701eb26bac24675395918a)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-api): stop wiping graph recursionLimit with undefined

  When a run omitted `config.recursion_limit`, the server still passed
`recursionLimit: undefined` into `streamEvents`. Pregel spreads that
over the
graph's `withConfig` default, so agents fell back to langchain-core's
25.
  Omit undefined keys so bound limits (and deepagents' 10000) stick.

- Updated dependencies
[[`059f3b8`](https://github.com/langchain-ai/langgraphjs/commit/059f3b8200d1f2f6bd701eb26bac24675395918a)]:
  - @langchain/langgraph-api@1.4.4
## @langchain/langgraph@1.4.9

### Patch Changes

- [#2653](https://github.com/langchain-ai/langgraphjs/pull/2653)
[`7880055`](https://github.com/langchain-ai/langgraphjs/commit/7880055ac7303483e424380cdd52f54cd094e311)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): checkpoint Topic as a flat values list

Match Python Topic checkpoints so Host JS graphs no longer put
`__pregel_tasks: [[], []]` through the Python checkpointer. Keep reading
legacy `[seen, values]` checkpoints for restore compatibility.
## @langchain/langgraph-ui@1.4.4

### Patch Changes

- [#2645](https://github.com/langchain-ai/langgraphjs/pull/2645)
[`059f3b8`](https://github.com/langchain-ai/langgraphjs/commit/059f3b8200d1f2f6bd701eb26bac24675395918a)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-api): stop wiping graph recursionLimit with undefined

  When a run omitted `config.recursion_limit`, the server still passed
`recursionLimit: undefined` into `streamEvents`. Pregel spreads that
over the
graph's `withConfig` default, so agents fell back to langchain-core's
25.
  Omit undefined keys so bound limits (and deepagents' 10000) stick.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-03 16:20:31 -07:00
Christian Bromann 7880055ac7 fix(langgraph): checkpoint Topic as a flat values list (#2653)
Topic checkpoints now emit a flat values list like Python, so Host no
longer sees empty `__pregel_tasks` as `[[], []]` and fails
checkpointer_put. Legacy `[seen, values]` checkpoints still restore.

## Test plan
- [x] `pnpm test src/tests/channels.test.ts` (langgraph-core)
- [x] `pnpm exec vitest run src/tests/pregel.test.ts -t 'obtain correct
channel values|PregelExecutableTasks'`
- [x] Changeset added for affected package(s)
2026-08-03 16:11:21 -07:00
Christian Bromann 059f3b8200 fix(langgraph-api): stop wiping graph recursionLimit with undefined (#2645)
When a run omitted `config.recursion_limit`, we still passed
`recursionLimit: undefined` into `streamEvents`. Pregel merges that over
the graph's `withConfig` default, so agents (including deepagents with a
bound 10000) fell back to langchain-core's 25 and hit
`GraphRecursionError` early.

Omit undefined keys from stream/assistant config objects so bound limits
stick.

## Test plan
- [x] `pnpm test tests/stream.test.mts` in `libs/langgraph-api` (8
passed)
- [x] Changeset added for affected package(s)
2026-08-03 16:03:57 -07:00
github-actions[bot] 483e6df5ea chore: version packages (#2621)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-sdk@1.9.28

### Patch Changes

- [#2622](https://github.com/langchain-ai/langgraphjs/pull/2622)
[`cf2407a`](https://github.com/langchain-ai/langgraphjs/commit/cf2407a31657a8308312873a13863f496b34f3ca)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): clear hydrate interrupt allowlist on respond()

`submit()` already cleared `#hydratedActiveInterruptIds` so a new run's
live `input.requested` events were not dropped as historical.
`respond()` / `respondAll()` (via `dispatchResume`) did not, so a
follow-on HITL after resume never appeared on `stream.interrupt` and
free-text submits could resume with the wrong payload.

- [#2613](https://github.com/langchain-ai/langgraphjs/pull/2613)
[`82a320f`](https://github.com/langchain-ai/langgraphjs/commit/82a320faf6876238f8bac8aa6a7c593bef2be061)
Thanks [@sreeramsama](https://github.com/sreeramsama)! - Fix `useStream`
crash (`TypeError: Cannot read properties of null (reading 'fetch')`)
when a thread is cleared while hydration is in flight. The stale hydrate
now bails immediately after the `getState()` await — it no longer
applies the fetched state to the thread that was left, nor opens a
reconnect via `threads.stream(null, …)`.
## @langchain/angular@1.0.29

### Patch Changes

- Updated dependencies
[[`cf2407a`](https://github.com/langchain-ai/langgraphjs/commit/cf2407a31657a8308312873a13863f496b34f3ca),
[`82a320f`](https://github.com/langchain-ai/langgraphjs/commit/82a320faf6876238f8bac8aa6a7c593bef2be061)]:
  - @langchain/langgraph-sdk@1.9.28
## @langchain/react@1.0.29

### Patch Changes

- Updated dependencies
[[`cf2407a`](https://github.com/langchain-ai/langgraphjs/commit/cf2407a31657a8308312873a13863f496b34f3ca),
[`82a320f`](https://github.com/langchain-ai/langgraphjs/commit/82a320faf6876238f8bac8aa6a7c593bef2be061)]:
  - @langchain/langgraph-sdk@1.9.28
## @langchain/svelte@1.0.29

### Patch Changes

- Updated dependencies
[[`cf2407a`](https://github.com/langchain-ai/langgraphjs/commit/cf2407a31657a8308312873a13863f496b34f3ca),
[`82a320f`](https://github.com/langchain-ai/langgraphjs/commit/82a320faf6876238f8bac8aa6a7c593bef2be061)]:
  - @langchain/langgraph-sdk@1.9.28
## @langchain/vue@1.0.29

### Patch Changes

- Updated dependencies
[[`cf2407a`](https://github.com/langchain-ai/langgraphjs/commit/cf2407a31657a8308312873a13863f496b34f3ca),
[`82a320f`](https://github.com/langchain-ai/langgraphjs/commit/82a320faf6876238f8bac8aa6a7c593bef2be061)]:
  - @langchain/langgraph-sdk@1.9.28

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-21 15:53:00 -07:00
Christian Bromann cf2407a316 fix(sdk): clear hydrate interrupt allowlist on respond() (#2622)
## Summary
- Clear the hydrate-window interrupt allowlist in `dispatchResume()`
(same as `submit()`), so `respond()` / `respondAll()` accept genuinely
new live `input.requested` events from the resumed run.
- Without this, a second HITL after answering the first never appeared
on `stream.interrupt`, and clients could free-text `submit` into an
implicit resume with the wrong payload (`KeyError: 'decisions'` on HITL
middleware).
- Add a regression test covering hydrate → `respond()` → follow-on
interrupt id.
2026-07-21 15:49:43 -07:00
Sreeram Sama 82a320faf6 fix(sdk): guard useStream hydrate reconnect against a cleared thread id (#2613)
## Summary

`useStream`'s mount-time **hydrate → reconnect** path can call
`client.threads.stream(null, …)` when the thread id is cleared while
hydration is in flight, throwing an uncaught `TypeError: Cannot read
properties of null (reading 'fetch')`. This adds a post-`await` guard in
the controller (root cause) and makes `ThreadsClient.stream` null-safe
at the boundary (defense-in-depth), plus a regression test.

## Root cause

`StreamController.hydrate()` null-guards `#currentThreadId` **before**
the `await`, then re-reads it **after** to open the reconnect, with no
re-check in between:

```ts
// controller.ts
if (this.#currentThreadId == null) { …; return; }   // guard BEFORE await (L538)
…
const state = await this.#fetchHydrationState();      // getState() — async gap (L564)
…
const thread = this.#ensureThread(this.#currentThreadId, !threadActive);  // L731, no re-check
```

`#ensureThread` forwards the id to `client.threads.stream(threadId, {
fetch, … })`. If `#currentThreadId` becomes `null` **during the await**
(the host clears the id, `hydrate(null)` runs, or the component unmounts
during navigation), `hydrate` resumes and calls `threads.stream(null,
{…})`. In `ThreadsClient.stream`, a non-string first arg is treated as
the **options** object, so `null` becomes `options` and `options.fetch`
throws:

```ts
// client/threads/index.ts
const { threadId, options } = typeof threadIdOrOptions === "string"
  ? { threadId: threadIdOrOptions, options: maybeOptions }
  : { threadId: uuidv7(), options: threadIdOrOptions };  // null ⇒ options = null
const userFetch = options.fetch;                          // null.fetch → throw
```

## Why it's intermittent

The null has to land inside the narrow `await #fetchHydrationState()`
window, and only for an **active** thread (idle/finished threads take
the deferred path and skip `#ensureThread`). It needs a concurrent
thread-id clear (navigation/unmount) racing an in-flight hydrate — so
it's flaky, not deterministic.

## Changes

- **`stream/controller.ts` (root fix):** re-check `this.#disposed` /
`this.#currentThreadId != null` after the `await`, before
`#ensureThread(...)`. Hydration is already settled by then, so an early
return is safe. Mirrors the existing post-await guard idiom (e.g.
`controller.ts` discovery-seed path).
- **`client/threads/index.ts` (defense-in-depth):** treat a nullish
first arg as the generate-thread-id form (use the second arg as options)
instead of binding `null` to `options`.
- **`stream/controller.test.ts`:** regression test — `getState()`
resolves *after* the thread id is cleared mid-hydrate; asserts the
reconnect is never opened with a null id.

## Risk

Low. The controller guard only early-returns when there's no thread to
reconnect. The `stream` overload change preserves behavior for the
string- and object-first calls; it only fixes the nullish-first-arg
case.

## How it was found

Surfaced as a flaky teardown `pageerror` in a downstream app's
Playwright E2E (agent editor: create → chat → delete). Confirmed against
`@langchain/langgraph-sdk@1.9.27` and reproduced on `main` (this
branch).

## Notes for reviewers

- Opened as **draft**: the regression test was authored to match
existing `controller.test.ts` conventions but **not run** in my
environment (SDK deps weren't installed) — please verify it in CI /
locally.
- Either change fixes the reported crash on its own; the
`threads.stream` hardening is optional but cheap.
2026-07-21 15:02:41 -07:00
github-actions[bot] afb42cd7fe chore: version packages (#2607)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-sdk@1.9.27

### Patch Changes

- [#2606](https://github.com/langchain-ai/langgraphjs/pull/2606)
[`fa4658c`](https://github.com/langchain-ai/langgraphjs/commit/fa4658c79489eb5fb3e38744c34a6f5bf2373831)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): omit carried `since` on SSE reconnect

Protocol `seq` is connection-scoped: a new `POST /stream/events`
re-numbers Redis replay from 1, so advancing `since` from observed seqs
and sending it after a successful open filtered out the full history
(heartbeats only). An explicit caller `since` is still sent until the
stream connects (including pre-ready retries); post-connect reconnects
omit `since` and rely on durable `event_id` dedup.
## @langchain/angular@1.0.28

### Patch Changes

- Updated dependencies
[[`fa4658c`](https://github.com/langchain-ai/langgraphjs/commit/fa4658c79489eb5fb3e38744c34a6f5bf2373831)]:
  - @langchain/langgraph-sdk@1.9.27
## @langchain/react@1.0.28

### Patch Changes

- Updated dependencies
[[`fa4658c`](https://github.com/langchain-ai/langgraphjs/commit/fa4658c79489eb5fb3e38744c34a6f5bf2373831)]:
  - @langchain/langgraph-sdk@1.9.27
## @langchain/svelte@1.0.28

### Patch Changes

- Updated dependencies
[[`fa4658c`](https://github.com/langchain-ai/langgraphjs/commit/fa4658c79489eb5fb3e38744c34a6f5bf2373831)]:
  - @langchain/langgraph-sdk@1.9.27
## @langchain/vue@1.0.28

### Patch Changes

- Updated dependencies
[[`fa4658c`](https://github.com/langchain-ai/langgraphjs/commit/fa4658c79489eb5fb3e38744c34a6f5bf2373831)]:
  - @langchain/langgraph-sdk@1.9.27

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-15 11:21:35 -07:00
Christian Bromann fa4658c794 fix(sdk): omit since on SSE reconnect (#2606)
## Summary
- Stop sending body `since` on SSE (re)connect in
`ProtocolSseTransportAdapter`.
- Protocol `seq` is connection-scoped; a new POST re-numbers Redis
history from 1, so a prior session's `since` (e.g. `146`) dropped the
entire replay and left only heartbeats after QUIC/idle drops.
- Clients continue to deduplicate via durable `event_id`. A durable
cursor can replace this later.
2026-07-15 10:58:05 -07:00
github-actions[bot] 3dccad1391 chore: version packages (#2603)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-api@1.4.3

### Patch Changes

- Updated dependencies []:
  - @langchain/langgraph-ui@1.4.3
## @langchain/langgraph-cli@1.4.3

### Patch Changes

- [#2595](https://github.com/langchain-ai/langgraphjs/pull/2595)
[`dac8c2f`](https://github.com/langchain-ai/langgraphjs/commit/dac8c2fa7edfd643aa393a1d6407759b6cd8acf4)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
chore: bump langsmith to ^0.8.0

- Updated dependencies []:
  - @langchain/langgraph-api@1.4.3
## @langchain/langgraph@1.4.8

### Patch Changes

- [#2604](https://github.com/langchain-ai/langgraphjs/pull/2604)
[`42ec394`](https://github.com/langchain-ai/langgraphjs/commit/42ec39460bfe0c3be017fb043c668c3204c8a175)
Thanks [@hntrl](https://github.com/hntrl)! - fix(pregel): wait for
completed-superstep persistence with sync durability

- Updated dependencies
[[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa),
[`c201256`](https://github.com/langchain-ai/langgraphjs/commit/c201256b27d55c9aa333d3d15f6ec16c2fd7de9b)]:
  - @langchain/langgraph-sdk@1.9.26
## @langchain/langgraph-sdk@1.9.26

### Patch Changes

- [#2605](https://github.com/langchain-ai/langgraphjs/pull/2605)
[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): keep SSE reconnect enabled with custom fetch

Auth/proxy fetch shims previously forced `maxReconnectAttempts: 0`, so
HITL waits that lost `/stream/events` (e.g. `ERR_QUIC_PROTOCOL_ERROR`)
never recovered and left `respond()`/`submit()` spinning. Fail-fast test
mocks should pass `maxReconnectAttempts: 0` explicitly. Also plumbs
reconnect options through framework `useStream` bindings.

- [#2602](https://github.com/langchain-ai/langgraphjs/pull/2602)
[`c201256`](https://github.com/langchain-ai/langgraphjs/commit/c201256b27d55c9aa333d3d15f6ec16c2fd7de9b)
Thanks [@HugoDurand](https://github.com/HugoDurand)! - fix(sdk): support
clearing a cron's end time via `crons.update(cronId, { endTime: null })`

`CronsClient.update` now accepts `endTime: null` to clear a previously
set cron end time; omitting `endTime` still leaves it unchanged. The
field was typed `string`, so callers could not express "clear" even
though the request already forwards an explicit `null`.
## @langchain/angular@1.0.27

### Patch Changes

- [#2605](https://github.com/langchain-ai/langgraphjs/pull/2605)
[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): keep SSE reconnect enabled with custom fetch

Auth/proxy fetch shims previously forced `maxReconnectAttempts: 0`, so
HITL waits that lost `/stream/events` (e.g. `ERR_QUIC_PROTOCOL_ERROR`)
never recovered and left `respond()`/`submit()` spinning. Fail-fast test
mocks should pass `maxReconnectAttempts: 0` explicitly. Also plumbs
reconnect options through framework `useStream` bindings.

- Updated dependencies
[[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa),
[`c201256`](https://github.com/langchain-ai/langgraphjs/commit/c201256b27d55c9aa333d3d15f6ec16c2fd7de9b)]:
  - @langchain/langgraph-sdk@1.9.26
## @langchain/react@1.0.27

### Patch Changes

- [#2605](https://github.com/langchain-ai/langgraphjs/pull/2605)
[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): keep SSE reconnect enabled with custom fetch

Auth/proxy fetch shims previously forced `maxReconnectAttempts: 0`, so
HITL waits that lost `/stream/events` (e.g. `ERR_QUIC_PROTOCOL_ERROR`)
never recovered and left `respond()`/`submit()` spinning. Fail-fast test
mocks should pass `maxReconnectAttempts: 0` explicitly. Also plumbs
reconnect options through framework `useStream` bindings.

- Updated dependencies
[[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa),
[`c201256`](https://github.com/langchain-ai/langgraphjs/commit/c201256b27d55c9aa333d3d15f6ec16c2fd7de9b)]:
  - @langchain/langgraph-sdk@1.9.26
## @langchain/svelte@1.0.27

### Patch Changes

- [#2605](https://github.com/langchain-ai/langgraphjs/pull/2605)
[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): keep SSE reconnect enabled with custom fetch

Auth/proxy fetch shims previously forced `maxReconnectAttempts: 0`, so
HITL waits that lost `/stream/events` (e.g. `ERR_QUIC_PROTOCOL_ERROR`)
never recovered and left `respond()`/`submit()` spinning. Fail-fast test
mocks should pass `maxReconnectAttempts: 0` explicitly. Also plumbs
reconnect options through framework `useStream` bindings.

- Updated dependencies
[[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa),
[`c201256`](https://github.com/langchain-ai/langgraphjs/commit/c201256b27d55c9aa333d3d15f6ec16c2fd7de9b)]:
  - @langchain/langgraph-sdk@1.9.26
## @langchain/vue@1.0.27

### Patch Changes

- [#2605](https://github.com/langchain-ai/langgraphjs/pull/2605)
[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): keep SSE reconnect enabled with custom fetch

Auth/proxy fetch shims previously forced `maxReconnectAttempts: 0`, so
HITL waits that lost `/stream/events` (e.g. `ERR_QUIC_PROTOCOL_ERROR`)
never recovered and left `respond()`/`submit()` spinning. Fail-fast test
mocks should pass `maxReconnectAttempts: 0` explicitly. Also plumbs
reconnect options through framework `useStream` bindings.

- Updated dependencies
[[`f326b89`](https://github.com/langchain-ai/langgraphjs/commit/f326b89365043bfa846e0b428564bcafafab4aaa),
[`c201256`](https://github.com/langchain-ai/langgraphjs/commit/c201256b27d55c9aa333d3d15f6ec16c2fd7de9b)]:
  - @langchain/langgraph-sdk@1.9.26
## @langchain/langgraph-ui@1.4.3

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-14 21:47:29 -07:00
Christian Bromann f326b89365 fix(sdk): keep SSE reconnect enabled with custom fetch (#2605)
## Summary
- Keep SSE auto-reconnect and idle-reconnect enabled when a custom
`fetch` is supplied (auth/proxy shims), instead of silently forcing
`maxReconnectAttempts: 0`.
- Plumb `maxReconnectAttempts`, `streamIdleReconnect`,
`reconnectDelayMs`, and `onReconnect` through `StreamController` and
React/Vue/Svelte/Angular `useStream`.
- Add transport unit coverage plus browser interrupt tests that drop
`/stream/events` mid-HITL and assert `respond()` still completes.
2026-07-14 21:45:12 -07:00
Hunter Lovell 42ec39460b fix(core): enforce sync durability barriers (#2604)
## Summary

Makes `durability: "sync"` enforce its superstep boundary: persistence
produced by a completed superstep must settle before the scheduler
prepares and dispatches the next one. Previously, persistence was
tracked and awaited at final cleanup but could overlap later supersteps.

## Changes

- Snapshot and await the current run's tracked `putWrites()` and ordered
checkpoint `put()` promises after each completed superstep when
durability is `sync`.
- Preserve asynchronous and exit-only durability behavior, including the
existing final persistence settlement path.
- Add gated `StateGraph` regression coverage for `invoke`, `stream`, and
`streamEvents`, plus coverage that async mode may progress while
persistence is pending.
- Add a patch changeset for `@langchain/langgraph`.
2026-07-14 19:12:09 -07:00
Christian Bromann dac8c2fa7e chore: bump langsmith to ^0.8.0 (#2595)
## Description

The langsmith SDK published v0.8.0. This updates the `langsmith`
dependency in the workspaces that pin it via a caret range
(`langgraph-cli`) to `^0.8.0` and refreshes `pnpm-lock.yaml` so the
workspace packages resolve to `0.8.0`. The broad peer/dependency range
in `langgraph-api` (`>=0.5.19 <1.0.0`) already permits `0.8.0` and is
left unchanged, matching prior langsmith bump PRs. Transitive
`langsmith` versions pulled in by published `@langchain/*` packages are
left untouched.

## Test Plan
- [ ] `pnpm install --frozen-lockfile` resolves without changes

Made by [Open
SWE](https://openswe.vercel.app/agents/019f436f-3343-7169-a06a-5f64fe70e3af)

---------

Signed-off-by: Christian Bromann <git@bromann.dev>
Co-authored-by: Christian Bromann <731337+christian-bromann@users.noreply.github.com>
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-14 14:08:13 -07:00
Hugo DURAND c201256b27 fix(sdk): support clearing cron end_time via update({ endTime: null }) (#2602)
## What & why

`CronsClient.update` could not clear a cron's `end_time`. The field was
typed `endTime?: string`, so a type-checked caller had no way to express
"remove the end time" — even though, unlike the Python SDK, the JS
request builder was already correct at runtime: it uses per-field `if
(payload?.endTime !== undefined)` guards (not a `None`-strip), and `null
!== undefined`, so a `null` would already be forwarded and
`JSON.stringify` preserves it.

So the defect was purely a **type imprecision**, and the fix is at the
source — the model — rather than a workaround in the request logic:

- `CronsUpdatePayload.endTime`: `string` → `string | null`. PATCH
semantics are now the standard tri-state:
  - **omit `endTime`** → keep the existing value
  - **`endTime: null`** → clear it
  - **`endTime: "<iso>"`** → set it
- `CronsCreatePayload.endTime` is intentionally left `string` — create
never needs to clear.

This mirrors the Python SDK change in langchain-ai/langgraph#8334
(`update(end_time=None)`), and requires an Agent Server that supports
clearing `end_time` via `PATCH /runs/crons/{id}` (`end_time: null`).
Against an older server, `update(id, { endTime: null })` is a harmless
no-op for clearing (the server coalesces `null` back to the stored
value), and a clear-only patch may 400.

## Also in this PR (unify `update()`)

While here, `update()`'s payload construction is unified with the
existing `create()` / `createForThread()` style: the 16 repetitive `if
(payload?.X !== undefined) json.Y = payload.X` guards become a single
declarative object literal. `JSON.stringify` drops `undefined` keys and
keeps `null`, so the wire output is **identical** — this is a
behaviour-preserving refactor, pinned by the pre-existing "only sends
defined fields" / "sends all updatable fields" tests. Net −44 lines in
the method.

## Test plan

- [x] `vitest run` on `libs/sdk/src/client/crons/index.test.ts` — **9
passed** (8 existing + 1 new: `update(id, { endTime: null })` sends body
`{ end_time: null }`), no type errors.
- [x] `pnpm build` (tsc compile + `attw` + `publint`) — clean.
- [x] `oxlint` — 0 warnings / 0 errors; `oxfmt --check` — clean.
- [x] Changeset added (`@langchain/langgraph-sdk`: patch).
2026-07-14 13:05:05 -04:00
github-actions[bot] 96876a4bf0 chore: version packages (#2583)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-api@1.4.2

### Patch Changes

- [#2590](https://github.com/langchain-ai/langgraphjs/pull/2590)
[`f71e00c`](https://github.com/langchain-ai/langgraphjs/commit/f71e00c52600a6dafacccdde1363e83c17c8d97b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(api): inject langgraph_auth_user on protocol-v2 run.start

Stamp authenticated user fields onto run config in createOrResumeRun so
v2 streaming matches the REST runs API. Shared helpers also dedupe REST
  run config auth/header enrichment.

- [#2575](https://github.com/langchain-ai/langgraphjs/pull/2575)
[`e1b40c2`](https://github.com/langchain-ai/langgraphjs/commit/e1b40c29e14f8e9fb2696acc62d611e14a813f43)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(cli): support node_version 24 in langgraph.json

Allow Node 24 in the CLI config schema and Docker base image resolution.
  The langgraphjs-api:24 image is already published from langgraph-api.

- Updated dependencies
[[`f71e00c`](https://github.com/langchain-ai/langgraphjs/commit/f71e00c52600a6dafacccdde1363e83c17c8d97b),
[`e1b40c2`](https://github.com/langchain-ai/langgraphjs/commit/e1b40c29e14f8e9fb2696acc62d611e14a813f43)]:
  - @langchain/langgraph-ui@1.4.2
## @langchain/langgraph-cli@1.4.2

### Patch Changes

- [#2590](https://github.com/langchain-ai/langgraphjs/pull/2590)
[`f71e00c`](https://github.com/langchain-ai/langgraphjs/commit/f71e00c52600a6dafacccdde1363e83c17c8d97b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(api): inject langgraph_auth_user on protocol-v2 run.start

Stamp authenticated user fields onto run config in createOrResumeRun so
v2 streaming matches the REST runs API. Shared helpers also dedupe REST
  run config auth/header enrichment.

- [#2575](https://github.com/langchain-ai/langgraphjs/pull/2575)
[`e1b40c2`](https://github.com/langchain-ai/langgraphjs/commit/e1b40c29e14f8e9fb2696acc62d611e14a813f43)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(cli): support node_version 24 in langgraph.json

Allow Node 24 in the CLI config schema and Docker base image resolution.
  The langgraphjs-api:24 image is already published from langgraph-api.

- Updated dependencies
[[`f71e00c`](https://github.com/langchain-ai/langgraphjs/commit/f71e00c52600a6dafacccdde1363e83c17c8d97b),
[`e1b40c2`](https://github.com/langchain-ai/langgraphjs/commit/e1b40c29e14f8e9fb2696acc62d611e14a813f43)]:
  - @langchain/langgraph-api@1.4.2
## @langchain/langgraph-ui@1.4.2

### Patch Changes

- [#2590](https://github.com/langchain-ai/langgraphjs/pull/2590)
[`f71e00c`](https://github.com/langchain-ai/langgraphjs/commit/f71e00c52600a6dafacccdde1363e83c17c8d97b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(api): inject langgraph_auth_user on protocol-v2 run.start

Stamp authenticated user fields onto run config in createOrResumeRun so
v2 streaming matches the REST runs API. Shared helpers also dedupe REST
  run config auth/header enrichment.

- [#2575](https://github.com/langchain-ai/langgraphjs/pull/2575)
[`e1b40c2`](https://github.com/langchain-ai/langgraphjs/commit/e1b40c29e14f8e9fb2696acc62d611e14a813f43)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(cli): support node_version 24 in langgraph.json

Allow Node 24 in the CLI config schema and Docker base image resolution.
  The langgraphjs-api:24 image is already published from langgraph-api.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-05 17:58:08 -07:00
Christian Bromann f71e00c526 fix(api): inject langgraph_auth_user on protocol-v2 run.start (#2590)
## Summary
- Inject `langgraph_auth_user`, `langgraph_auth_user_id`, and
`langgraph_auth_permissions` into run config in protocol v2
`createOrResumeRun`, matching the REST `createValidRun` behavior.
- Extract shared `applyAuthToRunConfig` /
`applyRequestHeadersToRunConfig` helpers and use them from both REST and
protocol paths.
- Pass `userId` into `runs.put()` from the protocol path for parity with
REST.
2026-07-05 17:55:52 -07:00
Christian Bromann e1b40c29e1 fix(cli): support node_version 24 in langgraph.json (#2575)
## Summary
- Add `"24"` to `NodeVersionSchema` in `@langchain/langgraph-cli` so
`node_version: "24"` is accepted in `langgraph.json`.
- Add config, `getBaseImage`, and `configToDocker` tests for Node 24 tag
resolution (`langchain/langgraphjs-api:24` and `{api_version}-node24`).
- Update CLI README to document supported Node versions (`"20"`, `"22"`,
`"24"`).
2026-06-29 20:10:24 -07:00
Christian Bromann ad7f9beb1e fix(ci): ignore example packages globbing the changelog 2026-06-25 16:40:40 -07:00
github-actions[bot] 2174637623 chore: version packages (#2572)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph@1.4.7

### Patch Changes

- [#2571](https://github.com/langchain-ai/langgraphjs/pull/2571)
[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): drop unused zod-to-json-schema peer dependency

Remove the vestigial `zod-to-json-schema` (and its
`peerDependenciesMeta`/dev) declarations. JSON Schema generation now
flows through `@langchain/core`'s Zod v3/v4 interop (`toJsonSchema`), so
the old `zod-to-json-schema@^3.x` peer (which pins `zod@^3.24.1`) is no
longer needed and was the last source of install-time peer conflicts
with Zod v4. Closes
[#1706](https://github.com/langchain-ai/langgraphjs/issues/1706).

## @example/ai-elements@0.1.43

### Patch Changes

- Updated dependencies
\[[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)]:
    -   @langchain/langgraph@1.4.7

## @examples/assistant-ui-claude@0.1.43

### Patch Changes

- Updated dependencies
\[[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)]:
    -   @langchain/langgraph@1.4.7

## @examples/ui-angular@0.0.53

### Patch Changes

- Updated dependencies
\[[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)]:
    -   @langchain/langgraph@1.4.7

## @examples/ui-multimodal@0.0.29

### Patch Changes

- Updated dependencies
\[[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)]:
    -   @langchain/langgraph@1.4.7

## @examples/ui-react@0.0.29

### Patch Changes

- Updated dependencies
\[[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)]:
    -   @langchain/langgraph@1.4.7

## langgraph@1.0.47

### Patch Changes

- Updated dependencies
\[[`85ba859`](https://github.com/langchain-ai/langgraphjs/commit/85ba859b6f60f4bf193d3313fa24149efe05491b)]:
    -   @langchain/langgraph@1.4.7

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-25 14:47:39 -07:00
Christian Bromann 85ba859b6f fix(langgraph): drop unused zod-to-json-schema dependency (#2571)
## Summary
- Remove the vestigial `zod-to-json-schema` peer/dev dependency from
`@langchain/langgraph` (`libs/langgraph-core`) and the `langgraph`
umbrella package. Nothing in source imports it anymore — graph JSON
Schema generation flows through `@langchain/core/utils/json_schema`'s
`toJsonSchema`, which uses Zod v4's native `toJSONSchema` with a v3
fallback.
- This was the last remaining `zod@^3.24.1` peer constraint, which is
what produced the install-time conflict with Zod v4 reported in #1706.
- Prune the unused `zod-to-json-schema` declaration from 6 example
projects (`multi_agent`, `chatbot-simulation-evaluation`, `reflection`,
`rewoo`, `plan-and-execute`, `quickstart`) that declared but never used
it. Kept it in `rag`, `how-tos`, and `chatbots`, whose notebooks
genuinely call `zodToJsonSchema`.
- Regenerate `pnpm-lock.yaml`.

Fixes #1706
2026-06-25 11:06:46 -07:00
github-actions[bot] 86389fa3a6 chore: version packages (#2567)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-checkpoint@1.1.3

### Patch Changes

- [#2566](https://github.com/langchain-ai/langgraphjs/pull/2566)
[`091a46f`](https://github.com/langchain-ai/langgraphjs/commit/091a46f32ddd3a85ee89e35fb9ea953dfc4cf8b4)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-checkpoint-postgres): prevent createAgent failures with
PostgresSaver

Add BaseCheckpointSaver.toJSON() so ConfigurableModel can stringify
runnable config without traversing pg Pool timers, and default missing
checkpoint maps on load/copy so resume no longer crashes on undefined
versions_seen. Closes
[#1808](https://github.com/langchain-ai/langgraphjs/issues/1808).

## @langchain/langgraph-checkpoint-postgres@1.0.4

### Patch Changes

- [#2566](https://github.com/langchain-ai/langgraphjs/pull/2566)
[`091a46f`](https://github.com/langchain-ai/langgraphjs/commit/091a46f32ddd3a85ee89e35fb9ea953dfc4cf8b4)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-checkpoint-postgres): prevent createAgent failures with
PostgresSaver

Add BaseCheckpointSaver.toJSON() so ConfigurableModel can stringify
runnable config without traversing pg Pool timers, and default missing
checkpoint maps on load/copy so resume no longer crashes on undefined
versions_seen. Closes
[#1808](https://github.com/langchain-ai/langgraphjs/issues/1808).

## @langchain/langgraph-api@1.4.1

### Patch Changes

- [#2568](https://github.com/langchain-ai/langgraphjs/pull/2568)
[`38d15e2`](https://github.com/langchain-ai/langgraphjs/commit/38d15e2f1f9dded34665a602cd9311cbcf5fbefc)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-api): support configurable TypeScript loaders in dev
server

Add `node_loader` to `langgraph.json` (and `LANGGRAPH_NODE_LOADER` env
override) so projects using reflect-metadata can use `ts-node`
(`--loader ts-node/esm`) instead of the default tsx CLI. Other loaders
default to `--import`; only registered shorthands like `ts-node` use
`--loader`. `--no-reload` now also disables tsx's internal watch mode.
Closes [#1834](https://github.com/langchain-ai/langgraphjs/issues/1834).

-   Updated dependencies \[]:
    -   @langchain/langgraph-ui@1.4.1

## @langchain/langgraph-cli@1.4.1

### Patch Changes

- [#2568](https://github.com/langchain-ai/langgraphjs/pull/2568)
[`38d15e2`](https://github.com/langchain-ai/langgraphjs/commit/38d15e2f1f9dded34665a602cd9311cbcf5fbefc)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-api): support configurable TypeScript loaders in dev
server

Add `node_loader` to `langgraph.json` (and `LANGGRAPH_NODE_LOADER` env
override) so projects using reflect-metadata can use `ts-node`
(`--loader ts-node/esm`) instead of the default tsx CLI. Other loaders
default to `--import`; only registered shorthands like `ts-node` use
`--loader`. `--no-reload` now also disables tsx's internal watch mode.
Closes [#1834](https://github.com/langchain-ai/langgraphjs/issues/1834).

- Updated dependencies
\[[`38d15e2`](https://github.com/langchain-ai/langgraphjs/commit/38d15e2f1f9dded34665a602cd9311cbcf5fbefc)]:
    -   @langchain/langgraph-api@1.4.1

## @langchain/langgraph@1.4.6

### Patch Changes

-
[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): emit valid UUIDs for exit-mode delta task_ids

Exit-mode DeltaChannel writes used a step-prefixed synthetic task id
that produced a 6-segment string Postgres rejects for
`checkpoint_writes.task_id uuid` in LangGraph API. Embed the superstep
in the first UUID group instead, matching langchain-ai/langgraph#8165.

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457),
[`091a46f`](https://github.com/langchain-ai/langgraphjs/commit/091a46f32ddd3a85ee89e35fb9ea953dfc4cf8b4)]:
    -   @langchain/langgraph-sdk@1.9.25
    -   @langchain/langgraph-checkpoint@1.1.3

## @langchain/langgraph-sdk@1.9.25

### Patch Changes

- [#2565](https://github.com/langchain-ai/langgraphjs/pull/2565)
[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): bundle pure-ESM deps into CJS build to fix ERR_REQUIRE_ESM

Bundle the pure-ESM dependencies `p-retry` and `p-queue` (and their
transitive ESM-only deps) into the build output so the CJS artifact no
longer does a top-level `require()` of an ESM module. This fixes
`ERR_REQUIRE_ESM` for CommonJS consumers on Node versions where
`require(ESM)` is not enabled by default (&lt; 20.19 / &lt; 22.12).
Closes [#2562](https://github.com/langchain-ai/langgraphjs/issues/2562).

## @langchain/angular@1.0.26

### Patch Changes

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457)]:
    -   @langchain/langgraph-sdk@1.9.25

## @langchain/react@1.0.26

### Patch Changes

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457)]:
    -   @langchain/langgraph-sdk@1.9.25

## @langchain/svelte@1.0.26

### Patch Changes

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457)]:
    -   @langchain/langgraph-sdk@1.9.25

## @langchain/vue@1.0.26

### Patch Changes

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457)]:
    -   @langchain/langgraph-sdk@1.9.25

## @langchain/langgraph-ui@1.4.1



## @example/ai-elements@0.1.42

### Patch Changes

- Updated dependencies
\[[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)]:
    -   @langchain/langgraph@1.4.6
    -   @langchain/react@1.0.26

## @examples/assistant-ui-claude@0.1.42

### Patch Changes

- Updated dependencies
\[[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)]:
    -   @langchain/langgraph@1.4.6
    -   @langchain/react@1.0.26

## @examples/ui-angular@0.0.52

### Patch Changes

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457),
[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)]:
    -   @langchain/langgraph-sdk@1.9.25
    -   @langchain/langgraph@1.4.6
    -   @langchain/angular@1.0.26

## @examples/ui-multimodal@0.0.28

### Patch Changes

- Updated dependencies
\[[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)]:
    -   @langchain/langgraph@1.4.6
    -   @langchain/react@1.0.26

## @examples/ui-react@0.0.28

### Patch Changes

- Updated dependencies
\[[`0558e47`](https://github.com/langchain-ai/langgraphjs/commit/0558e472b7697304c62cb6fe69cc3005e8e1a457),
[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)]:
    -   @langchain/langgraph-sdk@1.9.25
    -   @langchain/langgraph@1.4.6
    -   @langchain/react@1.0.26

## langgraph@1.0.46

### Patch Changes

- Updated dependencies
\[[`03a0d8b`](https://github.com/langchain-ai/langgraphjs/commit/03a0d8b8632082e6dbf4a96fcf37f8f67151b74f)]:
    -   @langchain/langgraph@1.4.6

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-24 17:51:02 -07:00
Christian Bromann 03a0d8b863 fix(langgraph): emit valid UUIDs for exit-mode delta task_ids
Exit-mode DeltaChannel writes used a step-prefixed synthetic task id that
Postgres rejects for checkpoint_writes.task_id uuid in LangGraph API. Embed
the superstep in the first UUID group instead, matching langgraph#8165.
2026-06-23 18:31:07 -07:00
Christian Bromann 38d15e2f1f fix(langgraph-api): support configurable TypeScript loaders in dev server (#2568)
## Summary
- Add configurable TypeScript loader support for the in-memory dev
server to fix reflect-metadata / `emitDecoratorMetadata` incompatibility
with tsx (esbuild).
- Introduce `node_loader` on Node `langgraph.json` configs and
`LANGGRAPH_NODE_LOADER` env override; default remains `tsx` CLI watch
mode.
- Generalize non-tsx loaders to `node [--watch] --import <loader>
--import preload entrypoint`, with shorthand mapping for `ts-node` →
`ts-node/esm`.
- Add `spawn-args` helper + unit tests; add `ts-node` as optional peer
dependency of `@langchain/langgraph-api`.

Fixes #1834
2026-06-23 09:43:07 -07:00
Christian Bromann 091a46f32d fix(langgraph-checkpoint-postgres): prevent createAgent failures with PostgresSaver (#2566)
## Summary
- Add `BaseCheckpointSaver.toJSON()` so runnable
`configurable.__pregel_checkpointer` can be JSON-stringified without
traversing backend clients (fixes the circular `Timeout` error when
using `createAgent` with `PostgresSaver`).
- Harden `copyCheckpoint()` and `PostgresSaver._loadCheckpoint()` to
default missing `channel_versions` and `versions_seen` to `{}`, fixing
resume crashes on `__input__` after a failed first run.
- Add unit and integration tests covering stringify safety and missing
`versions_seen` recovery.

Fixes #1808
2026-06-22 15:23:18 -07:00
Christian Bromann 0558e472b7 fix(sdk): bundle pure-ESM deps into CJS build to fix ERR_REQUIRE_ESM (#2565)
## Summary
- Fix `ERR_REQUIRE_ESM` in `@langchain/langgraph-sdk` for CommonJS
consumers on Node < 20.19 / < 22.12: the CJS build no longer does a
top-level `require()` of the pure-ESM `p-retry`/`p-queue`. They (and
their transitive ESM-only deps) are now bundled and transpiled into
relative CJS chunks.
- Add per-package build overrides via an optional `tsdown.config.ts`,
mirroring the langchainjs convention. `internal/build` discovers and
merges it (`config: false` disables tsdown's own discovery so the
config's imports resolve from the package dir), and re-exports
`defineConfig` from `@langchain/build` so packages get type-safe configs
without depending on `tsdown` directly.
- Remove the leftover `libs/checkpoint-redis/langchain.config.js` (from
the old `@langchain/scripts` build) — it was the only package still
carrying one and the current tsdown build ignores it.

Fixes #2562
2026-06-22 14:56:09 -07:00
github-actions[bot] 31261c3be5 chore: version packages (#2558)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-checkpoint-mongodb@1.4.0

### Minor Changes

- [#1928](https://github.com/langchain-ai/langgraphjs/pull/1928)
[`3d7fcea`](https://github.com/langchain-ai/langgraphjs/commit/3d7fcea7d7ea7f1203d24be9df607d5a8e8717bc)
Thanks [@Mihailoff](https://github.com/Mihailoff)! - Add TTL support for
automatic checkpoint expiration

    -   Add optional `ttl` parameter to MongoDBSaver (value in seconds)
    -   Add `setup()` method to create TTL indexes on collections
    -   Add `upserted_at` timestamp to documents when TTL is enabled
- Each write refreshes TTL (expires after inactivity, not creation)

### Patch Changes

- [#2556](https://github.com/langchain-ai/langgraphjs/pull/2556)
[`bee3c91`](https://github.com/langchain-ai/langgraphjs/commit/bee3c91d0adc315ebde0622d8c4b1fff041c1bfd)
Thanks [@mohamedkhaled4053](https://github.com/mohamedkhaled4053)! - Fix
`MongoDBSaver.putWrites` throwing `MongoServerError: Invalid
BulkOperation, Batch cannot be empty` when called with an empty `writes`
array. This is reached by human-in-the-loop / `interrupt()` flows, where
a task can complete producing zero channel writes and LangGraph calls
`putWrites(config, [], taskId)`. `putWrites` now no-ops on empty writes,
matching the behavior of the postgres and sqlite savers (which iterate
and naturally skip empty batches).

- [#2550](https://github.com/langchain-ai/langgraphjs/pull/2550)
[`2b8cc2f`](https://github.com/langchain-ai/langgraphjs/commit/2b8cc2f3fd5c9d3c33b56e013292daf5d936428e)
Thanks [@lazydiv](https://github.com/lazydiv)! -
feat(checkpoint-mongodb): add setup() to create required indexes

## @langchain/langgraph-api@1.4.0

### Minor Changes

- [#2559](https://github.com/langchain-ai/langgraphjs/pull/2559)
[`48cbdd2`](https://github.com/langchain-ai/langgraphjs/commit/48cbdd23fdf29277530f6aa05c397c9902e81206)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
feat(langgraph-cli): add `deploy` command for LangSmith Deployment

Port the Python CLI's `langgraph deploy` workflow to
`@langchain/langgraph-cli`, including local and remote build paths,
deployment lifecycle subcommands (`list`, `revisions list`, `delete`,
`logs`), and host-backend client utilities with tests.

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph-api): preserve non-empty response_metadata on protocol-v2
state messages

The protocol-v2 state normalizer stripped `response_metadata` from
messages,
dropping data that HITL flows rely on — an interrupt's card is carried
on
    `AIMessage.response_metadata` (e.g. `{ cards: ... }`). Non-empty
    `response_metadata` is now retained so the card reaches the client.

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

- Updated dependencies
\[[`48cbdd2`](https://github.com/langchain-ai/langgraphjs/commit/48cbdd23fdf29277530f6aa05c397c9902e81206)]:
    -   @langchain/langgraph-ui@1.4.0

## @langchain/langgraph-cli@1.4.0

### Minor Changes

- [#2559](https://github.com/langchain-ai/langgraphjs/pull/2559)
[`48cbdd2`](https://github.com/langchain-ai/langgraphjs/commit/48cbdd23fdf29277530f6aa05c397c9902e81206)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
feat(langgraph-cli): add `deploy` command for LangSmith Deployment

Port the Python CLI's `langgraph deploy` workflow to
`@langchain/langgraph-cli`, including local and remote build paths,
deployment lifecycle subcommands (`list`, `revisions list`, `delete`,
`logs`), and host-backend client utilities with tests.

### Patch Changes

- Updated dependencies
\[[`48cbdd2`](https://github.com/langchain-ai/langgraphjs/commit/48cbdd23fdf29277530f6aa05c397c9902e81206),
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e),
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-api@1.4.0

## @langchain/langgraph-ui@1.4.0

### Minor Changes

- [#2559](https://github.com/langchain-ai/langgraphjs/pull/2559)
[`48cbdd2`](https://github.com/langchain-ai/langgraphjs/commit/48cbdd23fdf29277530f6aa05c397c9902e81206)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
feat(langgraph-cli): add `deploy` command for LangSmith Deployment

Port the Python CLI's `langgraph deploy` workflow to
`@langchain/langgraph-cli`, including local and remote build paths,
deployment lifecycle subcommands (`list`, `revisions list`, `delete`,
`logs`), and host-backend client utilities with tests.

## @langchain/langgraph@1.4.5

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24

## @langchain/langgraph-sdk@1.9.24

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

## @langchain/angular@1.0.25

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24

## @langchain/react@1.0.25

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24

## @langchain/svelte@1.0.25

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24

## @langchain/vue@1.0.25

### Patch Changes

- [#2557](https://github.com/langchain-ai/langgraphjs/pull/2557)
[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): apply state update and goto alongside interrupt resume

    `respond(decision, { update, goto })` now maps to LangGraph's
`Command(resume, update, goto)`, so a human-in-the-loop UI can commit a
state
update (e.g. push the interrupt card into state) in the **same
superstep** as
the resume — one checkpoint, no separate `updateState` write, no
flicker.
`@langchain/langgraph-api` forwards `update`/`goto` through
`input.respond`,
and `@langchain/core` message instances in `update` are serialized to
dicts
before transport, exactly like `submit()`. Bumps `@langchain/protocol`
to
    `^0.0.18` for the `Goto` type.

`respond`/`respondAll` also apply `update` **optimistically** (mirroring
`submit()`): the pushed messages paint immediately, with stable ids
minted so
the resumed run's echo reconciles them in place. Without this the
interrupt is
cleared the instant `respond()` dispatches while the pushed card only
reappears
a server round-trip later — so the card would flicker in that gap. The
optimistic state settles on the resumed run's terminal (pending → sent,
or
    rolled back on a failure before any echo).

User-initiated optimistic writes (`submit()` / `respond()` /
`respondAll()`) now
commit to the store **synchronously**, in the same tick as the
triggering event,
instead of being coalesced onto the next macrotask. This lets a
framework render
the pushed message in the **same commit** as any local UI state the
caller flips
alongside it (e.g. a HITL form swapping its inputs for the resolved
card), so the
card no longer blinks out for the one-macrotask window before the flush
lands.
    High-frequency streaming writes keep their macrotask coalescing.

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24

## @example/ai-elements@0.1.41

### Patch Changes

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/react@1.0.25
    -   @langchain/langgraph@1.4.5

## @examples/assistant-ui-claude@0.1.41

### Patch Changes

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/react@1.0.25
    -   @langchain/langgraph@1.4.5

## @examples/ui-angular@0.0.51

### Patch Changes

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24
    -   @langchain/angular@1.0.25
    -   @langchain/langgraph@1.4.5

## @examples/ui-multimodal@0.0.27

### Patch Changes

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/react@1.0.25
    -   @langchain/langgraph@1.4.5

## @examples/ui-react@0.0.27

### Patch Changes

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph-sdk@1.9.24
    -   @langchain/react@1.0.25
    -   @langchain/langgraph@1.4.5

## langgraph@1.0.45

### Patch Changes

- Updated dependencies
\[[`b1e856d`](https://github.com/langchain-ai/langgraphjs/commit/b1e856d987ac16148dc0872d1fecf70e659ef28e)]:
    -   @langchain/langgraph@1.4.5

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-22 11:40:07 -07:00
Christian Bromann 48cbdd23fd feat(langgraph-cli): add deploy command for LangSmith Deployment (#2559)
## Summary
- Add `langgraphjs deploy` to `@langchain/langgraph-cli`, porting the
Python CLI's LangSmith Deployment workflow for JS projects.
- Support local Docker build/push and remote source-archive upload
paths, plus `deploy list`, `deploy revisions list`, `deploy delete`, and
`deploy logs`.
- Introduce host-backend client, archive/ignore/output helpers, and unit
tests; wire the command into the CLI entrypoint and add the `ignore`
dependency.

Test on our deployment cookbook:
```
pnpm run deploy

> js-langsmith@0.1.0 deploy /Users/christian.bromann/Sites/LangChain/deployment-cookbook/js-langsmith
> langgraphjs deploy

Note: 'langgraphjs deploy' is in beta. Expect frequent updates and improvements.

Skipping reserved env var: LANGSMITH_API_KEY
Skipping reserved env var: LANGSMITH_TENANT_ID
Docker is installed but not running.
Start Docker and try again.
Using remote build instead.

1. Looking up deployment 'deployment-cookbook-agent'
   No deployment found. Will create.
2. Creating deployment 'deployment-cookbook-agent'
   Deployment ID: fc41ac21-0251-4caf-9f6b-e8e381520e59
3. Creating source archive
   Archive created (0.1 MB)
4. Requesting upload URL
5. Uploading source
   Uploading (0.1 MB)... 100%
6. Triggering remote build
   View status: https://smith.langchain.com/o/d7ca4f49-e65f-4c96-8d03-e1d713acb728/host/deployments/fc41ac21-0251-4caf-9f6b-e8e381520e59
   QUEUED... (9s)
   AWAITING_BUILD... (18s)
   BUILDING... (3m 13s)
   AWAITING_DEPLOY... (3m 32s)
   DEPLOYING... (4m 50s)
   Deployment successful!
   URL: https://deployment-cookbook-agent-3569d4ef8d405f40850d56230f67258b.us.langgraph.app
   View status: https://smith.langchain.com/o/d7ca4f49-e65f-4c96-8d03-e1d713acb728/host/deployments/fc41ac21-0251-4caf-9f6b-e8e381520e59
```
2026-06-22 09:30:50 -07:00
lazyDev 2b8cc2f3fd feat(checkpoint): add setup() to create required MongoDB indexes (#2550)
## Summary

Fixes #2551

`MongoDBSaver` queries `checkpoints` and `checkpoint_writes` collections
by `thread_id`, `checkpoint_ns`, and `checkpoint_id`, but never creates
indexes on these fields. As the collections grow, every `getTuple()`,
`list()`, and `putWrites()` call triggers a **full collection scan**.

In production with ~450K checkpoints and ~570K checkpoint_writes, this
caused:
- `getState` taking **5-10 seconds** per request (scanning all 450K docs
each time)
- Total API response times of **30-40 seconds** instead of **3 seconds**

### Changes

- Adds a `setup()` method to `MongoDBSaver` that creates a compound
index `{ thread_id: 1, checkpoint_ns: 1, checkpoint_id: -1 }` on both
collections
- The method is idempotent (`createIndex` is a no-op when the index
already exists), safe to call on every app start
- Follows the same pattern as `MongoDBStore.start()` which already
creates indexes

### Before / After (production, 450K checkpoints)

| Metric | Before | After |
|---|---|---|
| Docs examined per query | 445,801 | 1 |
| `checkpoints` query | 5,173ms | <10ms |
| `checkpoint_writes` query | 925ms | <10ms |

### Test plan

- [x] Unit test added verifying `setup()` creates indexes on both
collections with correct key spec
- [x] Existing integration tests pass

---------

Signed-off-by: Christian Bromann <git@bromann.dev>
Co-authored-by: Christian Bromann <git@bromann.dev>
2026-06-22 08:25:03 -07:00
Christian Bromann b1e856d987 feat(sdk): apply state update and goto alongside interrupt resume (#2557)
## Summary
- Add `update` and `goto` options to `respond()` across the SDK so
resolving an interrupt can apply a state update and/or directed jump in
the **same superstep** — mapped to LangGraph's `Command(resume, update,
goto)`. The canonical use case is a HITL flow that pushes the interrupt
card into state at the moment it answers, committed in one checkpoint
with no flicker.
- `@langchain/langgraph-sdk`: new `update`/`goto` fields on
`StreamRespondAllOptions`, forwarded by
`StreamController.respond`/`respondAll`; `@langchain/core` `BaseMessage`
instances under the `messagesKey` are serialized to dicts before
transport, exactly like `submit()`.
- `@langchain/langgraph-api`: forward `update`/`goto` from
`input.respond` into the run `Command` in both the protocol service and
the embedded server.
- `@langchain/react`, `@langchain/vue`, `@langchain/svelte`,
`@langchain/angular`: document the new `respond({ update, goto })`
capability (incl. `BaseMessage` examples).
- Fix: the protocol-v2 state normalizer stripped `response_metadata`,
which HITL cards ride on (`AIMessage.response_metadata`); non-empty
`response_metadata` is now preserved.
- Add React browser tests (`interrupt_card_graph` fixture via
`createAgent`) covering the approve and reject paths: the FE-pushed card
lands in committed state exactly once and persists through a slow tool
execution.
2026-06-22 08:20:15 -07:00
George Mihailov 3d7fcea7d7 feat(langgraph-checkpoint-mongodb): add TTL support for automatic checkpoint data expiration (#1928)
Add optional TTL parameter to MongoDBSaver that enables automatic
expiration of checkpoints using MongoDB's TTL indexes.

- Add `ttl` option to MongoDBSaverParams (value in seconds)
- Add `setup()` method to create TTL indexes, returns Error[] for caller
to handle failures
- Add `upserted_at` timestamp to documents when TTL is enabled
- Each write refreshes TTL (expires after inactivity, not creation)

```js
  // Create checkpointer with 1-hour TTL (in seconds)                         
  const checkpointer = new MongoDBSaver({                                     
    client,                                                                   
    ttl: 3600,                                                                
  });                                                                         
                                                                              
  // Create TTL indexes (call on startup/deployment)                          
  const errors = await checkpointer.setup();                                  
  if (errors.length) {                                                        
    console.warn("Failed to create TTL indexes:", errors);                    
  } 
```

Fixes # (issue)

Ever growing records in database.

---------

Co-authored-by: Christian Bromann <git@bromann.dev>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-22 07:58:03 -07:00
Mohamed Khaled bee3c91d0a fix(langgraph-checkpoint-mongodb): no-op putWrites on empty writes (#2556)
## Summary

`MongoDBSaver.putWrites` builds a `bulkWrite` operations array from
`writes` and calls `collection.bulkWrite(operations)`. When `writes` is
empty, `operations` is empty and the MongoDB driver throws:

```
MongoServerError: Invalid BulkOperation, Batch cannot be empty
```

This is reached in normal operation by **human-in-the-loop /
`interrupt()`** flows: when a graph interrupts to wait for input, a task
can complete producing **zero channel writes**, so LangGraph calls
`putWrites(config, [], taskId)` and the saver throws.

The other first-party savers don't hit this — `checkpoint-postgres` and
`checkpoint-sqlite` iterate over `writes`, so an empty array is a
natural no-op. The sibling `store.ts` in this same package already
guards its bulk write with `if (bulkOps.length > 0)`. `putWrites` was
simply missing the equivalent guard.

## Fix

Skip the `bulkWrite` call when there are no operations, mirroring the
existing guard in `store.ts`. The guard is at the call site (not an
early return), so the existing `configurable` validation is preserved.
This aligns the MongoDB saver's empty-writes behavior with the postgres
and sqlite savers.

## Tests

- **Unit** (`checkpoints.test.ts`): asserts `putWrites(config, [],
taskId)` resolves and that `bulkWrite` is **not** called. Verified to
fail before the fix (`bulkWrite` was called with `[]`).
- **Integration** (`checkpoints.int.test.ts`): asserts `putWrites` with
empty writes resolves and persists nothing — the truest repro against
the real driver.

`pnpm build`, `pnpm lint`, `pnpm format:check`, and the unit suite all
pass locally. A changeset is included
(`@langchain/langgraph-checkpoint-mongodb` patch).

## Related

Same class of HITL / `interrupt()` + `putWrites` bug previously fixed
for the Redis saver: #1996 / #2026.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 20:25:49 -07:00
github-actions[bot] e6082e0575 chore: version packages (#2554)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph@1.4.4

### Patch Changes

- [#2552](https://github.com/langchain-ai/langgraphjs/pull/2552)
[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): isolate concurrent singleton-agent invocations by thread

`ensureLangGraphConfig` ignores the ambient `AsyncLocalStorage`
`configurable`
on root-level invokes that supply an invoke-time `thread_id` and have no
nesting
keys (ignoring graph-bound `.withConfig()` defaults). On a fresh
top-level run
the ambient `configurable` can belong to another concurrent invocation,
so its
    keys — internal scratchpad/task-input as well as user keys like
`tenant_id`/`user_id` — must not leak in; values the caller wants arrive
through
the explicit (bound + invoke-time) configs. Ambient nesting
(`__pregel_read__`)
and bound child graphs invoked from parent tasks are unaffected. This
prevents
cross-invocation leakage between concurrent `invoke()` calls on a shared
compiled
graph (e.g. BullMQ workers with `concurrency > 1`). Complements the
config-merge
fix that stopped shared graph-bound `metadata`/`configurable` objects
from being
    mutated across invocations
    ([#2040](https://github.com/langchain-ai/langgraphjs/issues/2040)).

- [#2553](https://github.com/langchain-ai/langgraphjs/pull/2553)
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): recognize JSON-erased `Overwrite` values across runtimes

`Overwrite` already survives JSON serialization in JS because
`Overwrite.toJSON()`
emits the canonical `{ "__overwrite__": value }` sentinel.
`_getOverwriteValue`
now additionally recognizes the discriminator form `{ "type":
"__overwrite__",
value }` produced when a typed `Overwrite` from another runtime (e.g. a
Python
dataclass routed through the LangGraph API server) is serialized and its
type is
erased. This keeps `Overwrite` (and `DeltaChannel`) semantics intact
across
cross-runtime JSON boundaries. These delta-channel APIs remain Beta.

## @example/ai-elements@0.1.40

### Patch Changes

- Updated dependencies
\[[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783),
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)]:
    -   @langchain/langgraph@1.4.4

## @examples/assistant-ui-claude@0.1.40

### Patch Changes

- Updated dependencies
\[[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783),
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)]:
    -   @langchain/langgraph@1.4.4

## @examples/ui-angular@0.0.50

### Patch Changes

- Updated dependencies
\[[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783),
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)]:
    -   @langchain/langgraph@1.4.4

## @examples/ui-multimodal@0.0.26

### Patch Changes

- Updated dependencies
\[[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783),
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)]:
    -   @langchain/langgraph@1.4.4

## @examples/ui-react@0.0.26

### Patch Changes

- Updated dependencies
\[[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783),
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)]:
    -   @langchain/langgraph@1.4.4

## langgraph@1.0.44

### Patch Changes

- Updated dependencies
\[[`d662cbb`](https://github.com/langchain-ai/langgraphjs/commit/d662cbbc63eebdf1312e57d41908da1b9018e783),
[`1c2aa5b`](https://github.com/langchain-ai/langgraphjs/commit/1c2aa5bfeacd8b7463e3d5b6010daee26e9217e0)]:
    -   @langchain/langgraph@1.4.4

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-17 16:41:40 -07:00
Christian Bromann d662cbbc63 fix(langgraph): isolate concurrent singleton-agent invocations by thread (#2552)
## Summary
- Hardens `ensureLangGraphConfig` so root-level invokes with an explicit
`thread_id` (and no nesting keys) no longer inherit langgraph-internal
`configurable` entries from `AsyncLocalStorage`, preventing
scratchpad/`currentTaskInput` leakage between concurrent `invoke()`
calls on a singleton agent.
- Adds unit tests for the new ALS-skipping behavior and an end-to-end
regression test that verifies checkpoint and tool state stay isolated
across concurrent invocations on a shared graph with `.withConfig()`.
- Complements #2531 (config merge / shared bound-config mutation fix),
which was the primary cause of cross-thread contamination reported in
#2040.

fixes #2040
2026-06-17 16:35:38 -07:00
Christian Bromann 1c2aa5bfea fix(langgraph): recognize JSON-erased Overwrite values across runtimes (#2553)
## Summary
- JS `Overwrite` already survives JSON serialization because
`Overwrite.toJSON()` emits the canonical `{ "__overwrite__": value }`
sentinel, which `_getOverwriteValue` recognizes.
- This adds recognition of the discriminator form `{ "type":
"__overwrite__", value }` that results when a typed `Overwrite` from
another runtime (notably a Python dataclass, post
langchain-ai/langgraph#8127) is serialized through a JSON boundary and
its type is erased.
- Brings JS to full parity with Python's three-form `_get_overwrite`
(instance, sentinel dict, discriminator dict), so `Overwrite`
round-trips both directions across the JS↔Python API boundary.
Delta-channel APIs remain Beta.
2026-06-17 15:58:20 -07:00
github-actions[bot] 73ecaa0fb5 chore: version packages (#2536)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @langchain/langgraph-checkpoint@1.1.2

### Patch Changes

- [#2544](https://github.com/langchain-ai/langgraphjs/pull/2544)
[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): make concurrent DeltaChannel writes deterministic on
replay

Concurrent same-superstep writes to a `DeltaChannel` could reconstruct
from a
checkpoint differently than they were applied live, because live
execution
ordered them by task path while savers replayed them by task id. This
fixes that
    divergence in two complementary ways:

- Plain concurrent writes are now applied in the canonical `(task_id,
idx)`
order on both paths: `_applyWrites` orders them that way live, and the
`getDeltaChannelHistory` walk enforces the same order so reconstruction
matches live for every saver (Postgres, SQLite, MongoDB, Redis, and
custom).
- An `Overwrite` now wins its entire super-step: every sibling write in
the same
        step — before AND after the `Overwrite` — is discarded, matching
`BinaryOperatorAggregate`. This makes the result independent of the
(unstable)
ordering of concurrent fan-in writes; previously a plain write that
landed
        after an `Overwrite` in the same step was still folded in.

To keep reconstruction in sync with this `Overwrite` rule, any
`DeltaChannel`
that sees an `Overwrite` in a super-step is now force-snapshotted at the
next
checkpoint (and, under `"exit"` durability, in the final checkpoint).
The
post-overwrite value is materialized into `channel_values`, so a cold
read seeds
from that snapshot and never has to replay across the reset — making
live and
reconstructed state identical without changing the sparse-replay history
shape.
    These delta-channel APIs remain Beta.

- [#2531](https://github.com/langchain-ai/langgraphjs/pull/2531)
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): forward task metadata and name subagents via
lc_agent_name

`mapDebugTasks` now forwards filtered user-meaningful task config
metadata
(including `lc_agent_name`) onto `tasks` stream payloads. The lifecycle
    transformer uses that metadata to set subagent `graph_name` from
`lc_agent_name` and recover `cause: { type: "toolCall", tool_call_id }`
from parent tool-dispatch tasks. Adds the shared
`EXCLUDED_METADATA_KEYS`
    constant to `@langchain/langgraph-checkpoint`. Ports langgraph#7928.

## @langchain/langgraph-checkpoint-redis@1.0.10

### Patch Changes

- [#2336](https://github.com/langchain-ai/langgraphjs/pull/2336)
[`25907eb`](https://github.com/langchain-ai/langgraphjs/commit/25907eb0be25258c26327c6c68c72bc828ee1cff)
Thanks [@MohMaherId](https://github.com/MohMaherId)! -
fix(langgraph-checkpoint-redis): persist and reconstruct full
`channel_values` across multi-node graphs.

`RedisSaver.put()` delta-filters `channel_values` to only the channels
written by the current node, but `getTuple()` had no reconstruction
logic — unlike `PostgresSaver` — so any multi-node graph whose last node
wrote a subset of channels silently lost the others. Each changed
channel is now persisted as a version-keyed `checkpoint_blob:*` entry in
`put()` and missing channels are reconstructed from those blobs on read.

`deleteThread()` now also deletes the `checkpoint_blob:*` keys. Without
this the blobs introduced above would orphan forever (memory growth) and
thread deletion would be incomplete, matching
`PostgresSaver.deleteThread()` parity.

When `ttlConfig.refreshOnRead` is enabled, reads now refresh the TTL of
the reconstructed `checkpoint_blob:*` keys alongside the checkpoint key.
Otherwise a read would keep the checkpoint alive while the blobs it
depends on expired, silently dropping reconstructed channels.

On write, `put()` now refreshes the TTL of every blob the checkpoint
references (the full `channel_versions` set), not just the channels
changed by the current node, so carried-over blobs from earlier nodes
expire in lockstep with the checkpoint doc. This write-side refresh is
independent of `refreshOnRead`. The per-channel blob writes also now run
in parallel.

Known limitation: with TTL enabled, a carried-over blob can still be
lost if it expires during an idle gap longer than `defaultTTL` (no read
or write refreshed it in time). When that happens the channel is left
cleanly absent on read rather than erroring. Fully closing this gap
(re-persisting expired blobs) is tracked as a follow-up.

## @langchain/langgraph@1.4.3

### Patch Changes

- [#2544](https://github.com/langchain-ai/langgraphjs/pull/2544)
[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): make concurrent DeltaChannel writes deterministic on
replay

Concurrent same-superstep writes to a `DeltaChannel` could reconstruct
from a
checkpoint differently than they were applied live, because live
execution
ordered them by task path while savers replayed them by task id. This
fixes that
    divergence in two complementary ways:

- Plain concurrent writes are now applied in the canonical `(task_id,
idx)`
order on both paths: `_applyWrites` orders them that way live, and the
`getDeltaChannelHistory` walk enforces the same order so reconstruction
matches live for every saver (Postgres, SQLite, MongoDB, Redis, and
custom).
- An `Overwrite` now wins its entire super-step: every sibling write in
the same
        step — before AND after the `Overwrite` — is discarded, matching
`BinaryOperatorAggregate`. This makes the result independent of the
(unstable)
ordering of concurrent fan-in writes; previously a plain write that
landed
        after an `Overwrite` in the same step was still folded in.

To keep reconstruction in sync with this `Overwrite` rule, any
`DeltaChannel`
that sees an `Overwrite` in a super-step is now force-snapshotted at the
next
checkpoint (and, under `"exit"` durability, in the final checkpoint).
The
post-overwrite value is materialized into `channel_values`, so a cold
read seeds
from that snapshot and never has to replay across the reset — making
live and
reconstructed state identical without changing the sparse-replay history
shape.
    These delta-channel APIs remain Beta.

- [#2531](https://github.com/langchain-ai/langgraphjs/pull/2531)
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): merge instead of overwrite in `ensureLangGraphConfig`

`ensureLangGraphConfig` now per-key merges `callbacks`, `tags`,
`metadata`,
and `configurable` across configs instead of last-write-wins, so values
bound via `.withConfig({...})` survive when a later (e.g. invoke-time)
config supplies other keys. The merged dicts are fresh objects, fixing a
by-reference mutation of shared base configs. Also drops the
now-redundant
`combineCallbacks` workaround in `streamEvents`, which double-registered
and
    double-fired graph-bound callbacks.

- [#2531](https://github.com/langchain-ai/langgraphjs/pull/2531)
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): preserve namespace nesting for imperative graph invokes

When a compiled graph is invoked from inside another graph's running
task
(e.g. a tool body calling `subAgent.invoke(...)`), the surrounding task
context — including the langgraph-internal nesting keys
(`__pregel_read`,
`__pregel_stream`, `checkpoint_ns`, the checkpoint map) — is propagated
    implicitly via `AsyncLocalStorage`. The base `Runnable.stream` calls
langchain-core's `ensureConfig`, which replaces the ambient
`configurable`
wholesale whenever the caller passes its own. Because `createAgent`
always
supplies a `configurable`, every tool-invoked sub-agent lost those keys,
ran
as a fresh root run, and had its streamed events flattened to the root
    namespace instead of nesting under the triggering task.

`Pregel.stream` now merges the ambient `configurable` underneath the
caller's
    (caller keys win per-key) when the ambient marks an active task
(`__pregel_read` present) but the explicit `configurable` is missing it.
Declared subgraph nodes (which already carry their own `__pregel_read`)
and
    top-level runs are unaffected.

- [#2537](https://github.com/langchain-ai/langgraphjs/pull/2537)
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): dispatch stream messages handler inline

The v3 `messages` handler (`StreamProtocolMessagesHandler`, which powers
`run.messages`) only performs a synchronous `push()` onto the run's
stream, but
its callbacks were dispatched on LangChain's background callback queue
(the
default `awaitHandlers === false`). A model or tool call inside a nested
or
parallel task could therefore flush its `messages` chunk _after_ the
Pregel
loop returned and sealed the stream, where
`IterableReadableWritableStream.push`
silently drops chunks once closed. This surfaced as empty per-message
streams
(`sub.messages`) for subagents dispatched in parallel from a single
tools step.

The handler now sets `awaitHandlers = true` so its callbacks run inline
— every
push happens during the originating model/chain call while the stream is
still
open. This avoids the global over-wait, fake-timer deadlock, and
error-path
unhandled rejections that a blanket `awaitAllCallbacks()` drain before
close
    would have introduced.

- [#2531](https://github.com/langchain-ai/langgraphjs/pull/2531)
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): forward task metadata and name subagents via
lc_agent_name

`mapDebugTasks` now forwards filtered user-meaningful task config
metadata
(including `lc_agent_name`) onto `tasks` stream payloads. The lifecycle
    transformer uses that metadata to set subagent `graph_name` from
`lc_agent_name` and recover `cause: { type: "toolCall", tool_call_id }`
from parent tool-dispatch tasks. Adds the shared
`EXCLUDED_METADATA_KEYS`
    constant to `@langchain/langgraph-checkpoint`. Ports langgraph#7928.

- [#2549](https://github.com/langchain-ai/langgraphjs/pull/2549)
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(langgraph): support DeltaChannel fields in StateSchema

Add a `DeltaValue` state field (and a `MessagesDeltaValue` prebuilt) so
a
`DeltaChannel` can be declared via `StateSchema`, not just
`Annotation.Root` or
a raw channel map. `StateSchema` now maps `DeltaValue` to a
`DeltaChannel`
(forwarding `snapshotFrequency` and the value-schema default) and
validates its
    inputs/`Overwrite` updates like `ReducedValue`.

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b)]:
    -   @langchain/langgraph-checkpoint@1.1.2
    -   @langchain/langgraph-sdk@1.9.23

## @langchain/langgraph-sdk@1.9.23

### Patch Changes

- [#2545](https://github.com/langchain-ai/langgraphjs/pull/2545)
[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236)
Thanks [@christian-bromann](https://github.com/christian-bromann)! -
fix(sdk): avoid scoped stream resubscribe churn

Defer final projection disposal by one microtask so framework bindings
that release and immediately reacquire the same scoped projection during
reactive updates keep the existing stream subscription instead of
rotating through root-only and scoped SSE filters.

## @langchain/angular@1.0.24

### Patch Changes

- Updated dependencies
\[[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236)]:
    -   @langchain/langgraph-sdk@1.9.23

## @langchain/react@1.0.24

### Patch Changes

- Updated dependencies
\[[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236)]:
    -   @langchain/langgraph-sdk@1.9.23

## @langchain/svelte@1.0.24

### Patch Changes

- Updated dependencies
\[[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236)]:
    -   @langchain/langgraph-sdk@1.9.23

## @langchain/vue@1.0.24

### Patch Changes

- Updated dependencies
\[[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236)]:
    -   @langchain/langgraph-sdk@1.9.23

## @example/ai-elements@0.1.39

### Patch Changes

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)]:
    -   @langchain/langgraph@1.4.3
    -   @langchain/react@1.0.24

## @examples/assistant-ui-claude@0.1.39

### Patch Changes

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)]:
    -   @langchain/langgraph@1.4.3
    -   @langchain/react@1.0.24

## @examples/ui-angular@0.0.49

### Patch Changes

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236),
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)]:
    -   @langchain/langgraph@1.4.3
    -   @langchain/langgraph-sdk@1.9.23
    -   @langchain/angular@1.0.24

## @examples/ui-multimodal@0.0.25

### Patch Changes

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)]:
    -   @langchain/langgraph@1.4.3
    -   @langchain/react@1.0.24

## @examples/ui-react@0.0.25

### Patch Changes

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`2134c8a`](https://github.com/langchain-ai/langgraphjs/commit/2134c8a2c0bc8dd2ebea33e1191c8dd0c4b83236),
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)]:
    -   @langchain/langgraph@1.4.3
    -   @langchain/langgraph-sdk@1.9.23
    -   @langchain/react@1.0.24

## langgraph@1.0.43

### Patch Changes

- Updated dependencies
\[[`4487214`](https://github.com/langchain-ai/langgraphjs/commit/448721449f0801009ba76b03dd2e9c16f900bbba),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`be09666`](https://github.com/langchain-ai/langgraphjs/commit/be096663f42fe7ea9355d6c0def4854e657866d8),
[`38cfe01`](https://github.com/langchain-ai/langgraphjs/commit/38cfe01ff02490ff6bcc86c66708ef671f2e0d4b),
[`bc667a9`](https://github.com/langchain-ai/langgraphjs/commit/bc667a998ae9909d15795387dad45048e8947219)]:
    -   @langchain/langgraph@1.4.3

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-17 15:34:21 -07:00
Christian Bromann 448721449f fix(langgraph): replay concurrent DeltaChannel writes in live order (#2544)
## Summary
- Fix a non-deterministic divergence where a `DeltaChannel`'s
reconstructed state did not match its live state when concurrent writes
(notably a plain write + an `Overwrite`) were applied in the same
super-step. Live execution applied concurrent writes in task-**path**
order, while every checkpointer replays persisted writes in task-**id**
order, so an `Overwrite` hard reset could land at a different point on
reload.
- `_applyWrites` (`@langchain/langgraph`) now applies concurrent
`DeltaChannel` writes in the canonical `(task_id, idx)` order — the same
order checkpointers replay them in.
- The base `getDeltaChannelHistory` (`@langchain/langgraph-checkpoint`)
now stable-sorts each ancestor checkpoint's writes by `task_id`, making
reconstruction order independent of how a saver returns `pendingWrites`.
This fixes Postgres, SQLite, MongoDB, Redis, and any custom saver in one
place; MemorySaver was already correct via its override.
2026-06-17 15:22:57 -07:00
Christian Bromann bc667a998a fix(langgraph): support DeltaChannel fields in StateSchema (#2549)
## Summary
- Add `DeltaValue<Value, Input>` (`state/values/delta.ts`), a
`StateSchema` field backed by a `DeltaChannel`'s batch reducer +
`snapshotFrequency` — distinct from `ReducedValue`'s single-value
reducer.
- Wire `DeltaValue` into `StateSchema`: `getChannels()` maps it to a
`DeltaChannel` (forwarding `snapshotFrequency` and seeding the initial
value from the value-schema default);
`getJsonSchema()`/`getInputJsonSchema()`/`validateInput()` handle it
(incl. `Overwrite`) like `ReducedValue`; and the type helpers infer
`State`/`Update` correctly.
- Add the `MessagesDeltaValue` prebuilt (a `DeltaChannel`-backed drop-in
for `MessagesValue`); export `DeltaValue` and `MessagesDeltaValue` from
`@langchain/langgraph`.
- Previously `DeltaChannel` was only usable via `Annotation.Root` / raw
channel maps; the `StateSchema` class and Zod paths threw. This closes
the `StateSchema` gap (Zod remains a separate follow-up).
2026-06-17 13:08:12 -07:00
Christian Bromann 2134c8a2c0 fix(sdk): avoid scoped stream resubscribe churn (#2545)
## Summary
- Defer final `ChannelRegistry` projection disposal by one microtask so
same-turn reacquires keep the existing projection runtime alive.
- Preserve `registry.size` as an active-consumer diagnostic while
allowing pending disposals to be cancelled.
- Add regression coverage for release-then-reacquire behavior.
2026-06-17 12:43:03 -07:00