ALLM.ImageUsage (allm v0.3.0)

Copy Markdown View Source

Image-side usage and cost summary. See spec §35.2.4.

Layer A — pure serializable data. :images defaults to 0 so a freshly-constructed %ImageUsage{} reads as "no work done yet"; the %ALLM.ImageResponse{} struct's default :usage carries one of these rather than nil.

Cost types — refinement of spec §35.2.4

Cost fields are typed float() | nil, NOT Decimal.t() | nil as spec §35.2.4 reads (Phase 13 design Decision #1). Rationale:

  • ALLM.Usage.cost is already float() (lib/allm/usage.ex:11); diverging ImageUsage to Decimal would split the cost type across two structs for no semantic gain.
  • :decimal is not a project dep and adopting it solely for typed nil-or-number adds runtime weight.
  • Float-summation drift on total_cost = input_cost + output_cost is bounded at ≤1 ULP, well below provider cent-level pricing precision.

A spec PR against steering/allm_engine_session_streaming_spec_v0_2.md §35.2.4 will land alongside the v0.3.0 release recording this refinement.

Providers that charge by image-count alone (dall-e-2, dall-e-3) populate :images, :size, :quality, and :total_cost. Providers that charge by tokens (gpt-image-1) additionally populate :input_tokens / :output_tokens / :input_cost / :output_cost.

Summary

Functions

Build an %ImageUsage{} from keyword opts.

Types

t()

@type t() :: %ALLM.ImageUsage{
  images: non_neg_integer(),
  input_cost: float() | nil,
  input_tokens: non_neg_integer() | nil,
  output_cost: float() | nil,
  output_tokens: non_neg_integer() | nil,
  quality: String.t() | nil,
  size: String.t() | nil,
  total_cost: float() | nil
}

Functions

new(opts \\ [])

@spec new(keyword()) :: t()

Build an %ImageUsage{} from keyword opts.

Unknown keys raise KeyError via struct!/2.

Examples

iex> u = ALLM.ImageUsage.new(images: 1, input_tokens: 100)
iex> u.images
1
iex> u.input_tokens
100
iex> u.size
nil