PhoenixKitAI.ManualPrice (PhoenixKitAI v0.26.1)

Copy Markdown View Source

A price entered by hand on an endpoint whose provider gives none (Z.ai, say): provider_settings["pricing"] — %{"model" => id, "input" => "0.60", "output" => "2.2"}, US dollars per 1M input and output tokens as decimal strings (a JSON number would read back as a float), both required, for the model it names. The endpoint's changeset stamps the model when none is given and drops the price when the endpoint's model changes (like a capability declaration).

A call whose provider reports no usage.cost and whose model no catalogue prices gets its cost from it (cost/3), and its usage row says cost_source: "manual" (PhoenixKitAI.CallCost keeps the order of the sources). Money limits and the daily budget then count the call like any other. That is chat, embeddings and the vision verbs (describe_image/3, extract_text/3, compare_images/4), for a call sent to the price's model. Making or editing images (generate_image/3, edit_image/4, process_image/4) is priced per image or per call, not per token, so a manual price does not apply there: those calls keep only the provider's own cost.

A price whose halves are integers is in the shape the released versions stored (millionths of a dollar); legacy?/1 says so, the module's migration chain converts it, and a call on such an endpoint is refused until it has.

Summary

Functions

What a call costs at a price per 1M tokens, in dollars, not rounded: (input_tokens × input + output_tokens × output) / 1_000_000. nil when a price the tokens need is missing (no price at all, or an output price for a call with output).

The endpoint's manual price for its own model, %{"input" => dollars, "output" => dollars} per 1M tokens as Decimals, or nil — when it has none, the stored price names another model, lacks a half, or is in the legacy shape (legacy?/1).

Whether the endpoint's stored price is in the released versions' shape: integer millionths of a dollar per 1M tokens.

The highest price per 1M tokens, in dollars ($10 000).

Checks a stored price: "input" and "output" both, dollar strings from 0 to max/0, and an optional "model" (the model it prices). :ok or :error.

Types

t()

@type t() :: %{optional(String.t()) => Decimal.t()}

Functions

cost(pricing, input_tokens, output_tokens)

@spec cost(t() | nil, non_neg_integer(), non_neg_integer()) :: Decimal.t() | nil

What a call costs at a price per 1M tokens, in dollars, not rounded: (input_tokens × input + output_tokens × output) / 1_000_000. nil when a price the tokens need is missing (no price at all, or an output price for a call with output).

get(arg1)

@spec get(PhoenixKitAI.Endpoint.t() | map() | nil) :: t() | nil

The endpoint's manual price for its own model, %{"input" => dollars, "output" => dollars} per 1M tokens as Decimals, or nil — when it has none, the stored price names another model, lacks a half, or is in the legacy shape (legacy?/1).

legacy?(arg1)

@spec legacy?(PhoenixKitAI.Endpoint.t() | map() | nil) :: boolean()

Whether the endpoint's stored price is in the released versions' shape: integer millionths of a dollar per 1M tokens.

max()

@spec max() :: Decimal.t()

The highest price per 1M tokens, in dollars ($10 000).

validate(pricing)

@spec validate(term()) :: :ok | :error

Checks a stored price: "input" and "output" both, dollar strings from 0 to max/0, and an optional "model" (the model it prices). :ok or :error.