Model Profiles Plugin
The Model Profiles plugin lets authenticated users define their own named LLM profiles (model id, base URL, API key, thinking options) and assign them to specific agent roles — overriding which model each role uses for that user's turns. Deployers control whether users may bring their own API keys and which endpoints are allowed.
Using it
On the web
Open Settings → Models. Two of its three tabs are this plugin's:
- Connections — create a named profile (model id, base URL, your API key), optionally Test it with a tiny live completion, and Use this profile to adopt a deployer-published one. A profile is called a connection here because that is what it is: an endpoint plus a key.
- Role map — pick Custom in the mode selector and every role that asks for a model gets a row: its name in words, one line saying what it does, the connection you assigned (or inherited), and the model id that actually resolves. Assigning is a dropdown per row; the rest of the table shows you what happens if you leave it alone. Without the Thinking Modes plugin there is no mode selector and the table lists your assignments only — an unassigned role reads not set, because working out what it would inherit is that plugin's job.
Assignments made in the Custom role map are the same per-user assignments this
plugin has always stored — they are what the
Thinking Modes plugin surfaces as the implicit Custom
mode.
Roles you can assign: main_agent, a catch-all default, subagent,
agentic_developer, agentic_memory_store, context_summarization,
explore, goal, web_retrieve, web_search, auto_title, translation
and voice_mediator.
In the terminal UI
Settings → Model Profiles shows both halves in one pane: the role map
first, then the profile list with its Add / Edit / Test / Del buttons. The map
is the web's, drawn for a terminal — a Mode dropdown at the top chooses
which mode it describes, every role gets its name in words, one line saying
what it does and the resolved connection → model-id with the same badge, and
the rows turn into dropdowns on Custom. Without the
Thinking Modes plugin there is no mode dropdown and the
map lists your own assignments, unassigned roles reading not set.
Everywhere
Deployers can define read-only admin profiles in the main models.profiles
block. Users may adopt those by supplying their own key.
Overrides apply only to authenticated users, and only while their turn is running.
Configuration
plugins:
- module: codumentor.plugins.model_profiles
class: ModelProfilesPlugin
priority: 5
args:
enabled: true
allow_custom_api_keys: true
max_profiles_per_user: 20
# allowed_base_urls: ["https://openrouter.ai/api/v1"]
Not enabled in the default shipped config; uncomment or add the snippet above to turn it on. Managing profiles requires the model_profiles:manage permission (power_user and admin have it by default) — without it, Settings → Models still shows the role map, read-only.
| Parameter | Type | Default | Description |
|---|---|---|---|
enabled | bool | true | Whether the plugin is active. |
allow_custom_api_keys | bool | true | Allow users to store their own API keys in profiles. When false, users can only use deployer-defined profiles. |
allowed_base_urls | list | unset | Allow-list of permitted endpoint base URLs. Omit or leave empty to allow any. |
max_profiles_per_user | int | 20 | Maximum profiles per user. |
data_dir | string | agent storage dir, else ./data | Where profile data is stored. |
previous_jwt_secrets | list | unset | Older JWT secrets, so profiles encrypted under a rotated key can still be decrypted. |
Notes
- Encryption at rest: API keys are encrypted with a key derived from
auth.jwt_secret(see User Secrets). Without a configured secret, keys fall back to plaintext. - A test action in the settings UI sends a tiny completion to verify a profile's endpoint, model, and key before you rely on it.
- The Role map's fourth column is the resolved
role → connection → model-idchain, and its badge says why —assigned,inherited,serverorbuilt-in model. It is the fastest way to check that an assignment did what you meant. - This is the per-user counterpart to the deployer-level
models.profilesblock in the main configuration.