defmodule LLM.Usage do @moduledoc """ Token usage information from an LLM request. Reports the number of tokens consumed by the input (prompt) and output (completion). The `total_tokens` field is computed automatically if not provided by the provider. ## Fields - `:input_tokens` — tokens in the prompt/messages sent to the model - `:output_tokens` — tokens in the model's response - `:total_tokens` — sum of input and output tokens ## Examples usage = LLM.Usage.new(input_tokens: 100, output_tokens: 50) usage.total_tokens #=> 150 # total_tokens can be provided directly usage = LLM.Usage.new(input_tokens: 100, output_tokens: 50, total_tokens: 200) usage.total_tokens #=> 200 """ @type t :: %__MODULE__{ input_tokens: non_neg_integer() | nil, output_tokens: non_neg_integer() | nil, total_tokens: non_neg_integer() | nil } defstruct [:input_tokens, :output_tokens, :total_tokens] @doc """ Create a usage struct, computing `total_tokens` if not provided. Accepts a map or keyword list with `:input_tokens`, `:output_tokens`, and optionally `:total_tokens`. LLM.Usage.new(input_tokens: 10, output_tokens: 20) #=> %LLM.Usage{input_tokens: 10, output_tokens: 20, total_tokens: 30} """ def new(attrs) do usage = struct!(__MODULE__, attrs) total = usage.total_tokens || (usage.input_tokens || 0) + (usage.output_tokens || 0) %{usage | total_tokens: total} end end