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.0.3 ### Patch Changes - [#2352](https://github.com/langchain-ai/langgraphjs/pull/2352) [`14f2a79`](https://github.com/langchain-ai/langgraphjs/commit/14f2a796912e81d7f52f0a4f16747f6d0a269209) Thanks [@Nagendhra-web](https://github.com/Nagendhra-web)! - fix(langgraph-checkpoint): block prototype pollution in MemorySaver via reserved storage keys `MemorySaver` previously embedded `thread_id`, `checkpoint_ns`, `checkpoint_id`, and `task_id` directly into property accesses on the nested plain objects `this.storage` and `this.writes`. A caller able to shape any of those fields (every quickstart, tutorial, and test fixture uses `MemorySaver` by default) could pass `"__proto__"`, `"constructor"`, or `"prototype"` and have the subsequent assignment mutate `Object.prototype`. From that point every plain object in the process inherits the injected property, breaking `for...in` loops, truthy short-circuits, and downstream serializers across unrelated code paths. CWE-1321. Adds an `assertSafeStorageKey` chokepoint applied at every public entry that touches `storage` or `writes` (`put`, `putWrites`, `deleteThread`, `getTuple`, `list`). The guard rejects non-string values, the empty string (unless explicitly opted-in for `checkpoint_ns`), and the three prototype-pollution keys. Behaviour for valid string identifiers is unchanged. ## @langchain/langgraph-checkpoint-redis@1.0.6 ### Patch Changes - [#2350](https://github.com/langchain-ai/langgraphjs/pull/2350) [`1e73c6b`](https://github.com/langchain-ai/langgraphjs/commit/1e73c6b4630bbc4aa976eea4bfc33c4f753b7ee9) Thanks [@Nagendhra-web](https://github.com/Nagendhra-web)! - fix(checkpoint-redis): block Redis KEYS / SCAN pattern injection via top-level identifiers `RedisSaver` and `ShallowRedisSaver` previously embedded `thread_id`, `checkpoint_ns`, `checkpoint_id`, and `task_id` directly into Redis keys and `client.keys(pattern)` calls with no validation. A caller able to shape any of those fields (multi-tenant SDK deployments where the `RunnableConfig` originates from request input, or webhook payloads that flow into a persisted thread) could promote a string identifier into a glob pattern (`*`, `?`, `[...]`) or escape character (`\`). The most severe sink is `deleteThread`: a `threadId` of `*` issues `client.keys("checkpoint:*:*")` followed by `client.del(...)`, deleting every checkpoint in the database across every tenant. `getTuple`, `list`, and `loadPendingWrites` are exposed to the same pattern via the fallback paths that bypass the existing `escapeRediSearchTagValue` defense. Adds a single `assertSafeKeyComponent` helper exported from `./utils.js` and applies it at every key-building site. The guard asserts the value is a non-empty string (the empty `checkpoint_ns` default is opt-in via `{ allowEmpty: true }`) and rejects the Redis pattern meta-characters `* ? [ ] \`. The `:` delimiter is intentionally permitted because LangGraph emits it as a legitimate part of `checkpoint_ns` for subgraphs / nested graphs, where it only ever appears as a literal in the key. Behavior for valid string identifiers is unchanged. ## @langchain/langgraph-api@1.2.3 ### Patch Changes - [#2447](https://github.com/langchain-ai/langgraphjs/pull/2447) [`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: fold forkFrom client-side and honor per-run multitaskStrategy The SDK now folds the ergonomic `forkFrom` option into `config.configurable.checkpoint_id` before sending `run.start`, so the agent server only ever accepts the single, legacy-compliant fork field (`forkFrom` no longer hits the wire). The protocol-v2 reference servers drop their top-level `forkFrom` normalization accordingly. The protocol-v2 servers now honor the caller's `multitaskStrategy` per run (one of `reject` \| `rollback` \| `interrupt` \| `enqueue`) instead of hardcoding it, falling back to `enqueue` when omitted or unrecognized. - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - [#2448](https://github.com/langchain-ai/langgraphjs/pull/2448) [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: add `respondAll()` and run config/metadata on interrupt resume The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a `respondAll(responsesById, options)` method to resume several interrupts pending at the same checkpoint in a single command — required for runs that pause on multiple interrupts at once (e.g. parallel tool-authorization prompts), which sequential `respond()` calls cannot handle. `respond()` now takes an options object (`{ interruptId?, namespace?, config?, metadata? }`) so a resumed run can carry the same run-level config (model, user context, …) and metadata (trigger source, test flags, …) a fresh `submit()` would. The protocol-v2 reference servers read the new `responses` batch and `config` / `metadata` fields leniently and fold them onto the run that services the `input.respond` command. - Updated dependencies \[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532)]: - @langchain/langgraph-ui@1.2.3 ## @langchain/langgraph-cli@1.2.3 ### Patch Changes - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-api@1.2.3 ## @langchain/langgraph-ui@1.2.3 ### Patch Changes - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. ## @langchain/langgraph-sdk@1.9.10 ### Patch Changes - [#2447](https://github.com/langchain-ai/langgraphjs/pull/2447) [`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: fold forkFrom client-side and honor per-run multitaskStrategy The SDK now folds the ergonomic `forkFrom` option into `config.configurable.checkpoint_id` before sending `run.start`, so the agent server only ever accepts the single, legacy-compliant fork field (`forkFrom` no longer hits the wire). The protocol-v2 reference servers drop their top-level `forkFrom` normalization accordingly. The protocol-v2 servers now honor the caller's `multitaskStrategy` per run (one of `reject` \| `rollback` \| `interrupt` \| `enqueue`) instead of hardcoding it, falling back to `enqueue` when omitted or unrecognized. - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - [#2448](https://github.com/langchain-ai/langgraphjs/pull/2448) [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: add `respondAll()` and run config/metadata on interrupt resume The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a `respondAll(responsesById, options)` method to resume several interrupts pending at the same checkpoint in a single command — required for runs that pause on multiple interrupts at once (e.g. parallel tool-authorization prompts), which sequential `respond()` calls cannot handle. `respond()` now takes an options object (`{ interruptId?, namespace?, config?, metadata? }`) so a resumed run can carry the same run-level config (model, user context, …) and metadata (trigger source, test flags, …) a fresh `submit()` would. The protocol-v2 reference servers read the new `responses` batch and `config` / `metadata` fields leniently and fold them onto the run that services the `input.respond` command. ## @langchain/angular@1.0.10 ### Patch Changes - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - [#2448](https://github.com/langchain-ai/langgraphjs/pull/2448) [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: add `respondAll()` and run config/metadata on interrupt resume The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a `respondAll(responsesById, options)` method to resume several interrupts pending at the same checkpoint in a single command — required for runs that pause on multiple interrupts at once (e.g. parallel tool-authorization prompts), which sequential `respond()` calls cannot handle. `respond()` now takes an options object (`{ interruptId?, namespace?, config?, metadata? }`) so a resumed run can carry the same run-level config (model, user context, …) and metadata (trigger source, test flags, …) a fresh `submit()` would. The protocol-v2 reference servers read the new `responses` batch and `config` / `metadata` fields leniently and fold them onto the run that services the `input.respond` command. - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-sdk@1.9.10 ## @langchain/react@1.0.10 ### Patch Changes - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - [#2448](https://github.com/langchain-ai/langgraphjs/pull/2448) [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: add `respondAll()` and run config/metadata on interrupt resume The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a `respondAll(responsesById, options)` method to resume several interrupts pending at the same checkpoint in a single command — required for runs that pause on multiple interrupts at once (e.g. parallel tool-authorization prompts), which sequential `respond()` calls cannot handle. `respond()` now takes an options object (`{ interruptId?, namespace?, config?, metadata? }`) so a resumed run can carry the same run-level config (model, user context, …) and metadata (trigger source, test flags, …) a fresh `submit()` would. The protocol-v2 reference servers read the new `responses` batch and `config` / `metadata` fields leniently and fold them onto the run that services the `input.respond` command. - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-sdk@1.9.10 ## @langchain/svelte@1.0.10 ### Patch Changes - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - [#2448](https://github.com/langchain-ai/langgraphjs/pull/2448) [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: add `respondAll()` and run config/metadata on interrupt resume The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a `respondAll(responsesById, options)` method to resume several interrupts pending at the same checkpoint in a single command — required for runs that pause on multiple interrupts at once (e.g. parallel tool-authorization prompts), which sequential `respond()` calls cannot handle. `respond()` now takes an options object (`{ interruptId?, namespace?, config?, metadata? }`) so a resumed run can carry the same run-level config (model, user context, …) and metadata (trigger source, test flags, …) a fresh `submit()` would. The protocol-v2 reference servers read the new `responses` batch and `config` / `metadata` fields leniently and fold them onto the run that services the `input.respond` command. - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-sdk@1.9.10 ## @langchain/vue@1.0.10 ### Patch Changes - [#2443](https://github.com/langchain-ai/langgraphjs/pull/2443) [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532) Thanks [@christian-bromann](https://github.com/christian-bromann)! - refactor(sdk): drop StreamSubmitOptions.command and simplify forkFrom Remove the misleading submit({ command }) surface from protocol-v2 StreamController; HITL resume is respond() only. Accept forkFrom as a plain checkpoint id string and align protocol-v2 servers and docs. - [#2448](https://github.com/langchain-ai/langgraphjs/pull/2448) [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d) Thanks [@christian-bromann](https://github.com/christian-bromann)! - protocol-v2: add `respondAll()` and run config/metadata on interrupt resume The stream controller (and the React/Angular/Svelte/Vue wrappers) gain a `respondAll(responsesById, options)` method to resume several interrupts pending at the same checkpoint in a single command — required for runs that pause on multiple interrupts at once (e.g. parallel tool-authorization prompts), which sequential `respond()` calls cannot handle. `respond()` now takes an options object (`{ interruptId?, namespace?, config?, metadata? }`) so a resumed run can carry the same run-level config (model, user context, …) and metadata (trigger source, test flags, …) a fresh `submit()` would. The protocol-v2 reference servers read the new `responses` batch and `config` / `metadata` fields leniently and fold them onto the run that services the `input.respond` command. - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-sdk@1.9.10 ## @example/ai-elements@0.1.25 ### Patch Changes - Updated dependencies \[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/react@1.0.10 ## @examples/assistant-ui-claude@0.1.25 ### Patch Changes - Updated dependencies \[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/react@1.0.10 ## @examples/ui-angular@0.0.35 ### Patch Changes - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-sdk@1.9.10 - @langchain/angular@1.0.10 ## @examples/ui-multimodal@0.0.11 ### Patch Changes - Updated dependencies \[[`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/react@1.0.10 ## @examples/ui-react@0.0.11 ### Patch Changes - Updated dependencies \[[`80c2806`](https://github.com/langchain-ai/langgraphjs/commit/80c2806cb2da93745a640664bd0cf603c2361da9), [`80a8c12`](https://github.com/langchain-ai/langgraphjs/commit/80a8c1200a240fd984edc4deb26a7787d08c7532), [`2c14b12`](https://github.com/langchain-ai/langgraphjs/commit/2c14b12a80c306578563e77595943037c7c4844d)]: - @langchain/langgraph-sdk@1.9.10 - @langchain/react@1.0.10 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@langchain/langgraph-sdk
The JavaScript / TypeScript SDK for talking to a LangGraph API server. Use it to create and manage assistants, threads, runs, cron schedules, and the KV store — and, most importantly, to stream graph executions in real time.
Install
pnpm add @langchain/langgraph-sdk @langchain/core
# or: npm install @langchain/langgraph-sdk @langchain/core
# or: yarn add @langchain/langgraph-sdk @langchain/core
Quick start
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: "http://localhost:2024" });
// Open a thread-centric stream (the recommended way to stream).
const thread = client.threads.stream({ assistantId: "my-agent" });
await thread.run.start({
input: { messages: [{ role: "user", content: "hello" }] },
});
for await (const message of thread.messages) {
for await (const token of message.text) {
process.stdout.write(token);
}
}
console.log(await thread.output);
await thread.close();
With no apiUrl, the SDK points at http://localhost:2024 (the
default langgraph dev URL).
What's in the SDK
| Sub-client | Purpose | Docs |
|---|---|---|
client.threads |
Create threads, manage state, and stream runs. | Threads · Streaming |
client.assistants |
CRUD for assistants (schemas, graphs, versions). | Assistants |
client.runs |
Trigger / join / cancel runs without streaming. | Runs (legacy) |
client.crons |
Schedule recurring runs. | Crons |
client.store |
Namespaced KV + semantic store. | Store |
Streaming
client.threads.stream(...) returns a ThreadStream
with typed, lazy projections for every aspect of a run:
thread.messages/thread.toolCalls— assembled chat output.thread.values/thread.output— graph state and final answer.thread.interrupts/thread.interrupted— human-in-the-loop.thread.subgraphs/thread.subagents— nested / deep-agent work.thread.extensions.<name>— typed custom server projections.thread.audio/thread.images/thread.video/thread.files— media.
Deprecated. The generator-based streaming APIs on
client.runs.*(stream,joinStream) andclient.threads.joinStreamare preserved for backwards compatibility only. New code should useclient.threads.stream(...). See Runs (legacy) for migration guidance.
Transports
Streaming defaults to Server-Sent Events (SSE) over HTTP. You can
switch to WebSocket per-call or globally, or plug in a custom
AgentServerAdapter:
const thread = client.threads.stream({
assistantId: "my-agent",
transport: "websocket",
});
See Transports for full details.
Framework adapters
If you're building a UI, use the framework-specific packages that wrap this SDK:
@langchain/langgraph-sdk/react@langchain/langgraph-sdk/vue@langchain/langgraph-sdk/svelte@langchain/langgraph-sdk/angular
Use the SDK directly when you need low-level control, run it from a non-browser environment (Node.js server, edge workers, scripts), or integrate into a framework that does not yet have a first-party adapter.
Architecture
The client code is organized into sub-client modules under
src/client/:
| Path | Module |
|---|---|
client/assistants/ |
AssistantsClient |
client/threads/ |
ThreadsClient (includes the v2 stream(...) primitive) |
client/runs/ |
RunsClient (legacy streaming + CRUD) |
client/crons/ |
CronsClient |
client/store/ |
StoreClient |
client/stream/ |
ThreadStream, assemblers, transports |
client/base.ts |
BaseClient, shared config & helpers |
client/index.ts |
Main Client class & re-exports |
Change log
See CHANGELOG.md.