Models overview
Ongrid does not ship with a baked-in model. The platform is a multi-provider router: you supply API keys for one or more upstreams, the manager surfaces the configured catalog to the SPA's per-message picker, and every chat / RCA / translate call dispatches to the right upstream at runtime.
Seven providers are supported out of the box:
| Provider | Default model | Env key |
|---|---|---|
| Anthropic | claude-sonnet-4-6 | ONGRID_ANTHROPIC_API_KEY |
| OpenAI | gpt-5.4 | ONGRID_OPENAI_API_KEY |
| Zhipu (GLM) | glm-4.7 | ONGRID_ZHIPU_API_KEY |
| DeepSeek | deepseek-v4-flash | ONGRID_DEEPSEEK_API_KEY |
| Gemini | gemini-2.5-pro | ONGRID_GEMINI_API_KEY |
| Kimi | kimi-k2.6 | ONGRID_KIMI_API_KEY |
| Custom (OpenAI-compatible) | — | ONGRID_CUSTOM_API_KEY + base URL |
Plus:
- A routing layer — pick provider per call, dynamic default.
- A budget gate — global per-UTC-day token cap.
The two configuration paths
Both paths produce the same []llm.ProviderConfig the router consumes; they differ only in who operates the knob.
Env-seeded (boot)
cmd/ongrid/main.go reads cfg.LLM.* and seeds matching rows into system_settings.llm.* via setting.Service.SetIfAbsent. First boot of a fresh install with ONGRID_ANTHROPIC_API_KEY=... ends with a working Anthropic-default install — no SPA login required.
SetIfAbsent is the key — re-boots never overwrite operator edits in the SPA.
Settings UI (runtime)
/settings/llm in the SPA lets an admin:
- Add / rotate the per-provider API key (stored in
system_settings.llm.<provider>_api_keywith the secret flag set). - Edit the BaseURL (relays, regional endpoints, China-based mirrors).
- Maintain the per-provider model list (the closed-set the picker shows).
- Pin the default model per provider.
- Pick the default provider — what the home-page chat falls back to when no per-message pin is set.
The 6 vendor cards plus the 7th "Custom" card render with their real provider mark logos (sourced from simple-icons) so admins recognise them without reading labels.
Hot swap
Provider edits take effect within 60s without a manager restart. The DB → router cache TTL is the resolver's 60s, plus the MultiClient's own 60s — so worst case 120s. Edge agents are unaffected; the manager is the only LLM client.
The resolver
LLMSettingsResolver reads from system_settings.llm.* and assembles []llm.ProviderConfig. Falls back to env defaults per field so a half-configured install (key set via env, BaseURL left blank) still works.
// internal/manager/biz/setting/llm.go:133
func (r *LLMSettingsResolver) ResolveProviders(ctx context.Context) (
providers []llm.ProviderConfig, defaultProvider string, err error,
)Provider IDs are stable strings: openai, anthropic, zhipu, gemini, deepseek, kimi, custom. These ids show up everywhere — the chat picker, audit logs, ChatReq.Provider, WithProvider option.
The catalog endpoint
GET /v1/aiops/models returns the catalog the SPA picker renders:
{
"providers": [
{
"id": "anthropic",
"label": "Anthropic",
"default_model": "claude-sonnet-4-6",
"models": ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5"]
},
{
"id": "zhipu", "label": "Zhipu (GLM)",
"default_model": "glm-4.7",
"models": ["glm-5.1", "glm-5", "glm-4.7", "glm-4.7-flash"]
}
],
"default": "anthropic"
}Providers with no API key configured are silently dropped — that's how the picker knows what's actually available. API keys themselves are never returned by this endpoint.
Per-call dispatch
A ChatReq carries a Provider field; when set, MultiClient.Chat dispatches to the matching sub-client. When empty, the router uses the configured default (DB > env > first sorted).
// internal/pkg/llm/router.go
func (m *MultiClient) Chat(ctx context.Context, req ChatReq) (*ChatResp, error)For graph-kernel calls (the ReAct agent), the equivalent is llm.WithProvider(id) as an eino model option — see Routing.
What's where
- Anthropic / OpenAI / Zhipu / DeepSeek / Gemini / Kimi / Custom — one page per provider with the env vars, the default model, and any vendor-specific quirks.
- Routing & default —
RoutingChatModel.pick, the DefaultResolver, and how to wire a non-default provider in code. - Budget & limits —
ONGRID_LLM_DAILY_TOKEN_LIMIT, theBudgetCallback, theErrBudgetExceededsemantics.
See also
- Architecture — where the LLM layer sits in the L3 intelligence layer.
- Environment variables — the full
ONGRID_*_API_KEYONGRID_*_MODEL+ONGRID_*_BASE_URLmatrix.