# `ReqLLM.Usage`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/usage.ex#L1)

Usage normalization helpers.

Provides a stable entrypoint for normalizing provider usage maps to ReqLLM's
canonical usage shape.

# `merge`

```elixir
@spec merge(map(), map()) :: map()
```

Merge two usage maps and take the maximum numeric value for each field.

Canonical token counters can be numbers or base-10 integer strings. Valid
integer strings are normalized before cumulative values are compared.
Malformed counters remain visible when no valid value exists, but they do
not replace an earlier valid counter and are not used to recompute totals.
Missing input or output counters keep the existing zero default.

# `normalize`

```elixir
@spec normalize(map() | any()) :: map()
```

Normalize usage into a canonical map.

Guarantees these canonical keys:
- `:input_tokens`
- `:output_tokens`
- `:total_tokens`
- `:input_includes_cached`

Also guarantees compatibility aliases:
- `:input`
- `:output`
- `:cached_tokens` for `:cache_read_tokens`
- `:cache_creation_tokens` for `:cache_write_tokens`

Prompt cache reads and writes are available as separate counters:
- `:cache_read_tokens`
- `:cache_write_tokens`

`:input_tokens` keeps the provider's counting rules. Read
`:input_includes_cached` to determine how the cache counters relate to it:

- `true`: input includes cache reads and writes, as in OpenAI usage.
- `false`: input excludes cache reads and writes, as in Anthropic usage.
  Add `:cache_read_tokens` and `:cache_write_tokens` to obtain the full
  prompt count.

An explicit `:input_includes_cached` value is preserved. Otherwise, the
flag is inferred from the usage format and defaults to `true` when the
format is unknown. Non-map inputs return zero counters and this flag set
to `true`.

A valid explicit `:total_tokens` value is preserved. When no total is
supplied, the total is `:input_tokens + :output_tokens`. This derived
total excludes cache reads and writes when `:input_includes_cached` is
`false`. It is therefore not always the full token count for the request.

Canonical counters accept numbers and base-10 integer strings. Malformed
component counters remain visible instead of becoming zero. A malformed
explicit total is replaced only when valid input and output counters can
produce a derived total.

# `zero`

```elixir
@spec zero(map() | any()) :: map()
```

Zero out a usage map for application-layer cache hits.

Existing keys are preserved where possible, but numeric values are reset so
callers can reliably distinguish response-cache hits from provider-native
cache reads that still incur an API call.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
