Token and cost usage for a single response — Layer A serializable data.
Every numeric field is optional and nil-able because not every
provider returns every counter. Costs are populated either by an
adapter that knows its own pricing or by an optional model-catalog
integration.
Fields
| Field | Type | Notes |
|---|---|---|
:input_tokens | non_neg_integer | nil | |
:output_tokens | non_neg_integer | nil | |
:cached_input_tokens | non_neg_integer | nil | Provider-cached prompt tokens. |
:reasoning_tokens | non_neg_integer | nil | Reasoning-model thinking tokens. |
:total_tokens | non_neg_integer | nil | |
:input_cost | float | nil | USD; populated when the adapter knows pricing. |
:output_cost | float | nil | |
:total_cost | float | nil | |
:tool_usage | map | Per-tool tally (caller-derived). |
:extra | map | Provider-specific spillover. |
Summary
Functions
Build a %Usage{} from keyword opts.
Return the :total_tokens field when set, otherwise the sum of
:input_tokens + :output_tokens when both are integers, otherwise nil.
Types
@type cost() :: float()
@type t() :: %ALLM.Usage{ cached_input_tokens: non_neg_integer() | nil, extra: map(), input_cost: cost() | nil, input_tokens: non_neg_integer() | nil, output_cost: cost() | nil, output_tokens: non_neg_integer() | nil, reasoning_tokens: non_neg_integer() | nil, tool_usage: map(), total_cost: cost() | nil, total_tokens: non_neg_integer() | nil }
Functions
Build a %Usage{} from keyword opts.
Every field is optional. Unknown keys raise ArgumentError via struct!/2.
Examples
iex> u = ALLM.Usage.new(input_tokens: 10, output_tokens: 20)
iex> u.input_tokens
10
iex> u.tool_usage
%{}
@spec total_tokens(t()) :: non_neg_integer() | nil
Return the :total_tokens field when set, otherwise the sum of
:input_tokens + :output_tokens when both are integers, otherwise nil.
Examples
iex> ALLM.Usage.total_tokens(ALLM.Usage.new(total_tokens: 42))
42
iex> ALLM.Usage.total_tokens(ALLM.Usage.new(input_tokens: 10, output_tokens: 20))
30
iex> ALLM.Usage.total_tokens(ALLM.Usage.new([]))
nil