# `PhoenixKitAgent`
[🔗](https://github.com/BeamLabEU/phoenix_kit_agent/blob/v0.1.0/lib/phoenix_kit_agent.ex#L1)

AI agent module for PhoenixKit.

A personal assistant inside a PhoenixKit application: per-user chats kept
in the database, files attached to messages, a managed system prompt, and a
model-and-tools loop over the PhoenixKit API registry. Model calls, endpoints,
credentials, budget and the request journal come from `phoenix_kit_ai`.

## System Management

- `enabled?/0` - Check if the agent module is enabled (default: off)
- `enable_system/0` - Enable the agent module
- `disable_system/0` - Disable the agent module

## Permissions

- `agent` — use the assistant.
- `agent.manage` — the module defaults, other users' settings and spending.
  Core gives every module sub-key to the Admin role automatically, so Admin
  holds `agent.manage` from the first boot; that is accepted (spec §8).

There is deliberately no `agent.view_all`: auto-granted to Admin, it would
open every user's chats — with the customer data their tool results hold —
to every Admin.

## Data

Tables come from the module's own migration chain
(`PhoenixKitAgent.Migrations`); attachment bytes live in a hidden Storage
library (`PhoenixKitAgent.Library`); module settings are read through
`PhoenixKitAgent.Config`. Deleting a user runs
`PhoenixKitAgent.UserDeletion` first.

# `ai_tasks`

```elixir
@spec ai_tasks() :: [PhoenixKitAI.TaskSpec.t()]
```

The AI tasks of the module, for the guard of `phoenix_kit_ai`
(`PhoenixKitAI.Tasks`):

  * `agent.chat` — the model calls of a turn. They need tools. A turn is
    admitted once (`PhoenixKitAI.Guard.admit/4` in `PhoenixKitAgent.Turns`),
    and the model may flag a request as off-purpose (`self_flag`).
  * `agent.attachment` — a picture described by the vision model. It needs
    images in.

Both are private: only holders of `ai.manage` see the reasons of their
flags and blocks. Both share the `free_text` block group with the AI
Playground. The module keeps its own per-user limits
(`PhoenixKitAgent.Limits`), so the guard has no user limits for them
(`user_limits: false`), only the limits of the task.
`typical_tokens` of the chat is the median of the assistant's calls
on a running site.

# `before_user_delete`

Before a user row is deleted: removes their attachment files from the
module's hidden library (only files nothing else uses), their folder there,
and their uuid from other users' notice lists and from the limit watchers.
Their rows in the module's tables go with the user (`ON DELETE CASCADE`).
See `PhoenixKitAgent.UserDeletion`.

# `disable_system`

```elixir
@spec disable_system() :: {:ok, term()} | {:error, term()}
```

Disables the agent module.

# `enable_system`

```elixir
@spec enable_system() :: {:ok, term()} | {:error, term()}
```

Enables the agent module.

# `enabled?`

```elixir
@spec enabled?() :: boolean()
```

Returns whether the agent module is enabled. Defaults to `false`, including
when the setting cannot be read.

# `handle_ai_usage`

```elixir
@spec handle_ai_usage(struct()) :: :ok
```

The `phoenix_kit_ai` usage sink: a request row whose `attribution` names an
assistant message (`"agent_message_uuid"`) is linked to it
(`messages.ai_request_uuid`). See `PhoenixKitAgent.Turns.Runner`.

# `header_widget_session`

```elixir
@spec header_widget_session(map()) ::
  %{required(String.t()) =&gt; String.t() | nil} | nil
```

The session of the chat panel, from the admin layout's assigns: the user's
uuid and locale and nothing else, or `nil` — no panel — when the module is
off, the session's scope does not hold `agent`, or the layout says the
account is borrowed (`:impersonating?`, a hint only: the panel checks the
session itself in its connected mount). Runs on every render of the layout,
so it reads only the scope and the cached module switch.

# `header_widgets`

The assistant in the admin header (spec §10): the chat panel
`PhoenixKitAgent.Web.Dock`, before the notifications bell, in the dock
column. Its session comes from `header_widget_session/1`.

# `notification_types`

The notification type of the module: `"agent_limit"`, what the watchers get
when someone reaches a limit of the assistant (`PhoenixKitAgent.Limits`). A
refusal of the AI budget is told by `phoenix_kit_ai`, under its own type. A
watcher can switch it off for themselves.

---

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