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.