struct

Arcana::AI::Usage

Inherits JSON::Serializable < Struct < Value < Object

What a call used, in the categories providers bill by, the same for every provider. Providers report usage differently (OpenAI's and Gemini's prompt counts include cached tokens, Anthropic's doesn't; Gemini counts thinking apart from output), so each provider fills this in from its own report:

  • input: input tokens billed at the full input rate, never cached ones.
  • cache_read: input tokens read from the provider's prompt cache.
  • cache_write: input tokens written to the cache at the provider's standard write rate (Anthropic's 5-minute cache, OpenAI's cache).
  • cache_write_1h: input tokens written to Anthropic's 1-hour cache.
  • output: output tokens, reasoning included. Text only, for models that also make images or audio.
  • reasoning: the part of output spent reasoning, when reported.
  • image_input: image tokens in the input, for image models that price them apart from text (OpenAI's GPT Image). Chat models count input images in input.
  • image_output: image tokens generated.
  • audio_output: audio tokens generated (OpenAI's speech models).
  • web_searches, code_executions: server-side tool calls.
  • tier: the service tier the call ran on, "standard" for the provider's standard tier, nil when not reported.
  • geo: where the provider says it ran the call (Anthropic's inference_geo), when reported.

A response carries a Usage only when the provider reported one: a nil usage means it didn't, never that the call was free.

Constructors

new(input : Int64 = 0_i64, output : Int64 = 0_i64, cache_read : Int64 = 0_i64, cache_write : Int64 = 0_i64, cache_write_1h : Int64 = 0_i64, reasoning : Int64 | Nil = nil, image_input : Int64 = 0_i64, image_output : Int64 = 0_i64, audio_output : Int64 = 0_i64, web_searches : Int64 = 0_i64, code_executions : Int64 = 0_i64, tier : String | Nil = nil, geo : String | Nil = nil)
Source
new(*, __pull_for_json_serializable pull : JSON::PullParser)
Source

Class methods

from_anthropic(usage : JSON::Any | Nil) : Usage | Nil

From an Anthropic usage object, whose input_tokens leave out the cache reads and writes. Writes go to the 5-minute cache unless the cache_creation breakdown puts them in the 1-hour one.

Source
from_gemini(meta : JSON::Any | Nil) : Usage | Nil

From Gemini's usageMetadata, whose promptTokenCount includes the cached tokens and whose candidatesTokenCount leaves out the thoughts. Tool-use prompt tokens (fetched pages, search results) bill as input.

Source
from_openai(usage : JSON::Any | Nil, service_tier : String | Nil = nil) : Usage | Nil

From an OpenAI (or compatible) usage object, whose prompt_tokens include the cached tokens and the cache writes. service_tier is the response's own field; OpenAI calls its standard tier "default". Nil when usage isn't an object.

Source
from_openai_image(usage : JSON::Any | Nil) : Usage | Nil

From the usage of an OpenAI Images API response, which splits the input into text and image tokens. Its output is image tokens, unless output_tokens_details says some were text. Nil when there's no usage, or when it doesn't account for every input token (a split missing or not adding up), since those couldn't be priced exactly.

Source
from_openai_speech(usage : JSON::Any | Nil) : Usage | Nil

From the usage that ends an OpenAI speech event stream: text tokens in, audio tokens out.

Source

Instance methods

+(other : Usage) : Usage

Two calls' usage together, as for an embedding run split into batches. The tier and region carry over only when both agree.

Source
audio_output
Source
cache_read
Source
cache_write
Source
cache_write_1h
Source
code_executions
Source
image_input
Source
image_output
Source
input
Source
output
Source
prompt

The whole prompt: input plus cache reads and writes, and input images. Prices that change with prompt length go by this.

Source
reasoning
Source
tier
Source
web_searches
Source