Models & Providers¶
Everything about how gald3r talks to LLMs — local (Ollama, LM Studio, vLLM, llama.cpp) or
cloud (OpenRouter, Anthropic, OpenAI, and any OpenAI-compatible endpoint). Every command output
on this page was verified against a real checkout unless a block is explicitly marked
illustrative — see troubleshooting.md for that same real-output
discipline applied to doctor/selftest/errors.
At a glance¶
| Verb | What it does |
|---|---|
gald3r init-providers |
Write (or preview) a starter providers.yaml, auto-detecting installed local backends |
gald3r providers set-key |
Store a provider's API key in your OS keyring instead of the plaintext file |
gald3r connect <provider> |
Device-code sign-in for a provider account — see below for a real capture |
gald3r local-model assess |
Recommend a local model size/quant for your hardware |
gald3r local-model serve |
Print the exact copy-pasteable command to serve that recommendation |
providers.yaml anatomy¶
gald3r init-providers¶
gald3r init-providers --help
Get set up to use local LLMs (Ollama, LM Studio, vLLM, llama.cpp) -- auto-detects what's
installed and writes the config for you.
Flags:
--dry-run Print the rendered starter YAML without writing it
--overwrite Replace an existing providers.yaml instead of leaving it untouched
--target string Destination path (default: <gald3r home>/providers.yaml)
The default location is <gald3r home>/providers.yaml — that home directory resolves to
$GALD3R_HOME when set, else ~/.gald3r (the same directory gald3r doctor reports on its
gald3r_home line). It is one file shared across every project on the machine — provider
credentials are a per-install concern, not a per-project one — pass --target to point at a
different path if you need one.
The full starter file (real capture)¶
gald3r init-providers --dry-run
# providers.yaml
# Edit to add/remove providers. API keys with $ prefix are env var references.
default_provider: ollama
default_model: qwen2.5:7b-instruct
providers:
ollama:
type: openai_compat
base_url: http://localhost:11434/v1
api_key: ollama
models:
- id: qwen2.5-coder:14b
role: coding
context_window: 32768
- id: qwen3:4b
role: general
context_window: 32768
- id: qwen3-vl:4b
role: vision
context_window: 32768
- id: deepseek-r1:32b
role: reasoning
context_window: 65536
- id: llava:7b
role: vision
context_window: 4096
- id: gpt-oss:20b
role: coding
context_window: 65536
- id: gpt-oss:120b
role: coding_heavy
context_window: 131072
lmstudio:
type: openai_compat
base_url: http://localhost:1234/v1
api_key: lm-studio
models:
- id: Qwen2.5-Coder-14B-Instruct-GGUF/Qwen2.5-Coder-14B-Instruct-Q4_K_M.gguf
alias: qwen2.5-coder-14b
role: coding
context_window: 32768
# ... (more LM Studio entries, trimmed here — see the full block this
# page's Ollama/LM Studio recipes below reproduce in full)
openrouter:
type: openai_compat
base_url: https://openrouter.ai/api/v1
api_key: $OPENROUTER_API_KEY
models:
- id: anthropic/claude-sonnet-4-5
role: planning
- id: google/gemini-2.5-flash
role: general_cheap
- id: qwen/qwen2.5-coder-32b-instruct
role: coding_cloud
anthropic:
type: anthropic
api_key: $ANTHROPIC_API_KEY
models:
- id: claude-opus-4-5-20260514
role: planning_heavy
- id: claude-sonnet-4-5
role: planning
- id: claude-haiku-3-5
role: general_cheap
openai:
type: openai_compat
base_url: https://api.openai.com/v1
api_key: $OPENAI_API_KEY
models:
- id: gpt-4o
role: general
- id: gpt-4o-mini
role: general_cheap
(Trimmed the LM Studio block's remaining entries and one bundled Sakana Fugu provider block for
length — every provider shown above and elided is transcribed unedited from a real --dry-run
run; nothing here is invented.)
Reading the shape¶
| Key | Meaning |
|---|---|
default_provider / default_model (top-level) |
Used when you run gald3r run "..." with no --model flag at all |
providers.<id>.type |
openai_compat (anything speaking the OpenAI Chat Completions wire format — local backends, OpenRouter, OpenAI itself) or anthropic (the native Anthropic Messages API) |
providers.<id>.base_url |
Required for every openai_compat provider (irrelevant for anthropic, which has a fixed endpoint) |
providers.<id>.api_key |
A literal string, a $ENV_VAR reference (expanded at read time), or — once you run set-key — overridden transparently by an OS-keyring secret (see Keys: keyring vs. plaintext below) |
providers.<id>.models[] |
One entry per model: id (the real model identifier sent to the endpoint), optional alias (a short name you can use instead of the full id — handy for LM Studio's long GGUF filenames), optional context_window, and role |
role is organizational metadata today, not a live routing switch. Resolving a model never
reads a model's role field to pick it — the only things that select a model are an explicit
provider:model_or_alias spec, the YAML's own default_provider/default_model, or (with
neither set) that provider's first models[] entry. role exists so a human (or an agent
reading the file) can tell at a glance which model in a provider's list is meant for which job
— and it's also what init-providers' auto-discovery heuristic assigns to a newly-detected
Ollama model by name pattern (coder/code → coding, vl/vision/llava → vision,
deepseek...r1 → reasoning, a 120b tag → coding_heavy, everything else → general) when
it writes the starter file. There is no code path today that reads role back out to
auto-select a model for a task; if you want a specific model, name it explicitly.
Resolving a provider:model spec¶
--model (on gald3r run) and default_provider/default_model (in the YAML) both accept
either bare provider or provider:model_or_alias:
ollamaalone → that provider's firstmodels[]entry (qwen2.5-coder:14bin the starter file above).lmstudio:qwen2.5-coder-14b→ matched againstaliasfirst (this is exactly why LM Studio's block gives its long GGUF filenames short aliases), then against the literalid.ollama:qwen3:4b→ model ids may themselves contain colons, so only the first colon splits provider from model.- A model you name that doesn't appear in
models[]at all is still passed through as-is (model lists aren't exhaustive — you may have pulled something brand new); the real backend returns its own error if the name truly doesn't exist. See Troubleshooting below for exactly what that looks like. - An unconfigured provider id raises immediately with a clear message — also covered below.
gald3r providers set-key — keys: keyring vs. plaintext¶
gald3r providers set-key --help
Store (or delete) a provider's API key in the OS keyring
Usage:
gald3r providers set-key PROVIDER [flags]
Flags:
--delete Remove the stored keyring entry instead of setting one
--value string Secret value (omit to be prompted -- passing this flag exposes the
secret in shell history/process list, so prefer the interactive
prompt unless scripting).
gald3r providers set-key openrouter prompts (securely — nothing echoed, nothing in shell
history) and stores the secret in your OS's native keyring (Credential Manager on Windows,
Keychain on macOS, Secret Service on Linux) under service gald3r-providers, account
<provider id>. Once stored, the keyring value takes precedence over anything in
providers.yaml for that provider — a literal api_key: string or a $ENV_VAR reference
both get overridden. That precedence is deliberate: the whole point of set-key is letting you
migrate a real secret out of the plaintext file, and if the file stayed authoritative after
that migration you'd have to separately go blank it out for the migration to mean anything.
If no keyring backend is available on the system, set-key says so plainly and does not
fall back to writing the secret to a file:
gald3r providers set-key --delete gald3r_docs_probe_nonexistent
No keyring entry found for 'gald3r_docs_probe_nonexistent' (or no keyring backend is available on this system).
(Real output — a safe, non-destructive probe against a provider id that was never stored, run while writing this page.)
init_providers_file (the code behind init-providers) never writes a real secret itself —
only template placeholders (ollama, lm-studio) and $ENV_VAR references. A hand-typed
literal key in the file is still supported, but every providers.yaml load logs a warning if
it finds one (or loose file permissions, on POSIX) — prefer set-key or a $ENV_VAR reference.
Local backends¶
Each recipe below: install the runtime, pull/load a model, the providers.yaml block, and how
to confirm gald3r actually reaches it. gald3r init-providers auto-detects three of the first
four runtimes below by probing their default port for a live, unauthenticated OpenAI-compatible
/models endpoint — Ollama is discovered
differently, via its own ollama list CLI — so re-running init-providers after a backend is
up is itself the verification step for that backend. Unsloth Studio (below) is NOT part of
that auto-discovery: its /models endpoint requires a bearer token (see its own subsection),
so an unauthenticated probe would just get a 401 rather than a usable model list — configure its
providers.yaml block by hand instead.
Ollama¶
Install from ollama.com, then:
ollama pull qwen2.5-coder:14b
gald3r init-providers shells out to ollama list and writes a models: entry per installed
model automatically — the ollama: block in the full starter capture above (base URL
http://localhost:11434/v1, api_key: ollama — a dummy value Ollama ignores, not a real
credential) is exactly what that discovery produced against models actually pulled on the
machine this page's example was drafted from.
Verify: gald3r doctor's providers line reports how many providers are configured
(...\providers.yaml: N provider(s) configured — see troubleshooting.md),
or re-run gald3r init-providers --dry-run and confirm your pulled models show up under
ollama:.
LM Studio¶
Install from lmstudio.ai, load a model in its UI, and start LM Studio's
local server (Developer tab → Start Server — default port 1234). The lmstudio: block in the
starter capture above was written by the same local-runtime discovery probe hitting
http://localhost:1234/v1/models while the server this page was drafted against had those GGUF
models loaded:
lmstudio:
type: openai_compat
base_url: http://localhost:1234/v1
api_key: lm-studio
models:
- id: Qwen2.5-Coder-14B-Instruct-GGUF/Qwen2.5-Coder-14B-Instruct-Q4_K_M.gguf
alias: qwen2.5-coder-14b
role: coding
context_window: 32768
The long id is LM Studio's own model-file path — that's why init-providers' auto-discovery
gives it a short alias (qwen2.5-coder-14b) you can use instead: --model
lmstudio:qwen2.5-coder-14b.
Verify: same as Ollama — gald3r doctor or a fresh init-providers --dry-run with the LM
Studio server running.
vLLM¶
Illustrative — no vLLM instance was available to probe while writing this page, but the
shape below is grounded in the real discovery behavior: the fixed default-port table
probes vLLM at http://localhost:8000/v1 by default, and
render_starter_yaml's block-writer sets type: openai_compat, that base_url, a placeholder
api_key: local (vLLM's OpenAI-compat server doesn't check it locally), and one models: entry
per id the /models probe returns — the exact same code path the real Ollama/LM Studio blocks
above went through.
pip install vllm
vllm serve Qwen/Qwen2.5-Coder-14B-Instruct --port 8000
vllm:
type: openai_compat
base_url: http://localhost:8000/v1
api_key: local
models:
- id: Qwen/Qwen2.5-Coder-14B-Instruct
role: coding
Verify: start vllm serve, then run gald3r init-providers --dry-run — a reachable vLLM
server on port 8000 gets auto-discovered and written into the block exactly like LM Studio's,
the same way you'd confirm any of these.
llama.cpp¶
Illustrative — same honesty note as vLLM above. llama.cpp's server binary (or
llama-server) defaults to port 8080 in the local-runtime discovery table:
# build llama.cpp per its own README, then:
llama-server -m ./models/qwen2.5-coder-14b-q4_k_m.gguf --port 8080
llama-cpp:
type: openai_compat
base_url: http://localhost:8080/v1
api_key: local
models:
- id: qwen2.5-coder-14b-q4_k_m
role: coding
Verify: identical pattern — gald3r init-providers --dry-run with the server running
auto-discovers it via the same /models probe.
Unsloth Studio¶
Illustrative — no live Unsloth Studio instance was available to probe while writing this
page; the shape below is sourced directly from Unsloth's own docs
(unsloth.ai/docs/desktop and its linked API guide,
unsloth.ai/docs/basics/api.md), verified against
those docs directly — not guessed, and not (yet) confirmed against a running instance. Unsloth
Studio is a new open-source local AI engine from the Unsloth team
(github.com/unslothai/unsloth); gald3r treats it as a
fourth "known" local runtime alongside Ollama/LM Studio/OpenRouter, with a dedicated
unsloth provider id.
Unlike the three runtimes above, Unsloth Studio's OpenAI-compatible endpoint is not keyless — every request needs a real bearer token:
unsloth studio -p 8888
unsloth:
type: openai_compat
base_url: http://localhost:8888/v1
api_key: $UNSLOTH_API_KEY
models:
- id: gemma-4-26B-A4B-it-GGUF
role: general
- Port: Unsloth's API guide states it "exposes these endpoints on whichever port it booted
on (typically
http://localhost:8000orhttp://localhost:8888)" — genuinely ambiguous prose in the source docs — but every concrete example in that same guide (unsloth studio -p 8888, the/v1/modelscurl sample below) targets8888, so that's the default gald3r ships. Confirm against whichever port your own instance printed on launch if it differs. - Auth: generate a key in Studio's Settings → API (format
sk-unsloth-...), then export it asUNSLOTH_API_KEY(matches both gald3r's own<PROVIDER>_API_KEYconvention and the exact variable name Unsloth's own docs use). There is no keyless placeholder forunsloththe wayollama/lm-studiohave one — a missing key fails at call time with a real auth error, not silently. - Model listing:
GET /v1/modelswithAuthorization: Bearer sk-unsloth-...— per the API guide's own example:bash curl http://localhost:8888/v1/models \ -H "Authorization: Bearer sk-unsloth-xxxxxxxxxxxx"
unsloth start interop (agent CLIs, not providers.yaml)¶
Unsloth Studio ships its own wrapper, independent of gald3r's providers.yaml: from a project
folder, with a model loaded in Studio,
unsloth start claude # or: codex, opencode, hermes
launches that agent CLI directly, pointed at the local model via a temporary,
session-scoped provider configuration — per Unsloth's own integration guide, it does not touch
the CLI's normal config files at all. This is a separate entry point from the providers.yaml
block above:
| You want... | Use |
|---|---|
gald3r's own provider registry to reach a running Unsloth Studio endpoint (--model unsloth:<id>, providers.yaml's unsloth: block) |
The providers.yaml block above |
| Unsloth's own wrapper to launch an agent CLI (Claude Code, Codex, OpenCode, Hermes Agent) against a local model for you | unsloth start <agent> |
Both reach the same underlying local server — pick whichever fits how you're launching that
session. unsloth start is Unsloth's tooling, not a gald3r verb; run unsloth start --help (or
consult unsloth.ai/docs/integrations/unsloth-start)
for its own flags.
Verify: once real hardware access is available, this section should be re-captured against a live instance the same way the Ollama/LM Studio sections above were — flagged here rather than silently presented as verified.
Cloud providers¶
OpenRouter (worked example)¶
The starter file's openrouter: block (real capture, above) is the template:
openrouter:
type: openai_compat
base_url: https://openrouter.ai/api/v1
api_key: $OPENROUTER_API_KEY
models:
- id: anthropic/claude-sonnet-4-5
role: planning
- id: google/gemini-2.5-flash
role: general_cheap
- id: qwen/qwen2.5-coder-32b-instruct
role: coding_cloud
Get a key from openrouter.ai, then store it — prefer the keyring
over the $ENV_VAR the template ships with:
gald3r providers set-key openrouter
(prompts securely; see Keys: keyring vs. plaintext above for
the exact success/failure message shapes). --model openrouter:anthropic/claude-sonnet-4-5 (or
any other listed id) selects a specific model; bare openrouter uses the first one.
Generic OpenAI-compatible cloud pattern¶
Any hosted endpoint that speaks the OpenAI Chat Completions wire format — a proxy, a
self-hosted gateway, a provider not shown above — uses the exact same openai_compat shape:
my-custom-endpoint:
type: openai_compat
base_url: https://my-endpoint.example.com/v1
api_key: $MY_ENDPOINT_API_KEY
models:
- id: whatever-the-endpoint-calls-it
role: general
Every openai_compat entry requires base_url — omit it and you get a clear ProvidersYAMLError at load/build time rather than
a silent failure.
connect, and the two local-model verbs¶
gald3r connect¶
gald3r connect [PROVIDER]
connect drives a real device-code sign-in round-trip (request → poll → store token) against
world_tree, gald3r's optional hosted coordination service — this is the world_tree account
link itself; for a third-party AI provider's own API key, use gald3r providers add/set-key
instead. Real capture:
gald3r connect openai
gald3r connect openai: visit http://api.gald3r.ai/api/v1/auth/device/verify?user_code=CHMC-3D77 and enter code CHMC-3D77 (waiting up to 600s)...
gald3r connect openai: device code expired before authorization completed -- run `gald3r connect` again.
(Real — the run printed a genuine verification URL and one-time code, then polled for up to 600
seconds. Nothing visited that URL during this capture, so it expired unused — this page did not
go on to test what happens after a completed authorization.) If you get this far, follow the
printed URL and enter the code in any browser to finish linking the account; gald3r login
--token <token> remains the direct power-user/CI path if you'd rather skip the device-code flow
entirely (see troubleshooting.md for that page's own login capture —
worth a grain of salt given this page's fresher finding above). None of this is required for
local-only providers.yaml use — connect/login only matter once you're using
world_tree-backed, cross-machine features.
gald3r local-model assess¶
gald3r local-model assess --help
Recommend a local-model variant/quant for this (or manually-described) hardware
Flags:
--apple-chip string
--apple-silicon Host is macOS arm64
--auto Probe this host's real OS/CPU/RAM/GPU facts instead of the manual flags below. Wins over every manual hardware flag when both are given.
--cpu-cores int
--efficiency-cores int
--gpu-count int Number of discrete GPUs with --gpu-vram-gib VRAM each (multi-GPU rigs are assumed uniform)
--gpu-name string
--gpu-vendor string
--gpu-vram-gib float Largest single discrete GPU's VRAM in GiB (0 = no discrete GPU)
--os-name string
--perf-cores int
--ram-gib float
--unified-memory-gib float
assess is a decision table over hardware facts — pass --auto to have it probe this host's
real OS/CPU/RAM/GPU facts directly, or supply any of the manual flags yourself to assess a
different machine (a manual flag always wins over --auto when both are given, so you can
override just the one fact you want to test). Three real runs against different hardware
profiles:
gald3r local-model assess --ram-gib 32 --gpu-vram-gib 24 --gpu-name "NVIDIA GeForce RTX 4090" --gpu-vendor nvidia
tier: 24gb
recommended variant: ornith-35b-moe (Q4_K_M)
[24gb tier] Recommend serving Ornith-1.0 35B MoE (~3B active/token) at Q4_K_M (~21.2 GiB) on NVIDIA GeForce RTX 4090 (24.0 GiB VRAM). 24GB baseline (RTX 4090 / 3090) — the validated default: 35B MoE Q4_K_M (~21 GiB) fits with room for context. Routine/bulk agent calls run locally at $0/token; reserve cloud models for hard tasks. Run 'gald3r local-model --serve-cmd' for the exact serve command.
gald3r local-model assess --ram-gib 16
tier: floor
recommended variant: ornith-floor (Q4_K_M)
No discrete GPU detected (CPU-only / integrated graphics) — FLOOR tier. Recommend the tiny SmolLM2 1.7B (tiny floor — routing/classification only) for cheap LOCAL routing / classification / autocomplete ONLY; it is NOT a coding model. Ornith 9B Q4 will run on CPU but slowly. Steer real coding to the CLOUD (reserve cloud for anything non-trivial). Run 'gald3r local-model --serve-cmd' for the floor + cloud guidance.
gald3r local-model assess --apple-silicon --apple-chip "Apple M4 Max" --unified-memory-gib 64
tier: apple_unified
recommended variant: ornith-35b-moe (Q8_0)
Apple M4 Max with 64 GiB UNIFIED memory — Apple-Silicon path (GPU shares system RAM, so the budget is far larger than a discrete card of the same price). Recommend serving Ornith-1.0 35B MoE (~3B active/token) at Q8_0 — runtime: PRIMARY is Ollama 0.19+ (MLX, ~2x faster) — its engine is MLX-backed automatically on Apple Silicon (no flag) on this 32 GiB+ Mac; mlx_lm.server is the fallback (Ollama-MLX-unsupported models). 64GB+ unified (M Max) — 35B MoE at higher precision with headroom for long context. Run 'gald3r local-model --serve-cmd' for the exact Mac serve command.
(All three real — the Apple-Silicon run works on any host since the hardware facts are supplied as flags, not detected; nothing above requires actually owning that hardware.) The recommendation is about Ornith, gald3r's own model family, sized to what your hardware can actually run — the "floor" tier explicitly steers real coding work to the cloud rather than pretending a 1.7B model can do it.
gald3r local-model serve¶
gald3r local-model serve --help
Print the copy-pasteable serve command(s) for a recommended variant
Flags:
--apple-silicon
--tensor-parallel-size int
--unified-memory-gib float
--variant string one of: cloud_only, ornith-31b, ornith-35b-moe, ornith-397b-moe, ornith-9b, ornith-floor
Feed it the recommended variant from assess's output:
gald3r local-model serve --variant ornith-35b-moe
variant: ornith-35b-moe
served_model_id: ornith-1.0-35b-moe
vLLM (primary): vllm serve ornith/Ornith-1.0-35B-MoE --served-model-name ornith-1.0-35b-moe --quantization gguf --max-model-len 16384 --gpu-memory-utilization 0.92 --port 8000 --enable-auto-tool-choice --tool-call-parser hermes
Ollama pull: ollama pull ornith-1.0:35b-moe-q4_K_M
Ollama run: ollama run ornith-1.0:35b-moe-q4_K_M
notes: Q4_K_M. 35B MoE Q4_K_M is ~21.2 GiB — fits a 24GB card 'barely' at 8-16K context. If you hit OOM, lower --max-model-len or --gpu-memory-utilization, or use Q5_K_M with ~1-2 layers offloaded to RAM. On multi-GPU (e.g. 2×24GB) tensor-parallel removes the fit pressure and allows higher precision.
Same variant, Apple-Silicon flags added:
gald3r local-model serve --variant ornith-35b-moe --apple-silicon --unified-memory-gib 64
variant: ornith-35b-moe
served_model_id: ornith-1.0-35b-moe
vLLM (primary): vllm serve ornith/Ornith-1.0-35B-MoE --served-model-name ornith-1.0-35b-moe --quantization gguf --max-model-len 16384 --gpu-memory-utilization 0.92 --port 8000 --enable-auto-tool-choice --tool-call-parser hermes
Ollama pull: ollama pull ornith-1.0:35b-moe-q4_K_M
Ollama run: ollama run ornith-1.0:35b-moe-q4_K_M
MLX (Apple): mlx_lm.server --model mlx-community/Ornith-1.0-35B-MoE-4bit --port 8080 --host 127.0.0.1
notes: Q4_K_M. 35B MoE Q4_K_M is ~21.2 GiB — fits a 24GB card 'barely' at 8-16K context. ... Apple Silicon (>= 32 GiB unified): PRIMARY is Ollama 0.19+ ('ollama run ornith-1.0:35b-moe-q4_K_M') — its engine is MLX-backed AUTOMATICALLY on Apple Silicon (no flag), ~2x faster than the old llama.cpp/Metal path. ... FALLBACK (< 32 GiB unified, or models Ollama-MLX can't serve yet): 'mlx_lm.server --model mlx-community/Ornith-1.0-35B-MoE-4bit --port 8080'.
It only ever prints commands — it never auto-installs a runtime or auto-pulls a model for
you; you still run the printed command yourself. Neither local-model verb reads or writes
providers.yaml; pair a locally-served Ornith model with a providers.yaml block the same way
the Ollama/LM Studio/vLLM/llama.cpp recipes above show, once it's actually running.
Troubleshooting¶
Every message below is a real [error] a real gald3r run prints, captured against a scratch
providers.yaml built specifically to trigger each failure — except the last, marked
illustrative.
Missing key (a configured provider with no usable credential)¶
gald3r run "hi" --model anthropic
[error] Could not resolve provider: No configuration found for provider 'anthropic'. Set API key in <home>\providers.yaml or as an environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY).
(Real — captured with an anthropic: block present in providers.yaml but with no api_key
field, no $ANTHROPIC_API_KEY set, and no keyring entry stored.) Fix: gald3r providers set-key
anthropic, a $ANTHROPIC_API_KEY environment variable, or a literal api_key: in the file.
Backend down / wrong base_url¶
gald3r run "hi" --model deadlocal
[error] Connection error.
(Real — captured with a deadlocal: provider whose base_url pointed at
http://localhost:19999/v1, a port nothing was listening on.) This is the same message shape
for both "the backend process isn't running" and "the base_url is simply wrong" — from
gald3r's side they look identical (a failed TCP connection), so the fix is the same either way:
confirm the backend is actually running (curl <base_url>/models, or just start it) and that
base_url matches the port it's actually listening on.
Provider id not in providers.yaml at all¶
gald3r run "hi" --model totallyfake
[error] Could not resolve provider: No configuration found for provider 'totallyfake'. Set API key in <home>\providers.yaml or as an environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY).
(Real — captured with no totallyfake: block anywhere in the file.) Note this is the same
message text as the missing-key case above — today, gald3r's error path doesn't distinguish
"this provider id doesn't exist in the file" from "this provider exists but has a config
problem." If you see this and you're sure the provider IS in your providers.yaml, double-check
its type/api_key/base_url fields rather than assuming the id itself is wrong — this is a
known rough edge in the error message, not a sign your setup is broken.
Model-name mismatch (illustrative)¶
Not independently reproducible offline — a genuine model-name-mismatch response comes from
the real backend's own API (e.g. Ollama/LM Studio returning an HTTP 404 for an unrecognized
model id), and no local backend was available to capture this against while writing this page.
The verified behavior instead: model resolution does not reject an unknown
model id up front — a name that isn't in a provider's models: list is passed through as-is
"as the user may have a brand-new local model," and the actual endpoint is left to return
whatever error it returns for an unrecognized model (typically an HTTP 404 from an
OpenAI-compatible server). If a run fails this way, the fix is to check the model id/alias
against what the backend itself reports as loaded (ollama list, LM Studio's UI, or the
endpoint's own /models route) rather than trust providers.yaml's list, since that list is
not authoritative over what the backend actually has loaded.
Where next¶
concepts.md— the one-paragraph version of all this, if you just need the summaryverbs.md— every provider-related verb in the full command mapinstall.md— getgald3ritself installed before any of this matterstroubleshooting.md—doctor'sprovidersline, and the general real-output-driven troubleshooting flow this page's Troubleshooting section follows
Managing providers.yaml from the CLI¶
Every command below was actually run against a scratch providers.yaml while writing this
page. Output is trimmed for length but not altered in substance.
Why this exists¶
Hand-editing providers.yaml directly works, but has no validation and no
feedback until something breaks at call time. gald3r providers adds a small
verb family that makes hand-editing optional: list what's configured, add/
remove/edit providers and their models, assign role routing, and validate the
whole file (schema, key presence, reachability) before you find out the hard
way.
Every edit verb is round-trip safe: it preserves comments and the ordering of every block it doesn't touch, rather than a plain load-then-dump that would silently drop every comment in the file.
gald3r providers list¶
At-a-glance table: provider, type, base URL, key status, model count, and which roles are covered.
gald3r providers list
providers.yaml: C:\Users\you\.gald3r\providers.yaml
provider type base_url key models roles
---------- ------------- ---------------------------- --------- ------ ------------------------------------------------
anthropic anthropic - env:unset 3 general_cheap, planning, planning_heavy
lmstudio openai_compat http://localhost:1234/v1 local 7 coding, coding_heavy, reasoning
ollama openai_compat http://localhost:11434/v1 local 7 coding, coding_heavy, general, reasoning, vision
openai openai_compat https://api.openai.com/v1 env:unset 2 general, general_cheap
openrouter openai_compat https://openrouter.ai/api/v1 env:unset 3 coding_cloud, general_cheap, planning
sakana openai_compat https://api.sakana.ai/v1 env:unset 2 general, planning_heavy
The key column is a classification, never the actual secret:
| Value | Meaning |
|---|---|
keyring |
Resolved from the OS keyring (gald3r providers set-key) — takes precedence over anything in the file |
env:set |
api_key is a $ENV_VAR reference and that variable is currently set |
env:unset |
api_key is a $ENV_VAR reference, but that variable is not set right now |
local |
A known keyless placeholder (ollama/lm-studio/local) — expected for local runtimes, not a real secret |
plaintext |
A literal secret sitting in the file — works, but consider gald3r providers set-key instead |
missing |
No key resolvable anywhere |
gald3r providers add¶
gald3r providers add together --base-url https://api.together.xyz/v1 --model meta-llama/Llama-3.3-70B
Added provider 'together' to C:\Users\you\.gald3r\providers.yaml.
If no providers.yaml exists yet, add creates one from scratch (you don't
have to run gald3r init-providers first).
Flags: --base-url URL, --type {openai_compat,anthropic} (default
openai_compat), --model MODEL_ID (repeatable — adds bare model entries;
use providers model add afterward to attach a role/alias/context window),
--api-key $ENV_VAR_OR_PLACEHOLDER — a real-looking secret literal is refused (keys never go in the file in plaintext; use gald3r providers set-key for the OS keyring, a $ENV_VAR reference, or the local placeholders ollama/lm-studio/local) (prefer gald3r providers set-key to keep real
secrets out of the file), --force (replace if the provider already exists).
gald3r providers remove¶
gald3r providers remove together --yes
Removed provider 'together' from C:\Users\you\.gald3r\providers.yaml.
--yes is required — this CLI never blocks on an interactive confirmation
prompt (same convention as gald3r profile reset). Omitting it refuses with a
clear message and makes no change.
If the provider you're removing sits immediately before a comment that documents a different provider, you'll see an extra warning first — the YAML round-trip editor attaches a "between blocks" comment to the end of the preceding block, not the "before" position of the one it visually describes, so removing the preceding provider can take an unrelated provider's documentation with it. The warning tells you before it happens so you can check the file afterward if that comment mattered.
gald3r providers set¶
Targeted field edits — no need to touch anything else in the block.
gald3r providers set ollama base_url=http://localhost:22222/v1
Updated 1 field(s) on provider 'ollama' in C:\Users\you\.gald3r\providers.yaml.
Multiple KEY=VALUE pairs in one call are fine. Values are type-coerced the
way you'd expect: true/false become real YAML booleans, integers and
floats parse as numbers, everything else stays a string.
gald3r providers model add / gald3r providers model remove¶
gald3r providers model add ollama gemma3:27b --role vision --context-window 32768
Added model 'gemma3:27b' to provider 'ollama' in C:\Users\you\.gald3r\providers.yaml.
gald3r providers model remove ollama gemma3:27b
Removed model 'gemma3:27b' from provider 'ollama' in C:\Users\you\.gald3r\providers.yaml.
model remove matches by either id or alias. --role is a single value
(not a list) — the on-disk schema carries exactly one role: per model
entry; a model that serves more than one purpose is expected to appear as
more than one entry, or you just re-run providers role set to reassign it.
gald3r providers role set¶
gald3r providers role set vision ollama/qwen3:4b
Set role 'vision' for ollama/qwen3:4b in C:\Users\you\.gald3r\providers.yaml.
The spec is PROVIDER/MODEL, split on the first / only — this matters
because LM Studio model ids are themselves filesystem-style paths containing
/ (e.g. lmstudio/Qwen2.5-Coder-14B-Instruct-GGUF/Qwen2.5-Coder-14B-Instruct-Q4_K_M.gguf),
so a naive last-/ split would cut the model id in half.
gald3r providers validate¶
Schema check, key-presence check, and (unless --no-network) a
reachability probe against {base_url}/models for every OpenAI-compatible
provider.
gald3r providers validate --no-network
[OK ] lmstudio
ok: API key resolved via local
skip: reachability probe disabled (--no-network)
[OK ] ollama
ok: API key resolved via local
skip: reachability probe disabled (--no-network)
[WARN] openrouter
warn: api_key references an unset environment variable
skip: reachability probe disabled (--no-network)
6 provider(s): 2 ok, 4 warn, 0 fail.
Exit code is 1 only if any provider has a fail-level finding (a real
schema defect, or no usable key at all for a provider type that requires
one). An unreachable local runtime, an unset env var, or a plaintext key are
all warnings — informational, not blocking (the runtime may simply not be
started right now).
Every network probe is hard-capped at 3 seconds regardless of what
--timeout you pass, and --no-network skips reachability checks entirely —
validate never hangs waiting on a dead endpoint.
Keys still never leave the keyring path¶
None of these verbs change how secrets are stored: gald3r providers set-key
remains the only way to put a real key in the OS keyring, and nothing here
ever prints, logs, or writes a literal secret value — only classification
labels like the key column above.
Can I edit providers.yaml while gald3r is already running?¶
Short answer: usually yes, already, with no extra step.
providers.yamlis re-read from disk on every single call that resolves a provider — there is no cache anywhere in the loader. A background autopilot loop or the ACP server's default provider factory both build a fresh registry per call, so an edit (via these verbs or by hand) is visible on the very next call, no restart needed.- The one exception is an already-open
gald3r chatREPL: it resolves its provider once per session and reuses that client for every turn until you run/model <spec>or start a new session. If you editproviders.yamlwhile a chat session is open, run/model(or restart) to pick up the change in that session.
See also¶
quickstart.md—gald3r init-providersand the starterproviders.yamlthis addendum assumes you already haveverbs.md— the full verb cataloggald3r providers --help/gald3r providers <subcommand> --help— always the authoritative source for exact flags