Turn-guard builders for a session loop's between-turn hook (RMA's
turn_guard: option; 0.5.0+, hook shape unchanged through 0.10). Plain
data in, plain verdict out — no RMA types.
for_grant/3 prices the session's accumulated usage with Mimir.Pricing
and halts once the grant budget is spent — the control-plane soft half of
enforcement, for runtimes where the gateway cannot sit in the data plane.
caps/1 is the mimir-less form: plain cost/token/turn caps, no minted key.
Guards never raise mid-run: on a pricing-table miss the cost check degrades
to whatever caps remain and a [:mimir, :guard, :pricing_miss] telemetry
warning is emitted (once per process per model).
Summary
Types
@type guard_fun() :: (turn_state() -> verdict())
@type turn_state() :: %{ :usage => map(), :turns => non_neg_integer(), optional(any()) => any() }
@type verdict() :: :cont | {:halt, term()}
Functions
Build a guard from plain caps — the mimir-less form. Options:
:max_turns— halt onceturnsreaches the cap:max_total_tokens— halt once input+output tokens reach the cap:max_cost_microdollars(with:model) — priced cost cap
Omitted caps don't constrain; with no options the guard always continues.
@spec for_grant(Mimir.Grant.t(), String.t(), keyword()) :: guard_fun()
Build a guard from a route-response grant. Pass resp.grant from a
%Mimir.RouteResponse{}. A %Grant{} with a nil budget_microdollars
never halts on cost. opts take caps/1 options; caps are checked before
the budget.