# PhoenixKitAgent v0.1.0 - Table of Contents > AI agent module for PhoenixKit — per-user chats with tool calling over the PhoenixKit API registry ## Modules - [PhoenixKitAgent](PhoenixKitAgent.md): AI agent module for PhoenixKit. - [PhoenixKitAgent.Attachments](PhoenixKitAgent.Attachments.md): Files attached to a chat (spec §5.3, §9). - [PhoenixKitAgent.Attachments.Bounds](PhoenixKitAgent.Attachments.Bounds.md): The technical bounds of attachment processing (spec §9): how much of a file the model is given and how long the work may take. They are not settings of the module; a host or a test may override them with `config :phoenix_kit_agent, attachment_limits: [text_chars: …]`. - [PhoenixKitAgent.Attachments.Cmd](PhoenixKitAgent.Attachments.Cmd.md): Runs the external programs of attachment processing (`pdfinfo`, `pdftotext`, `pdftoppm` — poppler) with a time limit, and says plainly when one is not installed. What a program prints is never returned or logged on failure: it can quote the file. - [PhoenixKitAgent.Attachments.Detect](PhoenixKitAgent.Attachments.Detect.md): What an uploaded file is, told by its content (spec §9: png/jpg/webp/heic, pdf, xlsx/csv, txt/md). - [PhoenixKitAgent.Attachments.Extract](PhoenixKitAgent.Attachments.Extract.md): Turns the bytes of an attachment into what the model reads (spec §9): the text of a text file, a CSV file or a PDF; CSV text of a workbook; JPEG or PNG pictures of an image or of the first pages of a scan. - [PhoenixKitAgent.Attachments.Jpeg](PhoenixKitAgent.Attachments.Jpeg.md): Takes the metadata out of a JPEG, without decoding or re-encoding it. - [PhoenixKitAgent.Attachments.Processor](PhoenixKitAgent.Attachments.Processor.md): The work done on an attachment before the turn that sends it (spec §9), in a task under `PhoenixKitAgent.Attachments.TaskSupervisor`: the row goes from `pending` to `ready` with what the model will read, or to `failed` with a code in `error`; the chat's topic then hears `{:agent_attachment_processed, conversation_uuid, attachment_uuid}`. - [PhoenixKitAgent.Attachments.Slots](PhoenixKitAgent.Attachments.Slots.md): The places for work on files on the node (spec §9): at most `Bounds` `concurrent_jobs` files are processed at the same time, of whom at most `jobs_per_user` are one user's. A file that finds no place waits for one, in turn, up to `queue_wait_ms`; with `queued_jobs` waiting already, or when the time is up, it is refused (`{:error, :unavailable}`) and the file `failed` as `unavailable`. - [PhoenixKitAgent.Attachments.Unzip](PhoenixKitAgent.Attachments.Unzip.md): Reads the parts of a workbook out of an uploaded zip without trusting it. - [PhoenixKitAgent.Attachments.Work](PhoenixKitAgent.Attachments.Work.md): The scratch space of attachment processing: a private directory tree in the system's temporary directory (`pk_agent_att/`), where a user's file is copied to be read and the pages of a scan are rendered. - [PhoenixKitAgent.Config](PhoenixKitAgent.Config.md): The module settings (`phoenix_kit_settings`, keys `agent_*`) and their defaults. A per-user value (`PhoenixKitAgent.Schemas.UserSettings`) wins over these; these win over the built-in defaults below. - [PhoenixKitAgent.Confirmations](PhoenixKitAgent.Confirmations.md): The confirmation cards of the chat (spec §12 Ф2, Б2.2): a write the model asked for waits for the user, who runs it, turns it down or asks for it again. - [PhoenixKitAgent.Conversations](PhoenixKitAgent.Conversations.md): The chats and messages of the assistant (spec §5.1-5.2, §8, §10). - [PhoenixKitAgent.Gettext](PhoenixKitAgent.Gettext.md): Gettext backend of the agent module's admin pages and permission labels. - [PhoenixKitAgent.Library](PhoenixKitAgent.Library.md): The module's own Storage library, where attachment bytes are kept. - [PhoenixKitAgent.Limits](PhoenixKitAgent.Limits.md): The spending and turn limits of a user (spec §7.3) and who is told when one is near or reached (spec §7.4). - [PhoenixKitAgent.Migrations](PhoenixKitAgent.Migrations.md): Module-owned versioned migrations for `phoenix_kit_agent` — the protocol core's `mix phoenix_kit.update` discovers through `PhoenixKitAgent.migration_module/0` (`current_version/0`, `migrated_version_runtime/1`, `up/1`, `down/1`). Same shape as `PhoenixKitDashboards.Migrations`: two version readers, `up/1` re-reading the version before it changes anything, the SQL kept as data (`up_statements/2`, `down_statements/2`). - [PhoenixKitAgent.Models](PhoenixKitAgent.Models.md): 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. - [PhoenixKitAgent.Prompt](PhoenixKitAgent.Prompt.md): The system prompt of a turn (spec §7.1), put together in the order of priority, each part separated by a blank line - [PhoenixKitAgent.Schemas.Attachment](PhoenixKitAgent.Schemas.Attachment.md): A file attached to a message (`phoenix_kit_agent_attachments`). The bytes live in Storage, in the module's hidden library (`file_uuid`); the row keeps what the model reads: the extracted text of a PDF or a sheet, truncated to a limit. - [PhoenixKitAgent.Schemas.Conversation](PhoenixKitAgent.Schemas.Conversation.md): A user's chat with the assistant (`phoenix_kit_agent_conversations`). - [PhoenixKitAgent.Schemas.LimitEvent](PhoenixKitAgent.Schemas.LimitEvent.md): A limit notice that was sent (`phoenix_kit_agent_limit_events`): at most one per user, kind and period (`period_key` is `"2026-10-19"` for a day, `"2026-10"` for a month), which is how a limit is announced once. A `warn_80` row names its limit in the key — `"cost:2026-10-19"`, `"cost:2026-10"`, `"turns:2026-10-19"` — so each of the three limits warns once (`PhoenixKitAgent.Limits`); the watchers' event of a limit reached is keyed `"w:"`. `used` and `limit` are in the limit's own unit (micro-dollars or turns; none for `ai_budget`). `user_uuid` is set by the caller. - [PhoenixKitAgent.Schemas.Message](PhoenixKitAgent.Schemas.Message.md): One message of a chat (`phoenix_kit_agent_messages`): what the user wrote, a model answer (with the tool calls it asked for), a tool result, or a notice (a limit, an error, a refusal). The table is also the assistant's journal of tool calls: who, what, when, and the outcome. - [PhoenixKitAgent.Schemas.UserSettings](PhoenixKitAgent.Schemas.UserSettings.md): The assistant settings of one user (`phoenix_kit_agent_user_settings`, keyed by `user_uuid`). A `nil` field means "the module default" (`PhoenixKitAgent.Config`); `enabled: false` switches the assistant off for this user even with the `agent` permission. - [PhoenixKitAgent.Spend](PhoenixKitAgent.Spend.md): What users spent on the assistant (spec §7.3), counted from the AI request journal (`phoenix_kit_ai_requests`) rather than from the module's own messages: a row of the user (`user_uuid`) whose `metadata.source` is `"agent"` — every model call of the module passes both, so a call that describes an attachment is counted too. The journal is not pruned by age, so the month never loses rows. The journal keeps a cost in dollars (`cost`, a `numeric` that can be finer than a micro-dollar); the sums are in micro-dollars ($1 = 1_000_000): each window is added up in dollars and only then rounded, half up, to a whole micro-dollar (`PhoenixKitAgent.Config.cost_to_micro/1`) — two rows of $0.0000004 are `1`, not `0`. Only endpoints that report a cost add to it. - [PhoenixKitAgent.Turns](PhoenixKitAgent.Turns.md): A turn of the assistant (spec §6.1): the user's message, then rounds of model calls and tool calls until the model answers, or until a write waits for the user's confirmation (`PhoenixKitAgent.Confirmations`). - [PhoenixKitAgent.Turns.History](PhoenixKitAgent.Turns.History.md): What a turn shows the model of the chat so far (spec §6.6): the `user` messages and the final `assistant` answers of earlier turns, newest kept first, up to `agent_history_chars`. Tool calls and tool results of earlier turns are left out — after a loss of rights the model must not see old data — and so are notices, but for one kind: the outcome of a confirmation card (`PhoenixKitAgent.Confirmations`) goes in as a `user` message with the module's own fixed phrase in the user's language — "[confirmation] done: ", "cancelled", "expired", "the data changed", "failed" — never anything the tool returned, and never a text a person wrote. So does a card with no such notice yet, where it stands in the chat: "[confirmation] waiting: ", so the model knows that its proposal still waits. Before it reads the chat, a turn gives the cards core no longer holds their notice (`Confirmations.settle_lapsed_in_turn/2`), so a card that ran out, or whose click was lost, does not read as waiting. - [PhoenixKitAgent.Turns.Locks](PhoenixKitAgent.Turns.Locks.md): The two locks of a turn (spec §6.1 step 3), both rows in the database - [PhoenixKitAgent.Turns.Monitor](PhoenixKitAgent.Turns.Monitor.md): Starts the task of each turn under `PhoenixKitAgent.Turns.TaskSupervisor`, watches it, and ends the turn whatever way the task ends (spec §6.1 step 5) - [PhoenixKitAgent.Turns.Runner](PhoenixKitAgent.Turns.Runner.md): The rounds of one turn (spec §6.1, "раунд r = 1..max_tool_rounds"), run in the turn's task. The task first stores the user's message (spec §6.1 step 4) and links its attachments, so a turn that never ran leaves nothing in the chat. Then each round - [PhoenixKitAgent.Turns.Supervisor](PhoenixKitAgent.Turns.Supervisor.md): The processes of the turn loop, started by the host through `PhoenixKitAgent.children/0` - [PhoenixKitAgent.Turns.Tools](PhoenixKitAgent.Turns.Tools.md): How the tools of a round are shown to the model, and how what it sends back is taken (spec §6.1 b, f; §6.2, §6.4). - [PhoenixKitAgent.UserConfig](PhoenixKitAgent.UserConfig.md): The assistant settings of one user (spec §5.4, §7) and how they combine with the module's. - [PhoenixKitAgent.UserDeletion](PhoenixKitAgent.UserDeletion.md): What the module does before core deletes a user (`before_user_delete/1`, spec §5.7). Core calls it outside the delete's transaction, whether or not the module is enabled, and a failure here never stops the delete. - [PhoenixKitAgent.Web.Access](PhoenixKitAgent.Web.Access.md): The permission checks of the module's admin pages, made again on every event. - [PhoenixKitAgent.Web.Dock](PhoenixKitAgent.Web.Dock.md): The assistant in the admin header (spec §10): a button before the notifications bell, the list of the user's chats under it, and the chat panel on the right. A sticky LiveView, rendered by core's admin layout as the module's header widget (`PhoenixKitAgent.header_widgets/0`), so it keeps its state across admin navigation. - [PhoenixKitAgent.Web.Dock.Components](PhoenixKitAgent.Web.Dock.Components.md): The pieces of the chat panel (`PhoenixKitAgent.Web.Dock`): one message of the feed, a confirmation card and a file waiting for a message. - [PhoenixKitAgent.Web.Dock.Panel](PhoenixKitAgent.Web.Dock.Panel.md): The markup of the chat panel (`PhoenixKitAgent.Web.Dock`) and its browser hooks: the button with the list of chats, and the panel with the feed, the indicator and the composer. The LiveView holds the state and the events; this module only draws them. - [PhoenixKitAgent.Web.Dock.Texts](PhoenixKitAgent.Web.Dock.Texts.md): What the chat panel (`PhoenixKitAgent.Web.Dock`) tells a person instead of a code: the refusals of `PhoenixKitAgent.Conversations`, `PhoenixKitAgent.Turns` and `PhoenixKitAgent.Attachments`, the codes of a failed attachment (`PhoenixKitAgent.Attachments.Processor`), the notices of a turn (stored in English, shown by their code), the states and refusals of a confirmation card (`PhoenixKitAgent.Confirmations`) and the upload errors of LiveView. A code this module does not know gets a general text, never the code itself. - [PhoenixKitAgent.Web.Markdown](PhoenixKitAgent.Web.Markdown.md): The markdown of a model answer as the chat panel shows it (spec §8.2): the text a model wrote may carry what a tool result or a file put in it, so the page must load nothing because of it. - [PhoenixKitAgent.Web.SettingsLive](PhoenixKitAgent.Web.SettingsLive.md): Settings → AI Agent: the module defaults (`PhoenixKitAgent.Config`, spec §5.6, §7) — the model the assistant uses and the one that describes pictures, the per-user limits a user without settings of their own gets, the limits of one turn, the module's system prompt and who is told when someone reaches a limit. - [PhoenixKitAgent.Web.SpendingLive](PhoenixKitAgent.Web.SpendingLive.md): Admin → Agent → Spending: what every user spent on the assistant today and this month, and how many turns they started today — everyone who used it this month, also a user who no longer holds `agent`. Money comes from the AI request journal (`PhoenixKitAgent.Spend`, micro-dollars shown as dollars; only endpoints that report a cost add to it), in the day and month of the site time zone. - [PhoenixKitAgent.Web.ToolAvailability](PhoenixKitAgent.Web.ToolAvailability.md): The card "What the assistant can use now" of the admin pages: the admin tools of every module, the ones that read and the ones that write, as core shows them for a scope (`PhoenixKit.API.Executor.tool_availability/1`) — available, or closed and why. The assistant sees exactly the available ones (`PhoenixKitAgent.Turns.Tools`: core's `visible_for/3` with `allow: :all`, no filter of the module's own), and a write still waits for the user's confirmation. - [PhoenixKitAgent.Web.UsersLive](PhoenixKitAgent.Web.UsersLive.md): Admin → Agent → Users: the people who hold the `agent` permission, each with the model they use, their limits, what they spent today and this month and whether a limit being hit is reported — and a form to set one user's settings (the switch, the model, the admin's prompt, the limits, the notice flag; `PhoenixKitAgent.UserConfig.admin_update/4`).