[PR #1842] [MERGED] feat(langgraph): introduce StateSchema, ReducedValue, and UntrackedValue #1768

Closed
opened 2026-02-15 20:16:46 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/langgraphjs/pull/1842
Author: @hntrl
Created: 1/6/2026
Status: Merged
Merged: 1/15/2026
Merged by: @dqbd

Base: mainHead: hunetr/state


📝 Commits (9)

📊 Changes

36 files changed (+3227 additions, -734 deletions)

View changed files

.changeset/tame-houses-happen.md (+5 -0)
📝 libs/langgraph-core/.eslintrc.cjs (+7 -1)
📝 libs/langgraph-core/package.json (+2 -1)
📝 libs/langgraph-core/src/channels/index.ts (+1 -0)
libs/langgraph-core/src/channels/untracked_value.ts (+113 -0)
📝 libs/langgraph-core/src/errors.ts (+38 -0)
📝 libs/langgraph-core/src/graph/index.ts (+2 -3)
📝 libs/langgraph-core/src/graph/message.test.ts (+2 -194)
📝 libs/langgraph-core/src/graph/message.ts (+1 -75)
📝 libs/langgraph-core/src/graph/messages_annotation.ts (+1 -1)
libs/langgraph-core/src/graph/messages_reducer.test.ts (+194 -0)
libs/langgraph-core/src/graph/messages_reducer.ts (+131 -0)
📝 libs/langgraph-core/src/graph/state.ts (+123 -39)
📝 libs/langgraph-core/src/graph/zod/plugin.ts (+10 -16)
📝 libs/langgraph-core/src/prebuilt/react_agent_executor.ts (+1 -1)
📝 libs/langgraph-core/src/pregel/algo.ts (+31 -0)
📝 libs/langgraph-core/src/pregel/loop.ts (+39 -2)
libs/langgraph-core/src/state/adapter.test.ts (+156 -0)
libs/langgraph-core/src/state/adapter.ts (+78 -0)
libs/langgraph-core/src/state/index.ts (+14 -0)

...and 16 more files

📄 Description

This PR introduces StateSchema, a new unified API for defining LangGraph state schemas with first-class TypeScript type inference and support for any Standard Schema compliant library (Zod 3, Zod 4, Valibot, ArkType, etc.).

The new API provides a more intuitive and type-safe way to define graph state, with dedicated value types for common patterns like reducers and transient values.

Changes

New StateSchema API

libs/langgraph-core/src/state/ - New state definition module

  • StateSchema class - Main entry point for defining state schemas with automatic type inference for State and Update types
  • ReducedValue - Define fields with custom reducers (replaces manual BinaryOperatorAggregate setup)
  • UntrackedValue - Define transient fields that are not persisted to checkpoints
  • MessagesValue - Prebuilt value type for message arrays with the standard messages reducer

Example usage:

import { z } from "zod";
import { StateSchema, ReducedValue, MessagesValue } from "@langchain/langgraph";

const AgentState = new StateSchema({
  messages: MessagesValue,
  count: z.number().default(0),
  history: new ReducedValue(
    z.array(z.string()).default(() => []),
    {
      inputSchema: z.string(),
      reducer: (current, next) => [...current, next],
    }
  ),
});

// Types are automatically inferred
type State = typeof AgentState.State;
type Update = typeof AgentState.Update;

const graph = new StateGraph(AgentState)
  .addNode("node", (state) => ({ count: state.count + 1 }))
  // ...

New UntrackedValueChannel

libs/langgraph-core/src/channels/untracked_value.ts - New channel type

  • Stores values during execution but does NOT persist to checkpoints
  • Useful for transient state like database connections, caches, or runtime configuration
  • Automatically resets to initial value on checkpoint restore

Type Preservation Fixes

libs/langgraph-core/src/graph/state.ts

  • Fixed ExtractStateDefinition to preserve StateSchema type information instead of washing it to generic StateDefinition
  • Updated CompiledStateGraph to use ExtractStateType and ExtractUpdateType for proper type flow
  • State and Update types are now correctly preserved through StateGraph compilation

Refactoring

libs/langgraph-core/src/graph/messages_reducer.ts - Extracted from message.ts

  • Moved messagesStateReducer and REMOVE_ALL_MESSAGES to dedicated file
  • Added JSDoc documentation for the reducer function
  • Uses RemoveMessage.isInstance() for proper type checking

libs/langgraph-core/src/pregel/algo.ts & loop.ts

  • Added sanitizeUntrackedValuesInSend to remove untracked values from Send packets before checkpointing
  • Filter out UntrackedValueChannel writes during checkpoint saves

Other Changes

  • libs/langgraph-core/src/state/adapter.ts - Schema adapter utilities for Standard Schema support
  • libs/langgraph-core/src/state/types.ts - Type definitions and type guards
  • libs/langgraph-core/src/errors.ts - Added StateGraphInputError for better error messages
  • libs/langgraph-core/src/graph/zod/plugin.ts - Fixed Zod plugin types for v3/v4 compatibility
  • Updated Zod peer dependency to ^3.25.32 || ^4.2.0

Tests

  • Comprehensive test suite for StateSchema including type inference, channel creation, and StateGraph integration
  • Tests for ReducedValue, UntrackedValue, and UntrackedValueChannel
  • Type-level tests verifying proper type preservation through compilation

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/langgraphjs/pull/1842 **Author:** [@hntrl](https://github.com/hntrl) **Created:** 1/6/2026 **Status:** ✅ Merged **Merged:** 1/15/2026 **Merged by:** [@dqbd](https://github.com/dqbd) **Base:** `main` ← **Head:** `hunetr/state` --- ### 📝 Commits (9) - [`037a253`](https://github.com/langchain-ai/langgraphjs/commit/037a253d735dfa74dd5785bcb82a5c9d08b6fc5b) feat(langgraph): introduce StateSchema, ReducedValue, and UntrackedValue - [`5a465bf`](https://github.com/langchain-ai/langgraphjs/commit/5a465bf1bd708b9772417fc4e6441560b8126dc0) Create tame-houses-happen.md - [`90c0655`](https://github.com/langchain-ai/langgraphjs/commit/90c06550cc78e6c7d5c3f8f4d1095c191af20e08) cr - [`d24f4b3`](https://github.com/langchain-ai/langgraphjs/commit/d24f4b394f8d25381d66514b721d7ef46f7dfdf6) cr - [`1f46adc`](https://github.com/langchain-ai/langgraphjs/commit/1f46adc875692c8daea7439c3f2b9abda212ee8d) cr - [`85cac2c`](https://github.com/langchain-ai/langgraphjs/commit/85cac2c25a4fb32cec524178582c993e4e80698d) pin zod - [`665417f`](https://github.com/langchain-ai/langgraphjs/commit/665417fe0d5739b5b19b01fe4434786657e648f5) cr - [`14e5bf1`](https://github.com/langchain-ai/langgraphjs/commit/14e5bf10b76f871dbc4a50c91a4b831944cd992b) cr - [`f5bb20e`](https://github.com/langchain-ai/langgraphjs/commit/f5bb20e1224a6b9180886722e40a07830426e5e5) Update changeset ### 📊 Changes **36 files changed** (+3227 additions, -734 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/tame-houses-happen.md` (+5 -0) 📝 `libs/langgraph-core/.eslintrc.cjs` (+7 -1) 📝 `libs/langgraph-core/package.json` (+2 -1) 📝 `libs/langgraph-core/src/channels/index.ts` (+1 -0) ➕ `libs/langgraph-core/src/channels/untracked_value.ts` (+113 -0) 📝 `libs/langgraph-core/src/errors.ts` (+38 -0) 📝 `libs/langgraph-core/src/graph/index.ts` (+2 -3) 📝 `libs/langgraph-core/src/graph/message.test.ts` (+2 -194) 📝 `libs/langgraph-core/src/graph/message.ts` (+1 -75) 📝 `libs/langgraph-core/src/graph/messages_annotation.ts` (+1 -1) ➕ `libs/langgraph-core/src/graph/messages_reducer.test.ts` (+194 -0) ➕ `libs/langgraph-core/src/graph/messages_reducer.ts` (+131 -0) 📝 `libs/langgraph-core/src/graph/state.ts` (+123 -39) 📝 `libs/langgraph-core/src/graph/zod/plugin.ts` (+10 -16) 📝 `libs/langgraph-core/src/prebuilt/react_agent_executor.ts` (+1 -1) 📝 `libs/langgraph-core/src/pregel/algo.ts` (+31 -0) 📝 `libs/langgraph-core/src/pregel/loop.ts` (+39 -2) ➕ `libs/langgraph-core/src/state/adapter.test.ts` (+156 -0) ➕ `libs/langgraph-core/src/state/adapter.ts` (+78 -0) ➕ `libs/langgraph-core/src/state/index.ts` (+14 -0) _...and 16 more files_ </details> ### 📄 Description This PR introduces `StateSchema`, a new unified API for defining LangGraph state schemas with first-class TypeScript type inference and support for any Standard Schema compliant library (Zod 3, Zod 4, Valibot, ArkType, etc.). The new API provides a more intuitive and type-safe way to define graph state, with dedicated value types for common patterns like reducers and transient values. ## Changes ### New `StateSchema` API **`libs/langgraph-core/src/state/`** - New state definition module - **`StateSchema`** class - Main entry point for defining state schemas with automatic type inference for `State` and `Update` types - **`ReducedValue`** - Define fields with custom reducers (replaces manual `BinaryOperatorAggregate` setup) - **`UntrackedValue`** - Define transient fields that are not persisted to checkpoints - **`MessagesValue`** - Prebuilt value type for message arrays with the standard messages reducer Example usage: ```typescript import { z } from "zod"; import { StateSchema, ReducedValue, MessagesValue } from "@langchain/langgraph"; const AgentState = new StateSchema({ messages: MessagesValue, count: z.number().default(0), history: new ReducedValue( z.array(z.string()).default(() => []), { inputSchema: z.string(), reducer: (current, next) => [...current, next], } ), }); // Types are automatically inferred type State = typeof AgentState.State; type Update = typeof AgentState.Update; const graph = new StateGraph(AgentState) .addNode("node", (state) => ({ count: state.count + 1 })) // ... ``` ### New `UntrackedValueChannel` **`libs/langgraph-core/src/channels/untracked_value.ts`** - New channel type - Stores values during execution but does NOT persist to checkpoints - Useful for transient state like database connections, caches, or runtime configuration - Automatically resets to initial value on checkpoint restore ### Type Preservation Fixes **`libs/langgraph-core/src/graph/state.ts`** - Fixed `ExtractStateDefinition` to preserve `StateSchema` type information instead of washing it to generic `StateDefinition` - Updated `CompiledStateGraph` to use `ExtractStateType` and `ExtractUpdateType` for proper type flow - State and Update types are now correctly preserved through `StateGraph` compilation ### Refactoring **`libs/langgraph-core/src/graph/messages_reducer.ts`** - Extracted from `message.ts` - Moved `messagesStateReducer` and `REMOVE_ALL_MESSAGES` to dedicated file - Added JSDoc documentation for the reducer function - Uses `RemoveMessage.isInstance()` for proper type checking **`libs/langgraph-core/src/pregel/algo.ts`** & **`loop.ts`** - Added `sanitizeUntrackedValuesInSend` to remove untracked values from `Send` packets before checkpointing - Filter out `UntrackedValueChannel` writes during checkpoint saves ### Other Changes - **`libs/langgraph-core/src/state/adapter.ts`** - Schema adapter utilities for Standard Schema support - **`libs/langgraph-core/src/state/types.ts`** - Type definitions and type guards - **`libs/langgraph-core/src/errors.ts`** - Added `StateGraphInputError` for better error messages - **`libs/langgraph-core/src/graph/zod/plugin.ts`** - Fixed Zod plugin types for v3/v4 compatibility - Updated Zod peer dependency to `^3.25.32 || ^4.2.0` ### Tests - Comprehensive test suite for `StateSchema` including type inference, channel creation, and StateGraph integration - Tests for `ReducedValue`, `UntrackedValue`, and `UntrackedValueChannel` - Type-level tests verifying proper type preservation through compilation --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-15 20:16:46 -05:00
yindo closed this issue 2026-02-15 20:16:46 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#1768