AgentCanvas / Pages / Developer Guide / Core / Decisions / Dataflow / ADR-dataflow-002
2026-03-31
Date
2026-03-31
Status
accepted
Field
dataflow
Old ID
ADR-014

Context

AgentCanvas nodes manage persistent state via hidden _NodeStateProxy._state dicts — invisible, per-node, not checkpointable, not shareable. HistoryTracker accumulates action history in ctx.history_entries, LLMCallNode accumulates conversation messages in ctx.messages, PolicyForward holds RNN hidden states in ctx.rnn_states — all invisible on the canvas. If two nodes need the same accumulated data, one must wire through the other. There is no checkpoint, resume, or replay capability. LangGraph's channel system showed that making state a first-class concept (typed, reducered, visible) dramatically improves debuggability and composability.

Decision

(1) StateContainer — a dict of multiple named states, rendered as a visible canvas element with dashed violet border and database icon. Each container groups related states (e.g. "Navigation State" holds action_history, active_plan, step_count). Multiple containers per graph. (2) BaseState hierarchy — 4 reducer types as standalone dataclasses: AccumulatorState (list.append, max_size), LastWriteState (overwrite), CounterState (sum), EphemeralState (clears at IterOut). Barrier deferred until parallel execution (TODO #14). (3) Two-axis type system — each state has a reducer type (behaviour) and a value_type (data shape) from an extensible registry that is a superset of wire types: includes TEXT, ACTION, IMAGE + domain types like POINTCLOUD, OCCUPANCY_MAP, EMBEDDING. (4) State edges — a separate wire system from data edges. A state edge grants a node read/write access to a container. Not data-carrying — access grants only. Rendered as dashed violet lines, hidden by default, toggled via toolbar button. (5) GraphDefinition extensionStateDef, ContainerDef, StateEdgeDef dataclasses added. GraphDefinition gains containers and state_edges fields (empty by default for backward compatibility). (6) Executor integration — containers built from graph.containers after flatten_graph(). State edge index maps node_id → {container_ids}. Connected containers injected into ctx._containers before node fires. on_iter_boundary() called at IterOut (Ephemeral clears). Container snapshots included in nav_step WS broadcast. (7) Flatten support — composite expansion prefixes container IDs and remaps state edge references, same pattern as nodes/edges. (8) Node decomposition pattern — "fancy" nodes like HistoryTracker can be decomposed into composite graphs wrapping simpler nodes + state containers. Same ports from outside; visible state inside.

Alternatives

(a) Copy LangGraph's implicit global state model (all nodes see all channels) — rejected, loses the explicit visual wiring that makes AgentCanvas a canvas. (b) Make containers regular computation nodes with input/output ports — rejected, containers are passive storage, not computation; they shouldn't fire or participate in the ready queue. (c) Single container per graph (like LangGraph's single State TypedDict) — rejected, multiple containers allow grouping by domain (navigation vs spatial memory). (d) Untyped containers (hold Any) — rejected, value_type enables validation and visual cues matching the existing wire type system.

Rationale

State moves from being an implementation detail of node handlers to a first-class canvas element. This is the key enabler for: (1) visible debugging — researchers see what's accumulating, (2) shared state — multiple nodes access the same history without wiring through each other, (3) checkpointing — save/restore agent state for replay, (4) composability — HistoryTracker becomes a composite with visible internal state instead of a monolith with hidden ctx.*. The dual-wire architecture keeps the simple case simple (graphs without containers work unchanged) while enabling the complex case. The design is dataflow-centric (edges carry data, containers store state) rather than state-centric (LangGraph: channels carry data AND trigger execution), matching the visual canvas paradigm.

Affected docs

architecture.md, glossary.md, blueprint.md, roadmap.md, design-docs/state-containers.md