Skip to main content
Typed workflow state gives AgentFlow.variables a schema, so a misspelled variable is refused when the flow is built instead of dying halfway through a run.

Quick Start

1

Untyped baseline

Without a model, variables stays the plain dict it has always been and flow.state is None.
2

Add a Pydantic model

Declare a state_model and read fields with typed, dotted access.
3

Use a plain dataclass

The same shape works as a @dataclass, so Pydantic is never required.

How It Works

Validation runs at construction, so a typo costs nothing to find because the flow never starts.

Catching mistakes at build time

An unknown key is an error, not something to ignore, and the message names the declared fields so the fix is visible.

Re-validating after a step writes

A step that writes into variables can re-check before the next step reads them.

When to use which model type

A dataclass works as well as a Pydantic model, so reach for the heavier dependency only when you need it.

API Reference

The public surface is one field, one property, one method, and one error type.
Advanced. For building your own tooling, praisonaiagents.workflows.state also exposes build_state(model, variables) to construct the typed instance and state_field_names(model) to read a model’s declared field names.

Best Practices

The cost is one class; the win is that a typo becomes a build-time error instead of a variable that is written, never read, and never reported.
Use a plain dataclass when you only need field names and types. Reach for a Pydantic BaseModel when you want validators, coercion, or a JSON schema.
Call flow.validate_variables() after a writing step so the next step reads a shape you have already proven valid.
None means no model was declared — never “empty state”. An empty typed state is a real instance, not None.

AgentFlow

The deterministic multi-step workflow that state_model describes.

Injected State

Hides tool parameters from the LLM — about tools, not flow variables.