Skip to main content
FSMState is the enum at the heart of ReasonBlocks’ difficulty tracking. After scoring each reasoning step, the SDK advances a finite state machine through these states to determine model routing, monitor-injection cooldowns, and whether to skip the E-trace retrieval pipeline. You read the current state from TraceState.current_state and from per-step StepLogEntry.fsm_state fields exposed on the middleware.

States

The default thresholds and windows live on DifficultyFSM; override them via ReasonBlocks(fsm_thresholds={...}).

State reference

FSMState.INIT

The trace starts in INIT. The first scored step transitions to NORMAL. You will only see INIT on the very first before_model call (before any thought has been produced).

FSMState.FAST

Entered from NORMAL when the most recent six difficulty scores are all below fast_threshold (default 0.2). In FAST, the middleware skips the full E-trace retrieval pipeline (E1, E2, E3); monitors still run so loop and trajectory-length detectors keep working. If model_routing contains a FAST entry, the next call uses that model.

FSMState.NORMAL

The default state. The E-trace pipeline runs, with E1 retrieval further gated by recent monitor activity (see the middleware notes). The model from your ReasonBlocks config is used unless model_routing overrides it for NORMAL.

FSMState.SLOW

Entered from NORMAL when the most recent five difficulty scores all exceed slow_threshold (default 0.6). E-traces continue to be retrieved; if model_routing contains a SLOW entry the next call swaps to that model.
Both FAST and SLOW exit on a single contrary score with hysteresis: from FAST, a score above fast_threshold + hysteresis_margin (0.3) returns to NORMAL; from SLOW, a score below slow_threshold - hysteresis_margin (0.5) returns to NORMAL.

FSMState.SKIP

Entered from SLOW when 35 consecutive scores all exceed skip_threshold (default 0.85). For routing and monitor-injection cooldown purposes, SKIP is identical to SLOW; it is a separate label so dashboards and downstream code can flag exceptionally stalled runs. There is no special “skip injection” — the same monitor steering and E-trace machinery applies.

FSMState.END

END is defined in the enum but the built-in DifficultyFSM.transition never returns it. The state exists for callers that supply a custom transition function that wants to mark a trace as terminal. Reading END from a stock SDK installation indicates manual intervention.

Monitor injection cooldowns

Monitor steering injection respects per-state cooldowns to avoid over-steering. The middleware caps monitor injections at 5 per run total.

Reading state after a run

StepLogEntry.fsm_state is the string value of the enum (e.g. "FAST", "NORMAL"); use FSMState(entry.fsm_state) to round-trip back to the enum.

Values

FSMState is a standard enum.Enum. Each member’s .value is its uppercase string name, which is also what appears in the dashboard.