ExAthena.Loop.Terminations (ExAthena v0.3.0)

Copy Markdown View Source

Typed termination subtypes for agent-loop runs.

Every run ends with exactly one termination. Normal completions use :stop; everything else is an error subtype carrying enough context (usage, cost, duration) to drive retries and observability.

Inspired by the Claude Agent SDK's typed termination subtypes — they keep accounting uniform across happy and sad paths.

Subtypes

  • :stop — model returned text with no tool calls.
  • :error_max_turns — iteration cap reached.
  • :error_max_budget_usd — cost ceiling tripped.
  • :error_during_execution — unrecoverable tool / provider error.
  • :error_max_structured_output_retries — repair budget exhausted.
  • :error_consecutive_mistakes — mistake counter threshold hit.
  • :error_halted — hook or tool returned :halt.
  • :error_compaction_failed — context compaction failed.

Summary

Functions

All known termination subtypes.

Categorise a termination for retry classification. Returns one of: :retryable, :capacity, :fatal.

Is this an error termination?

Is this a successful termination?

Types

subtype()

@type subtype() ::
  :stop
  | :error_max_turns
  | :error_max_budget_usd
  | :error_during_execution
  | :error_max_structured_output_retries
  | :error_consecutive_mistakes
  | :error_halted
  | :error_compaction_failed

Functions

all()

@spec all() :: [subtype()]

All known termination subtypes.

category(atom)

@spec category(subtype()) :: :success | :retryable | :capacity | :fatal

Categorise a termination for retry classification. Returns one of: :retryable, :capacity, :fatal.

  • :retryable — transient; caller may retry on a new run.
  • :capacity — the run hit a configured limit; caller should increase the limit or reduce scope.
  • :fatal — don't retry without operator action.

error?(arg1)

@spec error?(subtype()) :: boolean()

Is this an error termination?

success?(arg1)

@spec success?(subtype()) :: boolean()

Is this a successful termination?