Agent model & providers
The research agent runs on one of three connections a rep configures on Settings → General — not a deploy-time decision, because a self-hoster's admin cannot redeploy to change a model.
| Connection | Key | Notes |
|---|---|---|
| OpenRouter | openRouterApiKey | The catalog is filtered to models that support tool calling. z-ai/glm-4.6 is the compiled default. |
| Anthropic | anthropicApiKey | A maintained list of the current Claude family. |
| Custom OpenAI-compatible | customModelBaseUrl / customModelApiKey | OpenAI itself, a self-hosted Ollama, anything speaking the API. Every listed model is offered; an incompatible one fails loudly on the first tool call. |
Any combination can be configured at once. The model picker merges all three catalogs, and picking a model from any of them is what decides which one runs — along with a stored note of which connection it came from, since two catalogs could in principle report the same id.
It's a setting, not an env var
Every key and the chosen model id live in a database row. None of it is a deploy-time decision. The choice takes effect on the agent's very next step — nothing needs a restart.
No key, no fallback
Unlike every other capability in the product, having no connection configured doesn't narrow what the agent can do — a connection is what runs it. A session with nothing configured fails clearly rather than quietly running on some other model. There is deliberately no free default wired in as a safety net.
Not a frontier model, on purpose
The hard part of this job is refusing a plausible-looking wrong answer, and that's enforced by the tools and the evidence model rather than by model strength. What the job wants is a long context window — a company preamble hands over every contact on the account — and answers fast enough that the Agent tab reads as a conversation. The context window travels with the model id, so a model with a smaller window than the default is compacted against the right number.
Degrades, doesn't throw
A failed settings read — no row, no database, a resolver that raises — leaves the compiled fallback in force and logs why, rather than letting a session quietly run on a model nobody chose.