TraceState populated with StepRecord dataclasses (used by the FSM and retrieval pipeline), and a user-facing step_log of StepLogEntry objects exposed on the middleware. Most consumers read the step_log; TraceState and StepRecord are documented here for completeness and for callers building custom integrations.
StepLogEntry
StepLogEntry is the type you actually iterate after a run. The middleware appends one entry per wrap_model_call (i.e. per LLM call). Access via middleware.step_log.
int
Zero-based step index. Monotonically increasing across the run.
float
Wall-clock time (
time.time()) when the entry was created in before_model.float | None
Difficulty score for this step, or
None for the very first call (no thought to score yet).str
String value of the FSM state (e.g.
"INIT", "FAST", "NORMAL", "SLOW", "SKIP").str
Resolved model identifier used for this call after FSM-based routing. Empty string when no override applied.
list[str]
Short previews (≤150 chars) of each injection appended to the system prompt for this call.
list[str]
Source class names of the injections (e.g.
"E1Injection", "MonitorSteeringInjection").list[str]
Full, untruncated injection text for each injection, in the same order as
injection_sources.list[str]
Specific monitor names that fired on this step (e.g.
"loop_detector", "hedge").str | None
Categorical failure label from the server-side monitor evaluation, when present.
str | None
Set when retrieval was skipped — e.g.
"FSM=FAST, e-traces skipped". None otherwise.str
First 120 characters of the agent’s thought for this step, or
"(first call)" when there is no thought yet.list[str]
Names of tool calls produced by the LLM for this step.
int
Total tokens for this call (extracted from the AIMessage
usage_metadata).float
Milliseconds elapsed since the previous entry’s timestamp.
0.0 for the first entry.as_dict()
StepLogEntry.as_dict() returns a serialisable dict with every field above (rounded as appropriate). Optional fields like difficulty, model_id, skipped_reason, and failure_type are only included when they are populated.
StepRecord
StepRecord is the internal per-step dataclass written into TraceState.steps. The FSM and retrieval pipeline read from it; callers typically use StepLogEntry instead.
int
required
Zero-based position of this step in the trace.
str
required
The agent’s reasoning text for this step (extracted from the latest
AIMessage).str | None
Tool name selected by the agent for this step, or
None if no tool was called.str | None
String form of the tool arguments, or
None when action is None.str | None
Most recent tool message content (truncated to 400 chars), or
None if no observation.float
Difficulty score for this step in
[0.0, 1.0]. Defaults to 0.0 until scored.FSMState
FSM state recorded after scoring this step. Defaults to
FSMState.INIT.int
Tokens consumed by the LLM call that produced this step. Updated post-call from
usage_metadata.TraceState
TraceState is the run-level accumulator owned by TraceStateManager. The middleware reads from it during retrieval; consumers do not normally touch it directly.
str
required
Unique identifier for this run.
list[StepRecord]
Ordered list of every
StepRecord recorded so far.FSMState
The FSM state at the time of inspection. Starts as
FSMState.INIT.list[float]
Flat list of difficulty scores in step order. Equivalent to
[s.difficulty for s in steps].int
Sum of
StepRecord.tokens_used across all steps.int | None
The
token_budget configured on the parent ReasonBlocks instance, or None when no budget was set.
