# Managing Models

Every model and credential task, with its TUI command and HTTP endpoint.

Everything is managed from the TUI or the local HTTP API — there is no `agen model` CLI subcommand:

| Task | TUI | HTTP |
|---|---|---|
| Add / remove a provider or model | `/model` → `add`; `d` on a model row removes it | `POST` `/v1/models`, `DELETE` `/v1/models/*name` |
| Reorder fallback priority | — | `GET` `POST` `/v1/model/priority` — `{models}` |
| Set a model's tier | `/model`, `t` on a model row | `POST` `/v1/model/tier` — `{model, tier}` |
| Pick the dispatcher model | `/model` → `dispatch` | `GET` `POST` `/v1/model` — `{dispatcher}` |
| Pick a session's reasoning level | `/model` → `reasoning` (or `Shift+A` / `Shift+D`) | `POST` `/v1/session/:id` — `{reasoning}` |
| Pick the summary model | `/model` → `summary` | `GET` `POST` `/v1/model` — `{summary}` |
| Pick the image generator | `/model` → `image` | `GET` `POST` `/v1/model` — `{image}`, a provider endpoint rather than a model name |
| Pick the speech-to-text model | `/model` → `stt` | `GET` `POST` `/v1/model` — `{stt}`, chosen from `GET /v1/model/audio` |
| Pick the text-to-speech model | `/model` → `tts` | `GET` `POST` `/v1/model` — `{tts}`, chosen from `GET /v1/model/audio` |
| Pick a session's model | `/model` (or `Shift+W` / `Shift+S` to cycle `auto` and registered models) | `POST` `/v1/session/:id` — `{model, reasoning}` |
| Store a credential | `/key` | `POST` `/v1/provider/:provider/key` |
| OAuth login | `/model` | `GET` `/v1/provider/:provider/oauth` (SSE device code) |
| Clear an OAuth login | `/model` | `DELETE` `/v1/provider/:provider/oauth` |
| Check quota / balance | `Shift+U` | `GET` `/v1/providers/quota`; one model's provider: `GET` `/v1/model/quota?model=<name>` |

Model routing is one object: `GET` / `POST` `/v1/model` reads and partially updates `dispatcher`, `summary`, `image`, `stt`, and `tts` together. A field left out is untouched, `""` clears it. In `config.json` these land as `dispatcher_model`, `summary_model`, `image_generator`, `stt_model`, and `tts_model`.

Audio routing is separate from the model registry. `stt` and `tts` are not picked from the models you registered with `/model add` — they are queried live from whichever of OpenAI, Gemini and OpenRouter currently hold a credential, and only those three providers back audio today (OpenRouter was added in v1.0.17). Selecting `off` for `tts` also removes `generate_audio` from the tool set; selecting `off` for `stt` stops `read_files` from transcribing audio and video, and makes inbound Telegram / Discord voice messages refuse with a hint to pick a model.

Credentials (API keys, OAuth tokens) live in the OS keychain under service `agenvoy`, never in plain JSON. `config.json` keeps only the list of stored key names under `keys`.

The daemon watches `config.json`; a write reloads the agent registry (and reconnects Telegram / Discord) without a restart.

Since v1.0.13 a registry entry holds only the model name and resolves its provider config on every `Send` instead of building the client once at startup, so an OAuth token refreshed in the keychain takes effect on the next request rather than at the next registry reload.
