ExAthena.Loop.State (ExAthena v0.9.0)

Copy Markdown View Source

Internal state of a running agent loop.

Opaque to consumers. ExAthena.Loop.Mode implementations receive and return this struct as they drive iterations. The public result of a run is ExAthena.Result, which is built from the terminal State.

Fields

  • messages — running conversation history.
  • tool_specs — resolved Tool.Spec list for this run.
  • capabilities — provider capabilities map.
  • provider_mod, provider_opts — inference entry point.
  • request_template — base request overlaid each iteration with fresh messages + tool schemas.
  • permissions_opts — fed to ExAthena.Permissions.
  • hooks — lifecycle matcher/callback sets.
  • ctxExAthena.ToolContext threaded to every tool execution.
  • on_event — user-supplied callback for stream events.
  • budgetExAthena.Budget accumulator.
  • max_iterations, max_consecutive_mistakes, max_budget_usd, tool_timeout_ms, max_concurrency — reliability knobs.
  • max_unproductive_iterations — consecutive unproductive-iteration cap (default 3); halts with :error_no_progress when exceeded.
  • iterations, tool_calls_made, consecutive_mistakes — counters.
  • unproductive_iterations — consecutive iterations with no new tool name+args combination and no new assistant text.
  • last_tool_fingerprint — sorted [{name, args_binary}] list from the previous iteration, used to detect identical tool calls.
  • no_progress_snapshot — last few message pairs captured when :error_no_progress fires; included in Result for remediation.
  • mode, mode_state — Mode module + its private state.
  • halted_reason — populated when a tool / hook returns :halt.
  • session_id — stable id for this run. Distinct from ctx.session_id, which is what tools see; this one is what the loop / hooks / storage use. Generated automatically when not supplied.
  • parent_session_id — when this run was spawned as a subagent, the parent's session_id. nil for top-level runs. Used by sidechain storage and session-resume (PR4 + PR5).
  • meta — free-form map for Mode-specific data that doesn't fit anywhere else.

Summary

Types

t()

@type t() :: %ExAthena.Loop.State{
  budget: ExAthena.Budget.t() | nil,
  capabilities: map(),
  consecutive_mistakes: non_neg_integer(),
  ctx: ExAthena.ToolContext.t() | nil,
  halted_reason: term() | nil,
  hooks: map(),
  iterations: non_neg_integer(),
  last_tool_fingerprint: list() | nil,
  max_budget_usd: float() | nil,
  max_concurrency: pos_integer(),
  max_consecutive_mistakes: non_neg_integer(),
  max_iterations: non_neg_integer(),
  max_unproductive_iterations: non_neg_integer(),
  messages: [ExAthena.Messages.Message.t()],
  meta: map(),
  mode: module() | nil,
  mode_state: map(),
  no_progress_snapshot: [ExAthena.Messages.Message.t()] | nil,
  on_event: (term() -> term()) | nil,
  parent_session_id: String.t() | nil,
  permissions_opts: map(),
  provider_mod: module() | nil,
  provider_opts: keyword(),
  request_template: term(),
  session_id: String.t() | nil,
  tool_calls_made: non_neg_integer(),
  tool_specs: [ExAthena.Tool.Spec.t()],
  tool_timeout_ms: pos_integer(),
  unproductive_iterations: non_neg_integer()
}