OTP-native conversational runtime for Elixir agents.
Spectre owns the thin, boring middle of an agent: route a user turn, render
prompts, keep conversation state, stage provider-neutral actions, and enforce
policy gates before anything with side effects can execute.
The runtime is deliberately split into small boundaries:
Spectre.Inputnormalizes host input once.Spectre.Runtimeloads state and memory, then chooses policy resume or normal routing.Spectre.Routercollects route evidence and arbitrates a single route.Spectre.Runnerexecutes the route handler without directly performing protected side effects.Spectre.Runcarries a checkpointable continuation through the closedSpectre.Runtime.start/3,advance/2, andresume/3protocol.Spectre.Executionis the explicit boundary for executing a pending action or extension-owned effect after policy approval.
A simple stateless call:
{:ok, result} = Spectre.ask(MyApp.SupportAgent, "I need help")A stateful supervised conversation:
{:ok, session} = Spectre.summon(agent: MyApp.SupportAgent)
{:ok, result} = Spectre.ask(session, "create a project")
state = Spectre.state(session)
Summary
Functions
Activates a re-read bootstrap or approved governed Candidate through generation CAS.
Returns the currently committed Definition Activation for an Instance.
Admits an ownership-based event through the Instance sequencer.
Returns committed admitted Event Envelopes.
Runs configured action lifecycle hooks for a result.
Asks either an agent module or a supervised session to handle one turn.
Runs deterministic proactive-delivery authorization without sending.
Cancels the active policy/effect boundary and returns an updated result.
Returns the strict JSON canonical Agent checkpoint.
Returns canonical checkpoint persistence status.
Returns the lifecycle axes for one Definition or the active Definition.
Returns committed delivery audit receipts.
Dismisses a session supervised by Spectre.Supervisor.
Drains new admission while retaining owned continuations.
Starts or reuses the Instance for agent + subject, always returning
{:ok, pid} or {:error, reason}.
Executes the currently pending effect through its registered capability boundary. Actions use their provider mount; other effect kinds use the executor contributed by the owning extension.
Waits for durable persistence of the current canonical revision.
Starts or returns the unique supervised Instance for agent + subject.
Looks up the live local Instance for agent + subject.
Returns one committed operational-loop view.
Lists visible committed operational loops.
Returns committed operational events.
Requests a reversible loop pause.
Stores revocable proactive-delivery consent.
Returns quarantined Event Envelopes.
Reconciles an ambiguous canonical-checkpoint write before any retry.
Records a Beam/host transport outcome against an authorization receipt.
Registers a durable Vigil on an Agent Instance.
Renews a nonterminal Work, Vigil or controller expiry.
Replaces the current in-memory state of a supervised session.
Resolves exactly one visible operational loop without model guessing.
Resolves an open policy from a trusted host decision.
Resumes a Run owned by an Agent Instance.
Resumes a reversibly paused loop.
Revokes current Definition authority.
Revokes proactive-delivery consent.
Rolls activation back to an explicitly selected ancestor Candidate.
Returns one active or explicitly selected first-class Skill-state branch.
Lists first-class Skill-state branches.
Starts an authorized external controller on the shared runtime.
Starts a verified data-driven Work materialization on an Agent Instance.
Starts a precise Work on an Agent Instance.
Returns the current in-memory state of a supervised session.
Stops a loop terminally.
Subscribes the caller to committed local operational events.
Summons an Agent Instance or legacy Session process directly.
Summons a session under a Spectre.Supervisor.
Transitions one Definition lifecycle axis.
Transitions one dormant Skill-state branch retention status.
Delivers a declared trigger to a waiting loop.
Runs to the first observable boundary and returns its public Turn projection.
Removes the caller's local operational-event subscription.
Applies the durable pause-update-resume sequence.
Applies a version-fenced loop update.
Updates one active Skill-state branch through schema and revision fences.
Returns the running Spectre library version.
Functions
Activates a re-read bootstrap or approved governed Candidate through generation CAS.
Returns the currently committed Definition Activation for an Instance.
Admits an ownership-based event through the Instance sequencer.
Returns committed admitted Event Envelopes.
@spec after_action( module(), atom(), Spectre.Result.t(), Spectre.Context.t() | map(), keyword() ) :: :ok | {:error, [term()]}
Runs configured action lifecycle hooks for a result.
The common host-app use is to call this after a successful message delivery:
Spectre.after_action(MyAgent, :delivered, result, ctx)Hooks are kept outside route execution so delivery acknowledgements and audit events can be retried independently from the user-facing turn.
@spec ask( module() | GenServer.server(), Spectre.Input.t() | String.t() | map(), keyword() ) :: {:ok, Spectre.Result.t()} | {:error, term()}
Asks either an agent module or a supervised session to handle one turn.
When the first argument is an agent module built with use Spectre.Agent,
Spectre runs a stateless turn and uses the configured state adapter or the
explicit :state option. When the first argument is a session pid/name,
Spectre sends the turn to that supervised process.
Spectre.ask(MyApp.Agent, %{text: "hello", meta: %{locale: "en"}})
{:ok, session} = Spectre.summon(agent: MyApp.Agent)
Spectre.ask(session, "continue the same conversation")
Runs deterministic proactive-delivery authorization without sending.
@spec cancel(Spectre.Input.t() | String.t() | map(), Spectre.Context.t() | map()) :: {:ok, Spectre.Result.t()}
Cancels the active policy/effect boundary and returns an updated result.
{:ok, result} = Spectre.cancel("cancel", ctx)
Returns the strict JSON canonical Agent checkpoint.
Returns canonical checkpoint persistence status.
Returns the lifecycle axes for one Definition or the active Definition.
Returns committed delivery audit receipts.
@spec dismiss(GenServer.server(), pid()) :: :ok | {:error, term()}
Dismisses a session supervised by Spectre.Supervisor.
:ok = Spectre.dismiss(MyApp.SpectreSupervisor, pid)
Drains new admission while retaining owned continuations.
@spec ensure_instance( GenServer.server(), module() | Spectre.AgentRef.t(), term(), keyword() ) :: {:ok, pid()} | {:error, term()}
Starts or reuses the Instance for agent + subject, always returning
{:ok, pid} or {:error, reason}.
instance/4 mirrors the underlying supervisor's richer return shapes
({:ok, pid}, {:ok, pid, info}, {:error, {:already_started, pid}}).
Hosts that only need the pid use this normalized form:
{:ok, pid} = Spectre.ensure_instance(MySup, MyAgent, "conversation:42")
@spec execute(Spectre.State.t(), Spectre.Context.t() | map(), keyword()) :: {:ok, Spectre.Result.t()} | {:error, term()}
@spec execute(module() | GenServer.server(), Spectre.Result.t(), keyword()) :: {:ok, Spectre.Result.t()} | {:error, term()}
Executes the currently pending effect through its registered capability boundary. Actions use their provider mount; other effect kinds use the executor contributed by the owning extension.
{:ok, result} = Spectre.execute(state, ctx)
{:ok, result} = Spectre.execute(MyAgent, approved_result)
Waits for durable persistence of the current canonical revision.
@spec instance( GenServer.server(), module() | Spectre.AgentRef.t(), Spectre.Subject.t() | term(), keyword() ) :: DynamicSupervisor.on_start_child()
Starts or returns the unique supervised Instance for agent + subject.
@spec lookup_instance( module() | Spectre.AgentRef.t(), Spectre.Subject.t() | term(), atom() ) :: {:ok, pid()} | {:error, :instance_not_found}
Looks up the live local Instance for agent + subject.
Returns one committed operational-loop view.
Lists visible committed operational loops.
Returns committed operational events.
Requests a reversible loop pause.
Stores revocable proactive-delivery consent.
Returns quarantined Event Envelopes.
Reconciles an ambiguous canonical-checkpoint write before any retry.
Records a Beam/host transport outcome against an authorization receipt.
Registers a durable Vigil on an Agent Instance.
Renews a nonterminal Work, Vigil or controller expiry.
@spec reset(GenServer.server(), Spectre.State.t() | map() | keyword()) :: :ok | {:error, :instance_busy}
Replaces the current in-memory state of a supervised session.
:ok = Spectre.reset(session, %Spectre.State{current_flow: :checkout})
Resolves exactly one visible operational loop without model guessing.
@spec resolve_policy( module() | GenServer.server(), Spectre.Result.t(), Spectre.Policy.resolution(), keyword() ) :: {:ok, Spectre.Result.t()} | {:error, term()}
Resolves an open policy from a trusted host decision.
This is intended for durable facts already known by the host, such as terms accepted in another channel. The resolution label must be declared by the policy. For agent modules, Spectre persists the approved/rejected state before returning. For sessions it also advances the session's in-memory state.
{:ok, approved} =
Spectre.resolve_policy(
MyApp.Agent,
awaiting_result,
{:accept, :terms_accepted},
assigns: %{user: user}
)
@spec resume(GenServer.server(), Spectre.Run.Ref.t(), term(), keyword()) :: {:ok, Spectre.Turn.t()} | {:error, term()}
Resumes a Run owned by an Agent Instance.
Resumes a reversibly paused loop.
Revokes current Definition authority.
Revokes proactive-delivery consent.
Rolls activation back to an explicitly selected ancestor Candidate.
Returns one active or explicitly selected first-class Skill-state branch.
Lists first-class Skill-state branches.
Starts an authorized external controller on the shared runtime.
Starts a verified data-driven Work materialization on an Agent Instance.
Starts a precise Work on an Agent Instance.
@spec state(GenServer.server()) :: Spectre.State.t()
Returns the current in-memory state of a supervised session.
%Spectre.State{} = Spectre.state(session)
Stops a loop terminally.
Subscribes the caller to committed local operational events.
@spec summon(keyword()) :: GenServer.on_start()
Summons an Agent Instance or legacy Session process directly.
{:ok, pid} = Spectre.summon(agent: MyApp.Agent, subject: account.id)Supplying :subject selects the Agent Instance runtime. Calls without
it preserve the conversation-scoped Session compatibility path.
@spec summon(GenServer.server(), module(), keyword()) :: DynamicSupervisor.on_start_child()
Summons a session under a Spectre.Supervisor.
{:ok, pid} = Spectre.summon(MyApp.SpectreSupervisor, MyApp.Agent, [])
Transitions one Definition lifecycle axis.
Transitions one dormant Skill-state branch retention status.
Delivers a declared trigger to a waiting loop.
@spec turn( module() | GenServer.server(), Spectre.Input.t() | String.t() | map(), keyword() ) :: {:ok, Spectre.Turn.t()} | {:error, term()}
Runs to the first observable boundary and returns its public Turn projection.
{:ok, turn} = Spectre.turn(MyApp.Agent, "hello")
{:reply, result} = turn.decision
{:reply, "Hello!", ref} = turn.observable
Removes the caller's local operational-event subscription.
Applies the durable pause-update-resume sequence.
Applies a version-fenced loop update.
Updates one active Skill-state branch through schema and revision fences.
@spec version() :: String.t()
Returns the running Spectre library version.