The choice of a model for a user (spec §7.2). The module has no models of its
own: the choice is among the endpoints of phoenix_kit_ai (an endpoint is a
connection plus a model), and only endpoints that can chat.
list_endpoints/1 is the choice; tools_support/1 says, per endpoint,
whether its model takes tools — the assistant is useless on one that does
not, so the screens mark those. image_input_support/1 is the same question
about images in; the attachments (spec §9) use it to decide whether a
picture goes to the model as pixels or as a description. Both read
PhoenixKitAI.Capabilities.for_endpoint/1 — the provider's catalogue as
phoenix_kit_ai keeps it, with what an admin declared on the endpoint where
the catalogue says nothing — from its cache only, never the network:
:supported/:unsupported— the model is known to take it, or not;:unknown— nobody knows: a provider without a catalogue whose endpoint declares nothing, a model the catalogue does not list, a catalogue not read yet.
Only :supported lets pixels go to a model (image_input/1).
reports_cost?/2 says whether a call on an endpoint gets what it cost in
the AI journal — the money limits count only such calls (spec §7.3).
Summary
Types
What a call on an endpoint is: a model call of a turn, or a picture described by the vision model.
What a page shows of an endpoint: never the endpoint itself, which carries
its API key. reports_cost? is reports_cost?/2 of a chat call on it.
Whether a model takes tools.
Functions
image_input_support/1 for the one endpoint with this uuid, read again from
the database. :unknown for no endpoint (nil) and for one that does not
exist.
Whether each endpoint's model takes images as input (see the moduledoc):
%{endpoint_uuid => support}. A model that can only produce images does not.
image_input_support/1 for the endpoints with these uuids, read again from
the database (one that is gone is left out).
The endpoints a user can be given: enabled ones that chat (not speech,
embedding or image models), by name. include: uuid (or a list of uuids)
adds that endpoint even if it can no longer be picked — the one a user has
now, so that saving the form does not drop it unnoticed.
Whether a call on the endpoint gets what it cost in the AI journal, as
phoenix_kit_ai prices it. On an endpoint where it does not, money is not
counted and only the turn limit applies.
The endpoints with these uuids as summary/0: %{uuid => summary}.
An endpoint as a page keeps it (summary/0).
Whether each endpoint's model takes tools (see the moduledoc): %{endpoint_uuid => support}.
tools_support/1 for the endpoints with these uuids, read again from the
database (one that is gone is left out).
Types
@type call_kind() :: :chat | :vision
What a call on an endpoint is: a model call of a turn, or a picture described by the vision model.
@type summary() :: %{ uuid: String.t(), name: String.t(), model: String.t(), provider: String.t(), reports_cost?: boolean() }
What a page shows of an endpoint: never the endpoint itself, which carries
its API key. reports_cost? is reports_cost?/2 of a chat call on it.
@type support() :: :supported | :unsupported | :unknown
Whether a model takes tools.
Functions
image_input_support/1 for the one endpoint with this uuid, read again from
the database. :unknown for no endpoint (nil) and for one that does not
exist.
@spec image_input_support([PhoenixKitAI.Endpoint.t()]) :: %{ required(String.t()) => support() }
Whether each endpoint's model takes images as input (see the moduledoc):
%{endpoint_uuid => support}. A model that can only produce images does not.
image_input_support/1 for the endpoints with these uuids, read again from
the database (one that is gone is left out).
@spec list_endpoints(keyword()) :: [PhoenixKitAI.Endpoint.t()]
The endpoints a user can be given: enabled ones that chat (not speech,
embedding or image models), by name. include: uuid (or a list of uuids)
adds that endpoint even if it can no longer be picked — the one a user has
now, so that saving the form does not drop it unnoticed.
@spec reports_cost?(PhoenixKitAI.Endpoint.t() | summary() | nil, call_kind()) :: boolean()
Whether a call on the endpoint gets what it cost in the AI journal, as
phoenix_kit_ai prices it. On an endpoint where it does not, money is not
counted and only the turn limit applies.
:chat(a model call of a turn) —PhoenixKitAI.reports_cost?/1: the provider reports the cost (OpenRouter), or the operator's catalogue, a manual price on the endpoint or Anthropic's list price prices its model.:vision(a picture described,PhoenixKitAI.describe_image/3) —PhoenixKitAI.TaskLimits.money_counted?/2with:vision, which is the chat rule:phoenix_kit_aiprices a description like a chat call (the provider's cost, a catalogue, a manual or a list price).
A summary/0 carries the answer for :chat.
The endpoints with these uuids as summary/0: %{uuid => summary}.
@spec summary(PhoenixKitAI.Endpoint.t()) :: summary()
An endpoint as a page keeps it (summary/0).
@spec tools_support([PhoenixKitAI.Endpoint.t()]) :: %{ required(String.t()) => support() }
Whether each endpoint's model takes tools (see the moduledoc): %{endpoint_uuid => support}.
tools_support/1 for the endpoints with these uuids, read again from the
database (one that is gone is left out).