API Reference¶
Event Taxonomy¶
| Export | Type | Description |
|---|---|---|
Namespace |
Base class | Namespace for nested commands and outcomes; exposes __namespace_name__, __reducers__. Names are unique per graph, not per process — see namespace scope |
Command |
Base class | Imperative intent; must be nested inside a Namespace, and may not itself be subclassed once declared (class Rush(Order.Place) is a TypeError). Auto-exposes .Outcomes — union of nested DomainEvents. A handle method on the class registers as the command's inline handler when passed to EventGraph |
DomainEvent |
Base class | Fact inside the domain; must be nested inside a Namespace or Command |
IntegrationEvent |
Base class | Cross-boundary fact; top-level |
SystemEvent |
Base class | Framework-emitted fact; top-level |
InvariantViolated |
Event | Emitted when an invariants= predicate returns false |
Mixins¶
| Export | Type | Description |
|---|---|---|
Auditable |
Mixin | Marker for auto-logged events; trail() returns a compact summary. Compose with any event branch |
MessageEvent |
Mixin | Wraps LangChain BaseMessage; declares message or messages field. Compose with any event branch |
SystemPromptSet |
Event | Built-in IntegrationEvent + MessageEvent for system prompts |
Event |
Internal | Base class (not user-facing). Valid as type annotation and reducer event_type= catch-all |
Handler Subscription¶
@on subscribes a handler. Three shapes:
- Bare
@on— event type inferred from the first parameter's annotation. @on(kwargs=...)— inferred, with modifiers.@on(Type, ...)— explicit; required for multi-event subscription.
Modifiers:
*field_matchers— field dispatch;typevalues doisinstance,strvalues do equality.raises=— declared exceptions.retry=RetryPolicy(...)— declarative backoff around the handler call. Spelled as aretryclass attribute on aCommand, alongsideraises/invariants.invariants={InvariantClass: predicate}— preconditions.node_name=— pin a stable node identity (defaults to the function name) so renaming the function never breaks an interrupted checkpoint.previously=(str or tuple) — historic node names to keep resumable after a rename. These, andretry=, are reserved (a field namednode_name/previously/retrycan't be matched via**field_matchers; aCommanddeclaring an annotatedretryfield also fails at class creation — useretry: ClassVar = ...for the policy, or rename the field). InlineCommand.handle()handlers default their node identity to the command's__qualname__(e.g.Order.Place), not the method name, so it is stable regardless ofhandlers=[...]order; a renamed command declares its historic node names as a class attribute,previously: ClassVar = (...), mirroringraises/invariantsin spelling. All four are read off the command class that declares them — a concreteCommandmay not be subclassed, so a historic node name still identifies exactly one class. See Handler renames.
Returns enforced against the declared annotation, or the subscribed Command.Outcomes when unannotated. Omitting the return annotation is legal. An annotation that does not resolve at run time is not, and raises TypeError at graph construction — see Concepts › Return contract.
Graph & Execution¶
| Export | Type | Description |
|---|---|---|
EventGraph |
Class | Build and run the event-driven graph; accepts @on-decorated functions and/or Command subclasses with inline handle. services=[...] (type-keyed) or services={...} (name-keyed) injects project dependencies into handler params (see Concepts › Signature injection). Type-keyed matching needs an annotation that resolves at run time; name-keyed matching needs no annotation, but an annotation that is present is checked against the registered value at graph build. on_unresumable="raise"\|"halt"\|"warn" (default "raise") governs resume() on a thread not awaiting input |
RunScoped |
Class | Marker for a service derived per run. Place RunScoped(factory) in the name-keyed services={...} mapping. The factory is called with the node's RunnableConfig once per node call. Its result is injected under the handler's parameter name. The factory must have a return annotation. The framework checks it against the handler parameter at graph build (see Concepts › Run-scoped services) |
EventGraph.from_namespaces() |
Classmethod | Build a graph from domains' inline command handlers; handlers= appends external handlers. With checkpointer=MemorySaver() auto-wires a NamespaceAwareSerde scoped to the passed namespaces and auto-collects every @migrate_from / @backfill decorator on those classes. Opt out by passing MemorySaver(serde=<custom>) — a user-supplied serde always wins |
EventGraph.invoke() / .ainvoke() |
Method | Run (sync/async); returns EventLog |
EventGraph.resume() / .aresume() |
Method | Resume an interrupted graph (requires checkpointer) |
EventGraph.abandon() / .aabandon() |
Method | Settles a paused thread without answering its interrupt. require_interrupt=True (default) raises ValueError if the thread has no pending interrupt. Pass False to settle it anyway, recording discarded="". Requires a checkpointer. Raises ValueError if the thread has no events to settle (never run, or only pre_seed()ed). Returns None. See Ending a pause without answering it |
EventGraph.threads_paused_on() / .athreads_paused_on() |
Method | Configs for each listed thread whose latest checkpoint has a pending interrupt, optionally filtered to an Interrupted class or subclass. thread_ids= is required: the caller names the threads, and the library does not walk the store. Get the ids from a server-side query. With event_type=None, returns every listed thread that is paused. thread_ids=None or a bare str raises TypeError. Requires a checkpointer. See Finding candidates server-side and Ending a pause without answering it |
EventGraph.unrevivable_threads() / .aunrevivable_threads() |
Method | Mapping of thread id to the qualnames its latest checkpoint can no longer revive, wherever the serde met them: settled history, pending interrupt, completed sibling write, or a field nested in a live event. Empty when every listed thread revives. Reads the store, not the baseline, so it sees a settled thread the coverage gates cannot. thread_ids= is required, the same as for threads_paused_on(). To sweep every thread, get the ids from one SELECT DISTINCT thread_id FROM checkpoints WHERE checkpoint_ns = '' query. If one checkpointer stores more than one graph, keep only the thread ids of this graph. Thread ids keep the caller's order, without duplicates. Requires a checkpointer with a NamespaceAwareSerde, raises ValueError otherwise. See Retiring an Interrupted subclass |
EventGraph.plan_rewrite() / .aplan_rewrite() |
Method | RewriteReport of the rewrite each listed thread needs, after the same verification as rewrite_store(). Writes nothing. drop= names event classes whose stored instances leave the log. thread_ids= is required, the same as for threads_paused_on(). To sweep every thread, get the ids from one SELECT DISTINCT thread_id FROM checkpoints WHERE checkpoint_ns = '' query. If one checkpointer stores more than one graph, keep only the thread ids of this graph. A listed id with no checkpoint is reported as refused. Requires a checkpointer with a NamespaceAwareSerde and legacy_write=False, raises ValueError otherwise. See Rewriting the live set |
EventGraph.rewrite_store() / .arewrite_store() |
Method | Rewrites the latest checkpoint of each listed thread under the live migration table, through the checkpointer's put() under the same checkpoint id, and drops the stored instances of each drop= class from events and _pending. It filters causes at the same positions and remaps each source. A cause whose source was dropped becomes SourceDropped(via, source_type). Same arguments and report as plan_rewrite(). A refused thread is not written; its reason says what to do. Run while the graph is idle, never inside a rolling deploy window, after a store-level backup. See Rewriting the live set |
EventGraph.get_state() |
Method | GraphState for a checkpointed thread |
EventGraph.namespaces() |
Method | Code-derived snapshot — domains, commands, outcomes, handlers, policies, edges, seeds. Returns a NamespaceModel |
NamespaceModel.text(view=...) |
Method | Human-readable tree; view="structure" or "choreography" (default) |
NamespaceModel.mermaid(namespace_order=..., reactor_hub_min=..., focus=..., show_raises=..., notes=..., muted=...) |
Method | Mermaid graph LR choreography diagram (handlers, policies, invariants, edges). namespace_order is "affinity" (default — cluster heavily-connected namespaces adjacent) or "alphabetical" (legacy, byte-stable for snapshot-pinned consumers). reactor_hub_min=N opts in to hub-style fanout: any (source, handler) producing ≥N solid-or-scatter targets renders as Source → Hub → {targets} with the handler name on the hub instead of repeated on every edge. focus=NamespaceModel.Focus(...) draws the selected items, every edge that touches one, the nodes at both ends dimmed as context, and every other edge between two drawn nodes; a selected reaction's solid edges are thick arrows, and a focused diagram draws no entry arrows. show_raises=False hides the (raises) edges. notes={key: text} adds lines under a label, and muted=[key, ...] fades what it names: a key is an event qualname, a reducer name, or a reaction name (its edges), so every Cause.via is a valid key. A wrong key raises ValueError that lists the valid keys. For a structure-only view use text(view="structure"). |
NamespaceModel.json() / .to_dict() |
Method | JSON-serializable snapshot (event classes encoded as qualnames). Top-level schema_version is bumped on field removal, rename, or semantic change; additions don't bump. |
NamespaceModel.{Namespace, Command, CommandHandler, Policy, Edge, Invariant} |
Nested dataclasses | Frozen dataclasses for programmatic access |
NamespaceModel.Edge |
Nested dataclass | source, via, target, kind (how produced: solid/scatter/raises/retry/framework), causation (causal role: intent/react/orchestrate/chain/None) |
NamespaceModel.reducers |
Field | Tuple of NamespaceModel.Reducer — every reducer with name, subscribes and namespace. subscribes holds the concrete events of the model that the reducer folds, resolved from event_type (unlike Policy.subscribes, which holds the declared types), or None when a runtime_checkable Protocol with data members makes the folds unknown. namespace is a name, or None for a reducer passed to EventGraph(reducers=...) |
NamespaceModel.Focus |
Nested dataclass | The part of the graph that mermaid(focus=...) draws. Fields namespaces, reactions, reducers each take one name or an iterable of names, stored sorted. At least one name is required: an empty Focus() raises ValueError. Valid names are list(model.namespaces), [r.name for r in model.reactions] and [r.name for r in model.reducers] |
NamespaceModel.invariants |
Field | Tuple of NamespaceModel.Invariant — every declared invariant with cls, commands, declared_by, reactors |
EventGraph.compiled |
Property | Underlying CompiledStateGraph escape hatch |
EventGraph.reducer_names |
Property | frozenset of registered reducer names |
EventGraph.reflect(log) |
Method | Deterministic query surface over a run — returns a Reflection (see Reflection) |
Reflection |
Class | Facts-only read-model: context(), tool(), overview(), event(i), evidence(i), schema(), state(), .log. Injectable into handlers by parameter annotation, like EventLog |
QueryTool |
Frozen dataclass | The query_log LLM tool: name / description / parameters (JSON Schema) / run(...) -> str. Maps 1:1 to Anthropic / LangChain tool shapes |
EventLog |
Class | Immutable query container (see Concepts). cause(e), effects(e) and flow(e) read the causes that the log records. causes is the tuple of causes aligned with events, or None when the log records no causes. EventLog(events, causes=...) builds a log with causes, and EventLog(log.events, causes=log.causes) rebuilds a root log. A log from after(), before() or select() answers like its root |
Cause |
Frozen dataclass | (source, via): the event that a handler received, and the handler's graph node name. Event stores call source the causation ID. Cause.source is an event, while Edge.source is a type. via equals Edge.via unless the handler has a stable identity: an inline command handler (via is the command qualname), or an @on(node_name=...) pin. via must be a str. Returned by EventLog.cause() |
UnknownCause |
Class | Base of every case where the cause of an event is unknown. reason states why in one sentence. A cause is unknown only for history that the framework did not record |
NotRecorded |
Frozen dataclass | UnknownCause: the event was written before causes existed, in a checkpoint saved by an older release |
SourceDropped |
Frozen dataclass | UnknownCause (via, source_type): a handler produced the event, but rewrite_store(drop=...) deleted its source. The handler and the qualname of the deleted event stay known |
FrameworkEvent |
Frozen dataclass | The framework wrote the event: RunPaused, MaxRoundsExceeded, Cancelled or Abandoned. EventLog.cause() returns None only for a seed |
GraphState |
NamedTuple | (events, is_interrupted, interrupted). events carries the recorded causes of the thread |
RewriteReport |
Dataclass | (applied, threads) from plan_rewrite() / rewrite_store(). applied is False from the plan. .refused is the tuple of refused threads. str(report) prints one summary line, then one line per refused thread |
ThreadRewrite |
Dataclass | One thread's line in a RewriteReport: thread_id, status ("rewrite", "unchanged" or "refused"), migrated as (stored, live) identity pairs, dropped counts per identity, and reason on a refusal |
System Events¶
| Export | Type | Description |
|---|---|---|
Halted |
Event | Signal immediate termination; subclass for domain-specific halts |
MaxRoundsExceeded |
Event | Halted subtype when max_rounds is exceeded |
Cancelled |
Event | Halted subtype when an async handler is cancelled |
Abandoned |
Event | Halted subtype emitted by EventGraph.abandon() or .aabandon(). .reason is the caller-supplied reason. .discarded holds the discarded interrupts' qualnames (e.g. Order.ApprovalRequested, not the bare ApprovalRequested). The qualname stays unambiguous under nesting and stable whether or not the class still imports. Values are deduped and joined with ", " ("" if none). Match with in or .split(", "), never ==. Recorded, not dispatched: @on(Abandoned) never fires |
Unresumable |
Event | Halted subtype emitted by EventGraph(on_unresumable="halt") when resume() hits a thread not awaiting input. .resume_value is the resume event's type name. See Handler renames. For a deliberate settle instead of this runtime net, see abandon() |
RunPaused |
Event | SystemEvent (not Halted) emitted by the router when a per-call deadline=monotonic()+budget expires between dispatch rounds. Emitted at most once per /run regardless of how many parallel handlers fan in past the deadline. Cursor is advanced past it so a fresh /run on the same thread_id continues normally. No default AG-UI wire mapping — register a custom EventMapper to surface it on the wire |
Interrupted |
Base class | Subclass with typed fields to pause for human input. For frontend-discriminated payloads see InterruptedWithPayload in langgraph_events.agui |
Resumed |
Event | Emitted on resume() with the dispatched event + interrupted backref |
HandlerRaised |
Event | Emitted when a handler raises a raises=-declared exception; carries handler, source_event, exception, abandoned_for_deadline. The exception keeps its traceback — this is the terminal failure, the one you debug from. With a retry= policy it fires only after the budget is spent, or — uniquely tagged abandoned_for_deadline=True — once the next backoff would land on or past the run's deadline=. The flag is False on every other raise |
HandlerRetried |
Event | Emitted before each retry= backoff wait; carries handler, source_event, exception, attempt (1-based, the call that failed), delay_seconds. The exception instance is live (matchers and field injection work) but its __traceback__ is detached — as are those of its __cause__/__context__ chain and any ExceptionGroup members — so a breadcrumb never pins the failed attempt's frame; see Retries. A deadline give-up emits none, since no wait happened. Suppress with RetryPolicy(observe="log"\|"silent") |
RetryPolicy |
Class | Declarative retry for a handler call: max_attempts (counts the initial call), base_delay, max_delay, strategy ("exponential"/"constant"), jitter (full jitter, default True), on= (must overlap raises=, in either direction), respect_retry_after, observe. Distinct from langgraph.types.RetryPolicy, which re-runs a whole node |
Invariant |
Marker class | Subclass to declare a typed invariant; used as a dict key in invariants= and as the matcher value in @on(InvariantViolated, invariant=...) |
InvariantViolated |
Event | Emitted when an invariants= predicate returns false; carries invariant (instance of the declared Invariant subclass), handler, source_event. Use @on(InvariantViolated, invariant=SomeInvariant) to pin to a specific invariant |
Scatter |
Class | Fan-out into multiple events. Return type must enumerate concrete events (Scatter[WorkItem] or Scatter[A \| B]); bare Scatter, Scatter[Any], Scatter[Event], and Scatter[T] (TypeVar) are rejected at graph construction with TypeError |
Reducers¶
| Export | Type | Description |
|---|---|---|
Reducer |
Class | List accumulator; declare as Namespace class attribute or pass via reducers= |
ScalarReducer |
Class | Last-write-wins for a single value; None is valid |
FoldReducer |
Class | Folds each event into accumulating state via fold(self, state); next value depends on the prior. Generic over state type S |
Foldable |
Protocol | @runtime_checkable structural type for events with a fold method; types FoldReducer's event arg (don't inherit it) |
BaseReducer |
Class | Abstract base for custom reducers — subclass for bespoke channels |
SKIP |
Sentinel | Return from ScalarReducer.fn (or a FoldReducer.fold) to leave the value unchanged |
RESET |
Sentinel | Return from a FoldReducer.fold to clear the channel back to default_factory() |
message_reducer |
Function | Built-in reducer for MessageEvent projection |
Lifecycle Hooks¶
| Export | Type | Description |
|---|---|---|
on_namespace_finalize(cls, callback) |
Function | Schedule callback(cls, namespace_cls) to fire once cls's enclosing Namespace.__init_subclass__ finishes. Lets class decorators defer typing.get_type_hints() calls until forward references to siblings can resolve. Fires immediately if the enclosing Namespace has already finalized (e.g. when applied post-hoc to a bound class). |
Streaming & Frames¶
| Export | Type | Description |
|---|---|---|
EventGraph.stream_events() / .astream_events() |
Method | Yield events as produced; flags below control frame types |
EventGraph.stream_resume() / .astream_resume() |
Method | Streaming equivalent of resume() |
emit_custom / aemit_custom |
Function | Emit a custom stream event from a handler |
emit_state_snapshot / aemit_state_snapshot |
Function | Emit a typed state snapshot frame |
STATE_SNAPSHOT_EVENT_NAME |
Constant | Protocol name for snapshot events ("intermediate_state") |
Stream frame types live in the langgraph_events.stream submodule:
from langgraph_events.stream import (
StreamFrame, # (event, reducers, changed_reducers) — include_reducers=True
LLMToken, LLMStreamEnd, # LLM token delta / completion — include_llm_tokens=True
CustomEventFrame, StateSnapshotFrame, # include_custom_events=True
)
Warnings¶
| Export | Type | Description |
|---|---|---|
OrphanedEventWarning |
Warning | Issued at graph construction when a return type has no subscriber |
UnresumableError |
RuntimeError subclass | Raised by resume() (default EventGraph(on_unresumable="raise")) when the thread is not awaiting input — paused handler renamed/removed, thread already finished, double-resume, or a thread already settled by abandon(). Declare @on(previously=...) to recover, or set on_unresumable="halt"/"warn". See Handler renames |
DomainPatternWarning |
Warning | A namespace has 2+ events fanning out to an identical target set — a missing shared abstraction |
CommandChainWarning |
Warning | An inline Command.handle() emits another Command (a chain-causation edge) — prefer emitting a fact and reacting to it |
Errors¶
| Export | Type | Description |
|---|---|---|
CommandPrivacyError |
TypeError subclass | Raised at EventGraph construction; also at runtime when a handler with a broad base-class annotation (e.g. -> DomainEvent) constructs a Cmd.Private(...) that bypasses the static contract check. Outcomes nested inside a Command are private to that Command's inline handle() — neither sibling Commands nor non-inline reactors may produce them |
ReducerNotSetError |
ValueError subclass | Raised at injection time (before the handler body runs) when a handler parameter rejects None (e.g. strategy: str) and the channel value is None. Sits outside the raises= catch boundary — a broad raises=ValueError cannot swallow it. Opt out by widening the annotation to str | None, Any, object, or omitting it |
AG-UI Subpackage¶
Requires [agui]. See AG-UI Adapter.
| Export | Type | Description |
|---|---|---|
AGUIAdapter |
Class | Map EventGraph streams to AG-UI protocol events |
AGUI_EXTRAS_KEY |
Constant | Reserved BaseMessage.additional_kwargs key. Its mapping is forwarded as extra fields on the AG-UI message, and receives the client's extra fields on the way back |
AGUIAdapter.stream() / .connect() / .reconnect() |
Method | Execute / rehydrate checkpoint / refresh |
FrontendStateMutated |
Event | Adapter-emitted IntegrationEvent carrying RunAgentInput.state for client-state-mirror reducers |
FrontendToolCallRequested |
Event | Interrupted subclass for handler-initiated frontend tool calls (CopilotKit useFrontendTool) |
InterruptedWithPayload[PayloadT] |
Generic base | Typed-payload variant of Interrupted; subclasses implement interrupt_payload(self) -> PayloadT. The built-in InterruptedMapper recognizes it directly — no agui_dict() override needed |
AGUICustomEvent / AGUISerializable |
Protocol | Override fallback event names / payload serialization |
SeedFactory / ResumeFactory / EventMapper |
Protocol | Input → seed events; resume detection; event mapping |
MapperContext |
Dataclass | Shared state (run ID, thread ID, message counter) per stream |
create_starlette_response / encode_sse_stream |
Function | Framework-agnostic SSE wrapping |
extract_resume_input |
Function | Pulls and JSON-decodes RunAgentInput.forwarded_props["command"]["resume"]. Returns None if absent or falsy |
agui_messages_to_langchain |
Function | Converts AG-UI protocol messages to LangChain BaseMessage instances. Maps ToolMessage.error to status="error" and extra fields to additional_kwargs[AGUI_EXTRAS_KEY]. Optional drop_invalid_tool_calls=True to skip tool calls whose JSON arguments fail to parse |
merge_frontend_messages |
Function | resume_factory helper: reads messages from checkpoint_state["reducers"][reducer_name], converts input_data.messages, merges via add_messages (id-based dedup). Returns a tuple |
build_langchain_tools / detect_new_tool_results |
Function | Convert RunAgentInput.tools to OpenAI-format / extract new ToolMessages from a resume request |
Serde Subpackage¶
Namespace-aware serialization, auto-wired by default. EventGraph.from_namespaces(..., checkpointer=MemorySaver()) builds a NamespaceAwareSerde scoped to the passed namespaces and auto-collects every @migrate_from / @backfill on those classes. Opt out by passing MemorySaver(serde=<custom>). See Event migrations.
Exported from langgraph_events.serde unless a different module is noted.
| Export | Type | Description |
|---|---|---|
NamespaceAwareSerde |
Class | JsonPlusSerializer subclass keying Event identity by (__module__, __qualname__). Drop-in for any checkpointer accepting serde=. EventGraph.from_namespaces auto-wires one scoped to its namespaces when the checkpointer carries the default serde; pass your own via MemorySaver(serde=...) to opt out. Kwargs: migrations=, namespaces=, legacy_write=. legacy_write=True is refused at construction with an origin-scoped fill, any transform or any split |
migrate_from |
Decorator | @migrate_from(*old_qualnames, in_module=None, backfill=None, transform=None) — records historic identities a class held. backfill={field: default} scopes fills to payloads written under this decorator's qualname (one qualname per decorator) — the fan-in case where collapsed origins each pin their own discriminator. transform=fn rewrites the stored kwargs of payloads written under this decorator's qualname only, before the rename (one qualname per decorator). transform=lambda kw: {} retires an identity onto an empty tombstone. Auto-collected from the namespaces the serde was built with; stacks; not MRO-inherited |
backfill |
Decorator | @backfill(field, *, default=… \| default_factory=…) — class-global back-fill for a field that is required in code but absent from pre-existing payloads (one value for every origin and era; acts as the fallback under origin-scoped fills). Same auto-collection as @migrate_from; reuses the AddField mutable-default guard |
transform_fields |
Decorator | @transform_fields(fn) — the class stage: rewrites the stored kwargs for a field the class dropped, merged or retyped. fn receives a copy of the kwargs and returns the kwargs the constructor receives. Runs after any rename, on payloads from every era, so it must be idempotent. One per class. migrate_from(transform=fn) is the origin stage. Same auto-collection as @backfill. See Dropping, merging or retyping a field |
split_event |
Decorator | @split_event(select, *, targets=(...)) — applied to the source class, whose identity stays stored. select receives a copy of the stored kwargs and returns None to keep the source, or (target_class, kwargs) to build one of targets instead. Runs in the class stage, after any rename and @transform_fields, before the fills of the resulting identity. targets is validated at serde construction. One per class. Same auto-collection as @transform_fields. See Splitting one stored event into two on a payload value |
Migration |
Class | Hand-authored migration group for cross-module / composite cases. Migration.rename(...) / Migration.add_field(...) / Migration.transform_fields(...) / Migration.split_event(...) are single-op sugar; pass the live target as to=<class> / target=<class> / source=<class> (refactor-safe) instead of new_module/new_qualname strings. add_field or transform_fields keyed on a historic module/qualname is origin-scoped (applies before the rename) — the escape hatch for a per-origin default_factory or transform. split_event(source=Class, select=fn, targets=(...)) keys on the live source only |
assert_all_baselined_cover |
Function | assert_all_baselined_cover(serde, baseline_path) — weakest coverage gate: set-membership over revivable_identities(); raises MigrationCoverageError if an identity is neither live nor rename-covered. Walks the baseline's events and retired lists both. Scoped to the serde's namespaces= walk plus events=. See coverage gates |
assert_all_baselined_resolve |
Function | assert_all_baselined_resolve(serde, baseline_path) — rename-aware gate: asserts every baselined identity resolves to a live Event class without constructing it. Walks events and retired both. For baselines with __post_init__-validated, framework, or module-level events |
assert_all_baselined_revive |
Function | assert_all_baselined_revive(serde, baseline_path) — strongest gate: pushes a synthesized payload for every baselined identity through the real read path and asserts it revives. Walks events and retired both. A v3 baseline's recorded fields are sent too, so a field the live class dropped fails here. No per-event list to maintain |
synthesize_legacy_payload |
Function | synthesize_legacy_payload(module, qualname, kwargs) — builds the (format, bytes) a prior release would have written. For pinning a specific drifted field shape; the loop gate above covers identity reachability |
replay_reducer |
Function | replay_reducer(reducer, events) — rebuild a reducer's channel value from its (already-migrated) event log when the projection/output shape changed. Thin wrapper over BaseReducer.seed |
NamespaceAwareSerde.revivable_identities |
Method | Read-only frozenset of every revivable (module, qualname). For custom coverage rules; assert_all_baselined_cover is the gate |
assert_all_baselined_handlers_cover |
Function | assert_all_baselined_handlers_cover(graph, baseline_path) — handler analog: asserts every baselined handler node name is still live or covered by an @on(previously=...) alias. Takes the EventGraph. See Handler renames |
assert_resume_recovers |
Function | assert_resume_recovers(before, after, *, seed, resume_with, thread_id=None) — behavioral recovery proof: invokes before to interrupt, resumes after on the same checkpoint, asserts a Resumed (real recovery). The handler analog of assert_all_baselined_revive; both graphs must share one checkpointer. See Testing handler recovery |
CoverageError |
Exception | AssertionError base for both coverage failures; except CoverageError catches event and handler gates alike |
MigrationCoverageError |
Exception | Raised by the event gates (assert_all_baselined_cover/_resolve/_revive); CoverageError subclass. .uncovered is the offending (module, qualname) tuple. .retired is the subset the baseline lists as retired |
HandlerCoverageError |
Exception | Raised by assert_all_baselined_handlers_cover; CoverageError subclass (sibling of MigrationCoverageError). .uncovered is the offending handler node-name tuple |
write_baseline |
Function (…serde.migrations.detect) |
write_baseline(graph, path) — snapshots topology into a v3 baseline: every identity with its cumulative fields, the handler names, and a retired list of identities the graph no longer reaches. Never erases an identity. The allow_removed= keyword is deprecated and does nothing. See When to commit the baseline |
detect_changes |
Function (…serde.migrations.detect) |
detect_changes(graph, baseline_path) — diffs topology vs baseline into rename/ambiguous/removed buckets. Also runnable as the CI gate python -m langgraph_events.serde.migrations <module:factory> <baseline> |
BaselineRegressionError |
Exception (…serde.migrations.detect) |
Retained for one release; write_baseline no longer raises it. ValueError subclass. .removed is the tuple of dropped identities |
Raw RenameEvent / AddField / TransformFields / SplitEvent operation constructors are the composite escape hatch in langgraph_events.serde.migrations — intentionally not re-exported at the top level (the decorator + Migration sugar is the public tier). TransformFields(module, qualname, transform) rewrites the stored kwargs of one identity; the identity picks the stage, the same rule as AddField. SplitEvent(module, qualname, select, targets) keys on a live identity and builds one of targets when select returns it; the class stage only. Wrap either like every raw op: Migration(operations=(TransformFields(module, qualname, transform),)).