State schemas and reducers
An agent loop (module 2) is one prebuilt shape. A StateGraph is you drawing your own shape: named nodes, edges between them, and a typed state object that flows through and accumulates.
Impulse’s cold-mode heartbeat, sense then modulate then roll then route, is the system you love most. This module redraws it as an explicit StateGraph, parity-tested against src/strategy/dice.ts, rendered as a diagram, inspectable. It is the spine every later module upgrades.
State is a schema. You declare what the graph carries and how each field updates.
import {
StateGraph, StateSchema, ReducedValue, MessagesValue,
GraphNode, START, END, Command,
} from "@langchain/langgraph";
import * as z from "zod/v4";
const State = new StateSchema({
messages: MessagesValue,
retryCount: z.number().default(0),
allSteps: new ReducedValue(
z.array(z.string()).default(() => []),
{ inputSchema: z.string(), reducer: (cur, next) => [...cur, next] },
),
});Reducers decide how a field merges when a node returns an update. A plain zod field is last-write-wins. MessagesValue appends messages. ReducedValue lets you define custom merge logic: in the example above, a node returns a single string and the reducer appends it to a running array. Reducers are why concurrent or streamed updates do not clobber each other.
Try it yourself
What a reducer is for
Two parts. The second one is where the concept earns its keep, so give a concrete case rather than a category.
What is a reducer for, and when would last-write-wins be the wrong merge strategy?
Reveal answer
A reducer decides how a field's new value merges with its old value when a node returns an update. Last-write-wins is wrong whenever you want to accumulate rather than overwrite, for example a running log of steps taken (allSteps above) or an appended message history (MessagesValue) -- without a reducer, each node's update would clobber the previous one instead of adding to it.
StateSchema vs Annotation.Root
You open pod-factory's code and see Annotation.Root. What's the right read?
Show answer
Correct answer: A — Annotation.Root is the legacy style; StateSchema is the current idiom to write going forward
Annotation.Root is the older, legacy way of declaring graph state. pod-factory predates the current idiom. You should be able to read Annotation.Root fluently, but write new graphs with StateSchema.