Skip to content

Edit configuration

hal0’s configuration lives as plain TOML (plus one env file) under /etc/hal0. The directory is preserved across updates — the updater only swaps code, never your config. The hal0 config CLI is a thin layer over the same files and the running daemon.

FileWhat it holds
hal0.tomlTop-level config: [meta] schema_version, [slots] (port range, idle_timeout_s, evict_pressure_mb, publish_host), [dispatcher] prefetch tuning, [models] roots/store, [memory] engine + [memory.graph] extraction, [activity] audit-log retention, [telemetry] channel.
api.envEnvironment for the hal0-api service (systemd EnvironmentFile) — provider secrets plus env knobs like HAL0_MODEL_STORE, HAL0_MCP_ALLOWED_HOSTS, and the HAL0_*_PUBLIC_URL reverse-proxy overrides.
upstreams.tomlExternal / upstream provider routing.
providers.tomlProvider credential references (key names, never plaintext secrets).
profiles.tomlOptional custom profile catalogue. The built-in seed profiles (rocm, rocm-moe, vulkan, cuda, embed, rerank, flm, tts, tts-qwen3, cpu-llm, comfyui, …) are always overlaid from code on load and are never written back here, even if the file exists.
capabilities.tomlPersisted capability selections (embed / voice / img / vision). Carries its own schema_version.
slots/<name>.tomlOne file per slot — name, port, device (gpu-rocm|gpu-vulkan|gpu-cuda|cpu|npu), gpu_index (multi-GPU pinning), profile, mtp (tri-state Auto/on/off), vision (mmproj toggle), the TTS request-default trio (default_voice/default_speed/default_response_format), plus nested [model], [server], [npu] (asr/embed), and — on the img slot only — [image].

Other files the runtime drops here: hardware.json (cached hardware probe), manifest.json (release image pins), openwebui.env.

Terminal window
hal0 config show

Prints hal0.toml as it is on disk. If the file is root-owned and you run as a non-root user, the command tells you to re-run with sudo (or to chmod the config tree once) instead of crashing.

Terminal window
hal0 config edit

Opens hal0.toml in $EDITOR (falling back to $VISUAL, then vi). If the file doesn’t exist yet, it’s created with a valid skeleton ([meta] schema_version, [slots] port range).

Terminal window
hal0 config validate

Loads and validates hal0.toml, upstreams.toml, and providers.toml against the current Pydantic schema. It prints each problem and exits non-zero on any failure, or ✓ All configs pass schema validation. when clean.

After editing, ask the live daemon to re-read its TOMLs without a full restart:

Terminal window
hal0 config reload

This hits POST /api/settings/reload on the local API. If the daemon is down, the command exits non-zero — start hal0-api first.

Settings page showing live reload status Settings page with live daemon status and reload controls.

The dashboard’s Settings → Storage section also has its own Reload from disk button next to the hal0.toml path, which hits this same POST /api/settings/reload — use it after an out-of-band edit with hal0 config edit.

Beyond the files and CLI above, the dashboard’s Settings view covers most of the same ground with a few operator conveniences. Sections, in nav order: Secrets, Storage, Updates, Voice, Image-gen, NPU, Default slots, General, Advanced, About.

  • Secrets — provider API key presets (Hugging Face, OpenAI, Anthropic, Google, Groq) plus two paired AWS Bedrock presets (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, cross-referenced in the picker so you’re reminded to set both), or a custom key name.
  • Voice — STT enable + model, and the TTS request-default trio for the serving tts slot: Default voice (populated from the live voice list where available), Default speed (0.254.0), and Default format (mp3/wav/opus/flac/pcm). These persist to the same [slot] keys as slots/<name>.toml and are applied to the next /v1/audio/speech request with no restart — see Voice (STT/TTS).
  • Image-gendefault_size, default_steps, and idle_restore_minutes for the img/ComfyUI slot’s [image] table. idle_restore_minutes (how long ComfyUI can sit idle before the GPU arbiter restores LLM slots) is hot-reloadable — it takes effect on Save with no hal0-api restart.
  • NPU — for FastFlowLM (FLM) slots: Context size (--ctx-len), Load embeddings, and Load ASR (all require restarting the slot), plus a read-only Occupancy panel (TOPS, tile usage, per-slot breakdown) when an NPU is present.
  • Advanced — schema-driven controls for every [slots], [dispatcher], [memory], and [activity] key that previously required hal0 config edit (including slots.evict_pressure_mb, the pressure-eviction floor; the memory.engine picker only offers hindsight/pgvector even though the schema also accepts cognee/mem0, since those two are silently remapped to hindsight), plus a dedicated memory graph panel for [memory.graph] (extraction_slot, llm_timeout_s) and a Restart hal0-api button — a one-click restart-and-health-poll for hal0-api.service, handy after any change flagged “restart required”.
  • General — the Anonymous telemetry opt-in toggle for [telemetry] enabled (off by default; see Configuration schema reference).

When you update hal0 across a schema bump, bring hal0.toml to the latest version:

Terminal window
hal0 config migrate

It reads meta.schema_version, runs the registered migration chain, and atomically writes the result back only if the version actually advanced. If the config is already current (or absent), nothing is written and that is reported honestly.

Every config write hal0 performs — config migrate, the settings API, the updater’s hal0.previous record — uses a tempfile + os.replace pattern so a write is either fully applied or not at all; an interrupted write never leaves a half-written, unparseable file in place.