Conversation state owned by Spectre.
State is the authoritative machine state for routing and effect safety. It tracks the current flow, pending effects, active awaitables, compact chat history, and trace events.
Summary
Functions
Marks the policy-gated effect identified by an awaitable as approved.
Returns true when the state is waiting for an active policy response.
Returns true when the specified Run owns an open policy response.
Advances the optimistic-concurrency revision exactly once.
Cancels pending effects and appends a trace event.
Clears open awaitables without removing pending effects.
Clears pending effects and open awaitables.
Completes the next pending effect and returns {state, completed_effect}.
Marks the current pending effect as failed and clears it from the execution queue while preserving the failed transition in history.
Normalizes map, keyword, or nil input into a state struct.
Returns the currently open policy awaitable, if one exists.
Returns the open policy awaitable owned by one Run.
Returns the next effect in the execution queue, or nil when it is empty.
Returns the pending effect owned by one Run.
Stores a pending effect and optionally starts a policy gate for it.
Appends a compact chat-history entry under state.data[:chat_history].
Replaces an awaitable through the validated lifecycle transition.
Finds a terminal transition for an effect identifier.
Prepends a compact trace event to the state.
Types
@type t() :: %Spectre.State{ awaitables: [Spectre.Awaitable.t()], conversation_id: term(), current_flow: atom() | nil, current_scope: Spectre.Definition.scope() | nil, data: map(), memory_refs: [term()], pending_effects: [Spectre.Effect.t()], planned_effects: [Spectre.Effect.t()], revision: non_neg_integer(), state_version: pos_integer(), trace: [term()] }
Functions
@spec approve_pending_effect(t(), term()) :: {:ok, t(), Spectre.Effect.t()} | {:error, :pending_effect_not_found | {:effect_not_waiting_policy, term(), atom()}}
Marks the policy-gated effect identified by an awaitable as approved.
The effect remains pending so execution can happen at the explicit host boundary after this state transition has been persisted.
Returns true when the state is waiting for an active policy response.
Returns true when the specified Run owns an open policy response.
This scoped form is used by Spectre.Instance. Omitting the Run id retains
the conversation-wide compatibility behavior used by stateless calls and
Spectre.Session.
Advances the optimistic-concurrency revision exactly once.
Cancels pending effects and appends a trace event.
Clears open awaitables without removing pending effects.
Clears pending effects and open awaitables.
@spec complete_pending_effect(t(), term()) :: {t(), Spectre.Effect.t() | nil}
Completes the next pending effect and returns {state, completed_effect}.
If the queue is empty, the effect is nil. If the lifecycle rejects the
transition, the original state and nil are returned. Runtime integrations
should normally call Spectre.execute/3, which also enforces authorization,
persistence, idempotency, and action execution boundaries.
@spec fail_pending_effect(t(), term()) :: {t(), Spectre.Effect.t() | nil}
Marks the current pending effect as failed and clears it from the execution queue while preserving the failed transition in history.
Normalizes map, keyword, or nil input into a state struct.
@spec open_policy_awaitable(t()) :: Spectre.Awaitable.t() | nil
Returns the currently open policy awaitable, if one exists.
Closed, expired, and non-policy awaitables are ignored. Spectre enforces at most one active policy boundary during normal lifecycle transitions.
@spec open_policy_awaitable(t(), String.t() | nil) :: Spectre.Awaitable.t() | nil
Returns the open policy awaitable owned by one Run.
@spec pending_effect(t()) :: Spectre.Effect.t() | nil
Returns the next effect in the execution queue, or nil when it is empty.
Hosts normally use Spectre.Result.pending_effect/1 on the value returned by
Spectre.ask/3 or Spectre.turn/3. This state-level helper is useful for
adapters restoring persisted state.
@spec pending_effect(t(), String.t() | nil) :: Spectre.Effect.t() | nil
Returns the pending effect owned by one Run.
@spec put_pending_effect(t(), Spectre.Effect.t(), term()) :: t()
Stores a pending effect and optionally starts a policy gate for it.
@spec record_turn( t(), Spectre.Input.t(), Spectre.Result.t(), pos_integer() | false | nil ) :: t()
Appends a compact chat-history entry under state.data[:chat_history].
@spec replace_awaitable(t(), Spectre.Awaitable.t()) :: t()
Replaces an awaitable through the validated lifecycle transition.
Matching is performed by awaitable identifier. The function raises if the
replacement would violate lifecycle invariants; application code should
prefer the higher-level Spectre.Lifecycle operations unless implementing a
state adapter or compatibility layer.
@spec resolved_effect(t(), term()) :: Spectre.Effect.t() | nil
Finds a terminal transition for an effect identifier.
This is used as a local idempotency guard when a restored state accidentally contains both a pending copy and an already resolved copy of the same effect.
Prepends a compact trace event to the state.