API Reference PhoenixKitAgent v#0.1.0

Copy Markdown View Source

Modules

AI agent module for PhoenixKit.

Files attached to a chat (spec §5.3, §9).

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: …].

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.

What an uploaded file is, told by its content (spec §9: png/jpg/webp/heic, pdf, xlsx/csv, txt/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.

Takes the metadata out of a JPEG, without decoding or re-encoding it.

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}.

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.

Reads the parts of a workbook out of an uploaded zip without trusting it.

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.

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.

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.

The chats and messages of the assistant (spec §5.1-5.2, §8, §10).

Gettext backend of the agent module's admin pages and permission labels.

The module's own Storage library, where attachment bytes are kept.

The spending and turn limits of a user (spec §7.3) and who is told when one is near or reached (spec §7.4).

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).

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.

The system prompt of a turn (spec §7.1), put together in the order of priority, each part separated by a blank line

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.

A user's chat with the assistant (phoenix_kit_agent_conversations).

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:<period>". 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.

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.

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.

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.

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).

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

The two locks of a turn (spec §6.1 step 3), both rows in the database

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)

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

The processes of the turn loop, started by the host through PhoenixKitAgent.children/0

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).

The assistant settings of one user (spec §5.4, §7) and how they combine with the module's.

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.

The permission checks of the module's admin pages, made again on every event.

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.

The pieces of the chat panel (PhoenixKitAgent.Web.Dock): one message of the feed, a confirmation card and a file waiting for a message.

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.

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.

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.

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.

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.

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.

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).