Behaviour for a single compaction stage.
A stage is one cheap-to-expensive transformation in the
ExAthena.Compactor.Pipeline. The pipeline runs stages in order;
each stage may shrink the conversation a little (returning the new
estimate) or skip (returning :skip). Earlier stages run before
later ones, so cheap deterministic transformations get to reduce
the budget before the LLM-summary stage pays for inference.
Contract
Each stage receives the current Loop.State and a token estimate. It
returns:
{:ok, new_state, new_estimate}— applied a reduction.:skip— nothing to do this pass.{:error, reason}— surfaces to the kernel as:error_compaction_failed. The pipeline aborts.
Stages should be idempotent when re-run on a state they already
processed (the reactive-recovery path may run the pipeline a second
time with force: true after a context-window error).
Optional force?/2 callback
The pipeline calls force?(state, estimate) to ask whether a stage
should run unconditionally on the recovery path (where the goal
is "shrink as much as possible"). The default implementation returns
true.
Summary
Functions
Default builtin pipeline ordering. Stages are placed cheapest-first so the LLM-summary stage only fires when the deterministic stages couldn't get the conversation under target.
Types
@type result() :: {:ok, ExAthena.Loop.State.t(), ExAthena.Compactor.estimate()} | :skip | {:error, term()}
Callbacks
@callback compact_stage(ExAthena.Loop.State.t(), ExAthena.Compactor.estimate()) :: result()
@callback name() :: atom()
Stage's display name (atom). Used in telemetry.
Functions
@spec default_pipeline() :: [module()]
Default builtin pipeline ordering. Stages are placed cheapest-first so the LLM-summary stage only fires when the deterministic stages couldn't get the conversation under target.