You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR was opened by the Changesets release 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.
DeltaChannel is a reducer channel that stores only a sentinel in checkpoint
blobs instead of the full accumulated value, reconstructing state on read by
replaying ancestor writes through a batch reducer. This avoids re-serializing
the entire accumulated value at every step (e.g. long message histories).
DeltaChannel(reducer, { snapshotFrequency }) in @langchain/langgraph —
count-based snapshot cadence (default snapshotFrequency=1000) plus a
system bound DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT (default 5000, env LANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT).
messagesDeltaReducer — a batching-invariant messages reducer that coerces
raw object/string writes, for use with DeltaChannel.
BaseCheckpointSaver.getDeltaChannelHistory({ config, channels }) (beta) —
walks the parent chain returning per-channel { writes, seed? }, with a
direct-storage override in MemorySaver.
counters_since_delta_snapshot added to CheckpointMetadata; DeltaSnapshot
serialization support in the JSON+ serializer.
Reconstruction is wired through the Pregel read/execution paths (initialization, getState, updateState, local reads) and exit durability accumulates and
anchors delta writes so threads remain reconstructible without forcing
snapshots.
A timeout option is now supported on StateGraph.addNode, the functional API
(task/entrypoint), and the Send constructor. Pass a number of milliseconds
for a hard wall-clock cap, or a TimeoutPolicy for finer control:
import{TimeoutPolicy}from"@langchain/langgraph";// hard wall-clock cap on each attemptbuilder.addNode("agent",agentFn,{timeout: 60_000});// full controlbuilder.addNode("agent",agentFn,{timeout: {runTimeout: 60_000,// hard wall-clock cap, never refreshedidleTimeout: 10_000,// cap on time without observable progressrefreshOn: "auto",// "auto" | "heartbeat"},});// per-task overridenewSend("agent",state,{timeout: {idleTimeout: 5_000}});
When a timeout fires, a NodeTimeoutError (carrying node, kind
("run"/"idle"), timeout, elapsed, runTimeout, idleTimeout) is raised,
the attempt's buffered writes are dropped, and the node's AbortSignal is
aborted. idleTimeout is refreshed by observable progress (writes, custom
stream-writer calls, child-task scheduling, callback events) or an explicit runtime.heartbeat() call. The timer resets per retry attempt, and NodeTimeoutError is retryable under the default retry policy.
A new RunControl (exported from @langchain/langgraph) exposes requestDrain(reason) plus read-only drainRequested / drainReason. Pass it
through the new control option on invoke / stream / streamEvents (and the
functional API). It is surfaced on runtime.control, so nodes can read it or call requestDrain() themselves, and it is propagated into subgraphs.
When a drain is requested, the Pregel loop checks the flag at the top of each
superstep (after the previous step's writes are applied and checkpointed): if more
tasks remain it saves the checkpoint and throws the new GraphDrained error (also
under durability: "exit"), so the run can be resumed later from the same config.
If the graph naturally finishes on that tick it returns normally and the caller can
inspect control.drainRequested. A drain requested inside a subgraph bubbles up and
stops the parent at its next boundary. Draining never cancels work that is already
running — pair it with an AbortSignal if you need a hard upper bound.
DeltaChannel is a reducer channel that stores only a sentinel in checkpoint
blobs instead of the full accumulated value, reconstructing state on read by
replaying ancestor writes through a batch reducer. This avoids re-serializing
the entire accumulated value at every step (e.g. long message histories).
DeltaChannel(reducer, { snapshotFrequency }) in @langchain/langgraph —
count-based snapshot cadence (default snapshotFrequency=1000) plus a
system bound DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT (default 5000, env LANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT).
messagesDeltaReducer — a batching-invariant messages reducer that coerces
raw object/string writes, for use with DeltaChannel.
BaseCheckpointSaver.getDeltaChannelHistory({ config, channels }) (beta) —
walks the parent chain returning per-channel { writes, seed? }, with a
direct-storage override in MemorySaver.
counters_since_delta_snapshot added to CheckpointMetadata; DeltaSnapshot
serialization support in the JSON+ serializer.
Reconstruction is wired through the Pregel read/execution paths (initialization, getState, updateState, local reads) and exit durability accumulates and
anchors delta writes so threads remain reconstructible without forcing
snapshots.
StateGraph.addNode(name, fn, { errorHandler }) now accepts a first-class
node-level error handler. The handler runs ONLY after the failing node's retryPolicy is exhausted, so retry and handling stay decoupled. It receives a
typed NodeError { node, error } and the typed node input state, can return a
state update, and can route to a recovery branch via new Command({ goto })
(saga / compensation flows).
Failure provenance is checkpointed (via a reserved ERROR_SOURCE_NODE write) so
handlers observe the same context after a checkpoint resume. Uncaught node
errors without a handler still abort the run as before, and GraphBubbleUp
errors (such as interrupt()) are never swallowed by a handler.
StateGraph.setNodeDefaults({ errorHandler }) now also accepts a graph-wide
default handler. It is materialized at compile() as a single shared handler
and invoked for every regular node that does not set its own errorHandler. A
per-node handler always takes precedence, the default never catches a failure
raised by an error-handler node itself (handler failures fail the run), and the
default is not inherited by subgraphs.
A timeout option is now supported on StateGraph.addNode, the functional API
(task/entrypoint), and the Send constructor. Pass a number of milliseconds
for a hard wall-clock cap, or a TimeoutPolicy for finer control:
import{TimeoutPolicy}from"@langchain/langgraph";// hard wall-clock cap on each attemptbuilder.addNode("agent",agentFn,{timeout: 60_000});// full controlbuilder.addNode("agent",agentFn,{timeout: {runTimeout: 60_000,// hard wall-clock cap, never refreshedidleTimeout: 10_000,// cap on time without observable progressrefreshOn: "auto",// "auto" | "heartbeat"},});// per-task overridenewSend("agent",state,{timeout: {idleTimeout: 5_000}});
When a timeout fires, a NodeTimeoutError (carrying node, kind
("run"/"idle"), timeout, elapsed, runTimeout, idleTimeout) is raised,
the attempt's buffered writes are dropped, and the node's AbortSignal is
aborted. idleTimeout is refreshed by observable progress (writes, custom
stream-writer calls, child-task scheduling, callback events) or an explicit runtime.heartbeat() call. The timer resets per retry attempt, and NodeTimeoutError is retryable under the default retry policy.
#2461801d955 Thanks @christian-bromann! - Add StateGraph.setNodeDefaults() for setting graph-wide node policy defaults (retryPolicy, cachePolicy). Per-node values passed to addNode always take precedence, and defaults are resolved at compile() time so call order does not matter. Defaults are not inherited by subgraphs. Ports Python's set_node_defaults() (feat(langgraph): add set_node_defaults() to StateGraph langgraph#7747).
Ports Python fixes for stale RESUME writes during replay, wrong subgraph checkpoint loading during time travel, missing fork checkpoints on replay, and direct-to-subgraph time travel.
Route StateSchema runtime definitions through getJsonSchema() and
getInputJsonSchema() so LangGraph Studio receives state, input, and
context schemas when graphs use the StateSchema primitive.
Avoid building full-state mapDebugCheckpoint payloads on every tick when
no consumer subscribed to checkpoints or debug stream modes. v3
companion checkpoint envelopes are unchanged (they come from values metadata).
Build a PendingWritesIndex once per _prepareNextTasks call so resume and
skip-done-task checks avoid repeated linear scans over checkpointPendingWrites.
Reduce allocations in _applyWrites, fix O(N²) interrupt versions_seen updates,
skip stack traces on EmptyChannelError control flow, and cache task lists in
the pregel loop and runner.
#251767a4f8d Thanks @jackjin1997! - fix: MongoDBSaver.putWrites now honors WRITES_IDX_MAP, pinning special channels (__error__, __scheduled__, __interrupt__, __resume__) to fixed negative indices instead of the call-local ordinal. Previously a mixed putWrites([[...regular...], [INTERRUPT, …]], taskId) placed the INTERRUPT at a positive idx that could collide with a regular write at the same (task_id, idx), and the unconditional $set upsert silently overwrote whichever row landed there first. The conflict-resolution clause now matches the Postgres / SQLite (TS and Python) checkpointers: $set only when every channel is a special one, $setOnInsert otherwise.
@langchain/langgraph-checkpoint-postgres@1.0.3
Patch Changes
#2512375c73f Thanks @jackjin1997! - fix: reject SQL LIKE wildcards (%, _) and the backslash escape character in PostgresStore namespace labels. BaseStore.search() matches namespaces via namespace_path LIKE ${prefix}%, and these characters in caller-supplied namespace labels are interpreted as wildcards by Postgres even through a bound parameter — letting a namespace prefix of ["%"] match every namespace in the store across tenants. validateNamespace now throws for these characters at all search / get / put entrypoints, keeping store-wide consistency. CWE-1336.
@langchain/langgraph-checkpoint-redis@1.0.8
Patch Changes
#25189182ea3 Thanks @jackjin1997! - fix: RedisSaver.putWrites now honors WRITES_IDX_MAP, pinning special channels (__error__, __scheduled__, __interrupt__, __resume__) to fixed negative indices in their Redis key (checkpoint_write:…:<idx>) instead of the call-local ordinal. Previously a mixed putWrites([[…regular…], [INTERRUPT, …]], taskId) placed the INTERRUPT key at the positive idx of its position in the batch, where a peer task's regular write at the same idx would overwrite it via the unconditional JSON.SET. The conflict-resolution clause now matches Postgres / SQLite / MongoDB: unguarded JSON.SET when every write is a special channel, JSON.SET … NX (insert-or-ignore) otherwise.
@langchain/langgraph-checkpoint-sqlite@1.0.3
Patch Changes
#2516f6a6d26 Thanks @jackjin1997! - fix: SqliteSaver.putWrites now honors WRITES_IDX_MAP, pinning special channels (__error__, __scheduled__, __interrupt__, __resume__) to fixed negative indices instead of the call-local ordinal. Previously a follow-up putWrites([[INTERRUPT, …]], taskId) for the same checkpoint silently REPLACEd the regular write previously stored at idx=0 for that task, losing data. The conflict-resolution clause also now matches the Python checkpointer contract: OR REPLACE only when every channel is a special one (so e.g. INTERRUPT→RESUME state transitions overwrite), OR IGNORE otherwise.
A concrete useStream<typeof agent>() handle was not assignable to AnyStream because generic-computed covariant members (toolCalls, values) don't widen under any — InferToolCalls<any>[] resolves to AssembledToolCall<…, never>[], narrower than a concrete handle. Override
those members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte, ShallowRef for Vue, Signal for Angular) so the message/tool/value selector hooks accept a
fully-typed stream without an as AnyStream cast.
A concrete useStream<typeof agent>() handle was not assignable to AnyStream because generic-computed covariant members (toolCalls, values) don't widen under any — InferToolCalls<any>[] resolves to AssembledToolCall<…, never>[], narrower than a concrete handle. Override
those members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte, ShallowRef for Vue, Signal for Angular) so the message/tool/value selector hooks accept a
fully-typed stream without an as AnyStream cast.
A concrete useStream<typeof agent>() handle was not assignable to AnyStream because generic-computed covariant members (toolCalls, values) don't widen under any — InferToolCalls<any>[] resolves to AssembledToolCall<…, never>[], narrower than a concrete handle. Override
those members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte, ShallowRef for Vue, Signal for Angular) so the message/tool/value selector hooks accept a
fully-typed stream without an as AnyStream cast.
A concrete useStream<typeof agent>() handle was not assignable to AnyStream because generic-computed covariant members (toolCalls, values) don't widen under any — InferToolCalls<any>[] resolves to AssembledToolCall<…, never>[], narrower than a concrete handle. Override
those members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte, ShallowRef for Vue, Signal for Angular) so the message/tool/value selector hooks accept a
fully-typed stream without an as AnyStream cast.
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Remove or replace dependencies that include known critical CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@vitest/browser@4.0.18. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm @schematics/angular is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@schematics/angular@22.0.0. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
Warn
Obfuscated code: npm @typescript-eslint/eslint-plugin is 90.0% likely obfuscated
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/@typescript-eslint/eslint-plugin@8.59.2. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release 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.0
Minor Changes
#2452
a8e7659Thanks @christian-bromann! - AddDeltaChanneland the writes-history saver API (beta).DeltaChannelis a reducer channel that stores only a sentinel in checkpointblobs instead of the full accumulated value, reconstructing state on read by
replaying ancestor writes through a batch reducer. This avoids re-serializing
the entire accumulated value at every step (e.g. long message histories).
DeltaChannel(reducer, { snapshotFrequency })in@langchain/langgraph—count-based snapshot cadence (default
snapshotFrequency=1000) plus asystem bound
DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT(default 5000, envLANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT).messagesDeltaReducer— a batching-invariant messages reducer that coercesraw object/string writes, for use with
DeltaChannel.BaseCheckpointSaver.getDeltaChannelHistory({ config, channels })(beta) —walks the parent chain returning per-channel
{ writes, seed? }, with adirect-storage override in
MemorySaver.counters_since_delta_snapshotadded toCheckpointMetadata;DeltaSnapshotserialization support in the JSON+ serializer.
Reconstruction is wired through the Pregel read/execution paths (initialization,
getState,updateState, local reads) andexitdurability accumulates andanchors delta writes so threads remain reconstructible without forcing
snapshots.
Patch Changes
#2450
2f6d873Thanks @christian-bromann! - Add node-level timeouts.A
timeoutoption is now supported onStateGraph.addNode, the functional API(
task/entrypoint), and theSendconstructor. Pass a number of millisecondsfor a hard wall-clock cap, or a
TimeoutPolicyfor finer control:When a timeout fires, a
NodeTimeoutError(carryingnode,kind(
"run"/"idle"),timeout,elapsed,runTimeout,idleTimeout) is raised,the attempt's buffered writes are dropped, and the node's
AbortSignalisaborted.
idleTimeoutis refreshed by observable progress (writes, customstream-writer calls, child-task scheduling, callback events) or an explicit
runtime.heartbeat()call. The timer resets per retry attempt, andNodeTimeoutErroris retryable under the default retry policy.Ports chore: node-level timeouts langgraph#7599, #7646, and #7659.
@langchain/langgraph@1.4.0
Minor Changes
#2449
d12d269Thanks @christian-bromann! - Add cooperative, between-superstep graph draining viaRunControl.A new
RunControl(exported from@langchain/langgraph) exposesrequestDrain(reason)plus read-onlydrainRequested/drainReason. Pass itthrough the new
controloption oninvoke/stream/streamEvents(and thefunctional API). It is surfaced on
runtime.control, so nodes can read it or callrequestDrain()themselves, and it is propagated into subgraphs.When a drain is requested, the Pregel loop checks the flag at the top of each
superstep (after the previous step's writes are applied and checkpointed): if more
tasks remain it saves the checkpoint and throws the new
GraphDrainederror (alsounder
durability: "exit"), so the run can be resumed later from the same config.If the graph naturally finishes on that tick it returns normally and the caller can
inspect
control.drainRequested. A drain requested inside a subgraph bubbles up andstops the parent at its next boundary. Draining never cancels work that is already
running — pair it with an
AbortSignalif you need a hard upper bound.#2452
a8e7659Thanks @christian-bromann! - AddDeltaChanneland the writes-history saver API (beta).DeltaChannelis a reducer channel that stores only a sentinel in checkpointblobs instead of the full accumulated value, reconstructing state on read by
replaying ancestor writes through a batch reducer. This avoids re-serializing
the entire accumulated value at every step (e.g. long message histories).
DeltaChannel(reducer, { snapshotFrequency })in@langchain/langgraph—count-based snapshot cadence (default
snapshotFrequency=1000) plus asystem bound
DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT(default 5000, envLANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT).messagesDeltaReducer— a batching-invariant messages reducer that coercesraw object/string writes, for use with
DeltaChannel.BaseCheckpointSaver.getDeltaChannelHistory({ config, channels })(beta) —walks the parent chain returning per-channel
{ writes, seed? }, with adirect-storage override in
MemorySaver.counters_since_delta_snapshotadded toCheckpointMetadata;DeltaSnapshotserialization support in the JSON+ serializer.
Reconstruction is wired through the Pregel read/execution paths (initialization,
getState,updateState, local reads) andexitdurability accumulates andanchors delta writes so threads remain reconstructible without forcing
snapshots.
#2451
d65a920Thanks @christian-bromann! - feat(langgraph): add node-level error handlersStateGraph.addNode(name, fn, { errorHandler })now accepts a first-classnode-level error handler. The handler runs ONLY after the failing node's
retryPolicyis exhausted, so retry and handling stay decoupled. It receives atyped
NodeError { node, error }and the typed node input state, can return astate update, and can route to a recovery branch via
new Command({ goto })(saga / compensation flows).
Failure provenance is checkpointed (via a reserved
ERROR_SOURCE_NODEwrite) sohandlers observe the same context after a checkpoint resume. Uncaught node
errors without a handler still abort the run as before, and
GraphBubbleUperrors (such as
interrupt()) are never swallowed by a handler.StateGraph.setNodeDefaults({ errorHandler })now also accepts a graph-widedefault handler. It is materialized at
compile()as a single shared handlerand invoked for every regular node that does not set its own
errorHandler. Aper-node handler always takes precedence, the default never catches a failure
raised by an error-handler node itself (handler failures fail the run), and the
default is not inherited by subgraphs.
Ports the Python feature from feat(langgraph): add node-level error handlers langgraph#7233.
#2450
2f6d873Thanks @christian-bromann! - Add node-level timeouts.A
timeoutoption is now supported onStateGraph.addNode, the functional API(
task/entrypoint), and theSendconstructor. Pass a number of millisecondsfor a hard wall-clock cap, or a
TimeoutPolicyfor finer control:When a timeout fires, a
NodeTimeoutError(carryingnode,kind(
"run"/"idle"),timeout,elapsed,runTimeout,idleTimeout) is raised,the attempt's buffered writes are dropped, and the node's
AbortSignalisaborted.
idleTimeoutis refreshed by observable progress (writes, customstream-writer calls, child-task scheduling, callback events) or an explicit
runtime.heartbeat()call. The timer resets per retry attempt, andNodeTimeoutErroris retryable under the default retry policy.Ports chore: node-level timeouts langgraph#7599, #7646, and #7659.
#2461
801d955Thanks @christian-bromann! - AddStateGraph.setNodeDefaults()for setting graph-wide node policy defaults (retryPolicy,cachePolicy). Per-node values passed toaddNodealways take precedence, and defaults are resolved atcompile()time so call order does not matter. Defaults are not inherited by subgraphs. Ports Python'sset_node_defaults()(feat(langgraph): add set_node_defaults() to StateGraph langgraph#7747).Patch Changes
#2179
01c67dfThanks @christian-bromann! - fix(core): time travel replay/fork for graphs with interrupts and subgraphsPorts Python fixes for stale RESUME writes during replay, wrong subgraph checkpoint loading during time travel, missing fork checkpoints on replay, and direct-to-subgraph time travel.
#2514
9e0201dThanks @christian-bromann! - fix(schema): expose StateSchema JSON schemas for Studio introspectionRoute StateSchema runtime definitions through getJsonSchema() and
getInputJsonSchema() so LangGraph Studio receives state, input, and
context schemas when graphs use the StateSchema primitive.
Fixes #2466
#2471
9b96f60Thanks @christian-bromann! - perf(core): skip debug checkpoint snapshots when not streaming themAvoid building full-state
mapDebugCheckpointpayloads on every tick whenno consumer subscribed to
checkpointsordebugstream modes. v3companion checkpoint envelopes are unchanged (they come from values metadata).
#2472
8e06aceThanks @christian-bromann! - perf(core): index pending writes for O(1) task-prep lookupsBuild a PendingWritesIndex once per _prepareNextTasks call so resume and
skip-done-task checks avoid repeated linear scans over checkpointPendingWrites.
#2473
a8b0036Thanks @christian-bromann! - perf(core): optimize applyWrites, interrupt seen, and channel errorsReduce allocations in _applyWrites, fix O(N²) interrupt versions_seen updates,
skip stack traces on EmptyChannelError control flow, and cache task lists in
the pregel loop and runner.
#2444
4096933Thanks @christian-bromann! - feat(remote): add RemoteGraph v3 streaming supportExpose the v3
streamEventssurface forRemoteGraphby adapting remote SDK thread streams to the localGraphRunStreamshape.Updated dependencies [
a8e7659,2f6d873]:@langchain/langgraph-checkpoint-mongodb@1.3.4
Patch Changes
67a4f8dThanks @jackjin1997! - fix:MongoDBSaver.putWritesnow honorsWRITES_IDX_MAP, pinning special channels (__error__,__scheduled__,__interrupt__,__resume__) to fixed negative indices instead of the call-local ordinal. Previously a mixedputWrites([[...regular...], [INTERRUPT, …]], taskId)placed the INTERRUPT at a positive idx that could collide with a regular write at the same(task_id, idx), and the unconditional$setupsert silently overwrote whichever row landed there first. The conflict-resolution clause now matches the Postgres / SQLite (TS and Python) checkpointers:$setonly when every channel is a special one,$setOnInsertotherwise.@langchain/langgraph-checkpoint-postgres@1.0.3
Patch Changes
375c73fThanks @jackjin1997! - fix: reject SQLLIKEwildcards (%,_) and the backslash escape character inPostgresStorenamespace labels.BaseStore.search()matches namespaces vianamespace_path LIKE ${prefix}%, and these characters in caller-supplied namespace labels are interpreted as wildcards by Postgres even through a bound parameter — letting a namespace prefix of["%"]match every namespace in the store across tenants.validateNamespacenow throws for these characters at allsearch/get/putentrypoints, keeping store-wide consistency. CWE-1336.@langchain/langgraph-checkpoint-redis@1.0.8
Patch Changes
9182ea3Thanks @jackjin1997! - fix:RedisSaver.putWritesnow honorsWRITES_IDX_MAP, pinning special channels (__error__,__scheduled__,__interrupt__,__resume__) to fixed negative indices in their Redis key (checkpoint_write:…:<idx>) instead of the call-local ordinal. Previously a mixedputWrites([[…regular…], [INTERRUPT, …]], taskId)placed the INTERRUPT key at the positive idx of its position in the batch, where a peer task's regular write at the same idx would overwrite it via the unconditionalJSON.SET. The conflict-resolution clause now matches Postgres / SQLite / MongoDB: unguardedJSON.SETwhen every write is a special channel,JSON.SET … NX(insert-or-ignore) otherwise.@langchain/langgraph-checkpoint-sqlite@1.0.3
Patch Changes
f6a6d26Thanks @jackjin1997! - fix:SqliteSaver.putWritesnow honorsWRITES_IDX_MAP, pinning special channels (__error__,__scheduled__,__interrupt__,__resume__) to fixed negative indices instead of the call-local ordinal. Previously a follow-upputWrites([[INTERRUPT, …]], taskId)for the same checkpoint silentlyREPLACEd the regular write previously stored atidx=0for that task, losing data. The conflict-resolution clause also now matches the Python checkpointer contract:OR REPLACEonly when every channel is a special one (so e.g. INTERRUPT→RESUME state transitions overwrite),OR IGNOREotherwise.@langchain/angular@1.0.21
Patch Changes
#2515
49b8c1aThanks @christian-bromann! - fix: make AnyStream a true supertype so selector hooks need no castA concrete
useStream<typeof agent>()handle was not assignable toAnyStreambecause generic-computed covariant members (toolCalls,values) don't widen underany—InferToolCalls<any>[]resolves toAssembledToolCall<…, never>[], narrower than a concrete handle. Overridethose members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte,
ShallowReffor Vue,Signalfor Angular) so the message/tool/value selector hooks accept afully-typed stream without an
as AnyStreamcast.@langchain/react@1.0.21
Patch Changes
#2515
49b8c1aThanks @christian-bromann! - fix: make AnyStream a true supertype so selector hooks need no castA concrete
useStream<typeof agent>()handle was not assignable toAnyStreambecause generic-computed covariant members (toolCalls,values) don't widen underany—InferToolCalls<any>[]resolves toAssembledToolCall<…, never>[], narrower than a concrete handle. Overridethose members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte,
ShallowReffor Vue,Signalfor Angular) so the message/tool/value selector hooks accept afully-typed stream without an
as AnyStreamcast.@langchain/svelte@1.0.21
Patch Changes
#2515
49b8c1aThanks @christian-bromann! - fix: make AnyStream a true supertype so selector hooks need no castA concrete
useStream<typeof agent>()handle was not assignable toAnyStreambecause generic-computed covariant members (toolCalls,values) don't widen underany—InferToolCalls<any>[]resolves toAssembledToolCall<…, never>[], narrower than a concrete handle. Overridethose members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte,
ShallowReffor Vue,Signalfor Angular) so the message/tool/value selector hooks accept afully-typed stream without an
as AnyStreamcast.@langchain/vue@1.0.21
Patch Changes
#2515
49b8c1aThanks @christian-bromann! - fix: make AnyStream a true supertype so selector hooks need no castA concrete
useStream<typeof agent>()handle was not assignable toAnyStreambecause generic-computed covariant members (toolCalls,values) don't widen underany—InferToolCalls<any>[]resolves toAssembledToolCall<…, never>[], narrower than a concrete handle. Overridethose members with their widest forms (preserving each framework's
reactivity wrapper — plain arrays for React/Svelte,
ShallowReffor Vue,Signalfor Angular) so the message/tool/value selector hooks accept afully-typed stream without an
as AnyStreamcast.@example/ai-elements@0.1.36
Patch Changes
01c67df,d12d269,a8e7659,49b8c1a,9e0201d,9b96f60,8e06ace,d65a920,2f6d873,a8b0036,4096933,801d955]:@examples/assistant-ui-claude@0.1.36
Patch Changes
01c67df,d12d269,a8e7659,49b8c1a,9e0201d,9b96f60,8e06ace,d65a920,2f6d873,a8b0036,4096933,801d955]:@examples/ui-angular@0.0.46
Patch Changes
01c67df,d12d269,a8e7659,49b8c1a,9e0201d,9b96f60,8e06ace,d65a920,2f6d873,a8b0036,4096933,801d955]:@examples/ui-multimodal@0.0.22
Patch Changes
01c67df,d12d269,a8e7659,49b8c1a,9e0201d,9b96f60,8e06ace,d65a920,2f6d873,a8b0036,4096933,801d955]:@examples/ui-react@0.0.22
Patch Changes
01c67df,d12d269,a8e7659,49b8c1a,9e0201d,9b96f60,8e06ace,d65a920,2f6d873,a8b0036,4096933,801d955]:langgraph@1.0.40
Patch Changes
01c67df,d12d269,a8e7659,9e0201d,9b96f60,8e06ace,d65a920,2f6d873,a8b0036,4096933,801d955]: