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.:error_prompt_too_long— provider rejected the request because the assembled prompt exceeded the model's context window. Modes signal this to the kernel so the compaction pipeline can attempt reactive recovery before the run terminates.:error_no_progress— consecutive-iteration productivity threshold exceeded; the last N iterations produced identical tool calls with no new text. TheResult.no_progress_snapshotfield carries the stuck message pairs for remediation reprompts.:error_schema_validation— model output could not be parsed as valid structured output or tool calls. Category:retryable; caller may retry with a reformat prompt hint.Result.error_diagnosticcarries the structured failure payload.:error_provider_auth— provider returned HTTP 401 or 403. Category:fatal; blind retry will not help — operator must fix credentials.
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
@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
| :error_prompt_too_long
| :error_no_progress
| :error_schema_validation
| :error_provider_auth
Functions
@spec all() :: [subtype()]
All known termination subtypes.
@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.
Is this an error termination?
Is this a successful termination?