docs / Configuration
Providers & models
Every way to bind an LLM, plus peak/off-peak billing windows.
connections.kdl
Providers, API keys and the active model live in ~/.config/shuvarie/connections.kdl (the file starts with a reminder that
it contains your API keys — treat it accordingly). It is written for you by
the add-provider wizard (/provider) and edited
indirectly via /model and Ctrl+T, but
you can edit it by hand:
active {
provider "67e55044-10b1-426f-9247-bb680e5fe0c8" // required: id of the default provider
model "gpt-4o" // optional: default model
variant "high" // optional: default reasoning effort
}
providers {
provider id="67e55044-10b1-426f-9247-bb680e5fe0c8" name="OpenAI" {
kind "openai" // transport, see below
catalog "ollama-cloud" // optional: catalog id for model metadata
api-key "sk-..." // required unless local or OAuth (chatgpt, copilot)
// api-key-env "OPENAI_API_KEY" // alternative: read the key from the environment
base-url "https://..." // optional: overrides the catalog endpoint
}
} Valid kind values: openai, openai-compat, openrouter, vercel, anthropic, google, azure, bedrock, google-vertex, ollama, chatgpt, copilot.
Notes:
- An API key is required unless the provider is local (
ollamaneeds none; it defaults tohttp://localhost:11434) or its catalog entry is keyless. chatgptandcopilotuse OAuth device sign-in instead of API keys: omitapi-key, and submitting the add-provider wizard opens a popup with a verification URL and code (o/Enter opens the browser, y copies the URL, c copies the code; dismissing the popup doesn’t cancel the sign-in). Tokens are cached on disk and refreshed automatically. Other kinds must configure an API key.api-keyandbase-urlvalues expand$VAR/${VAR}from the environment.api-key-envkeeps the secret out of the file: it names an environment variable, read when the connection is opened. Both spellings work —api-key-env "OPENAI_API_KEY"and the Selune-styleapi-key-env "$OPENAI_API_KEY"— and the sigil is stripped when the file is written. A literalapi-keywins over the variable, and a blankapi-keydoes not shadow it. The add-provider wizard offers the same bargain: Alt+E over the API key row flips it to the variable Selune names for that provider — but only while that variable actually holds a value, since a source that cannot resolve would only mislead.
decision-providers
Decision models (see Decisions) do not ride the completion path: they use their own decision-providers block and
an active decision selection in the same connections.kdl. The only wire
protocol today is systemone (TypeSafe’s System One API, which Ollama’s Clef
models and Cloudflare also serve):
decision-providers {
provider "ollama" { // name used to reference the connection
type "systemone"
base-url "http://localhost:11434" // host root gains /v1/systemone; a full URL is used as-is
api-key "…" // optional: local servers ignore authentication
}
}
decision {
provider "ollama" // both children are required
model "clef" // free text — decision models are not enumerable
} /decision-provider opens the dialog that writes
both blocks (name, endpoint, optional key, free-text model).
default-providers
When a prompt names a model as <provider_kind>/<model> (for example a
custom command’s model: frontmatter), default-providers says which
connection to use for each connection type:
default-providers {
use id="67e55044-10b1-426f-9247-bb680e5fe0c8"
} registries
The built-in model/provider registry is selune. Popups fetch catalog data
on demand — press Ctrl+O to toggle between offline and hosted
sources — or refresh at startup with remote-first #true (5 s timeout):
registries {
selune {
remote-first #false
// disabled #true // add #true to switch the registry off
}
} Add your own registry with a registry block — an offline snapshot
(path) and/or a remote source (url), plus optional request headers. name is required and must not be selune (it is always defined):
registries {
registry {
name "internal"
url "https://registry.example.com/catalog.json"
path "~/.cache/shuvarie/internal.json" // optional offline snapshot
headers { Authorization "Bearer $REGISTRY_TOKEN" }
// disabled #true
remote-first #false
}
} registries merges key-by-key across config layers.
Peak/off-peak schedules
Some providers bill a model at a higher rate inside fixed windows of the day.
Those windows come from the catalog, not from your config: a provider (or a
single model of it) declares its periods, the timezone they are stated in
(default UTC) and, optionally, the day classes they skip (weekends, holidays-us, …) — DeepSeek’s 09:00–12:00 and 14:00–18:00 Asia/Shanghai, for example. A model’s own schedule overrides the
provider-wide one.
When the active model has a schedule, the sidebar’s context panel carries a
live countdown to the end of the current phase — Peak ends in 2h in red, Off-Peak ends in 1d 4h in green — and /peak-table lists the day’s windows (and the
exempt day classes) in the schedule’s zone, UTC or your machine’s local time,
with t cycling the clock. A model without a schedule shows neither.
embedding
Embeddings power session search. Default per provider: ollama ⇒ nomic-embed-text with 768 dimensions, Google ⇒ gemini-embedding-001.
embedding {
provider "ollama"
model "nomic-embed-text"
dimensions 768
// disabled #true // add #true to switch embeddings off
}