Skip to content

reference

Provider catalogue (`providers.json`, `cost-defaults.json`, `voice.toml`)

/etc/deputyos/providers.json is the **bake-time catalogue of model providers** the wizard offers. Each entry is everything the runtime needs to test a key, render a help string, look up an env var, and present pricing.

/etc/deputyos/providers.json is the bake-time catalogue of model providers the wizard offers. Each entry is everything the runtime needs to test a key, render a help string, look up an env var, and present pricing.

This page also covers the two related runtime config files: /etc/deputyos/cost-defaults.json (per-provider USD rate sheet used by the cost ledger when the per-message provider response omits cost) and /etc/deputyos/voice.toml (voice-relay runtime config).

The Rust struct is in deputyctl/src/model.rs; the catalogue source is deputyctl/etc/providers.json.

[TOC]

providers.json — schema

struct ProvidersFile { providers: Vec<Provider> }

struct Provider {
    id: String,                   // stable identifier, kebab-case
    display_name: String,         // human-readable
    kind: String,                 // dispatch tag for the test path
    endpoint_default: String,     // canonical base URL (may be empty)
    key_env_var: String,          // env var name in /etc/deputyos/secrets.env
    key_format: String,           // hint string shown in the wizard
    default_model: String,        // optional, default ""
    supported_models_hint: String,// optional, default ""
}
FieldTypeRequiredDescription
idstringyesStable provider id, kebab-case (e.g. openrouter, anthropic, google-ai-studio). Used by deputyctl model set --provider <id> and the wizard <select>.
display_namestringyesHuman-readable name shown in the wizard and PWA.
kindstringyesDispatch tag for the test path. One of: openai-compatible, openai, anthropic, google, bedrock, huggingface.
endpoint_defaultstringyesCanonical base URL. May be empty for self-hosted (Custom OpenAI-compatible).
key_env_varstringyesName of the KEY=VALUE line written into /etc/deputyos/secrets.env.
key_formatstringyesHint shown next to the input box (e.g. sk-or-v1-..., AIza..., (URL only; no key required)).
default_modelstringoptionalSuggested default model id. May be empty for providers requiring per-call selection.
supported_models_hintstringoptionalFree-form hint surfaced in the wizard.

Resolution order

deputyctl/src/paths.rs::providers_file():

  1. $DEPUTYOS_PROVIDERS_FILE env var if set.
  2. /etc/deputyos/providers.json if it exists.
  3. deputyctl/etc/providers.json (dev fallback).

kind enum values

KindTest pathNotes
openai-compatibleGET <endpoint>/models with Authorization: Bearer <key>.The bulk of providers — anything that speaks the OpenAI Chat Completions API on /v1/....
openaiSame as above, against api.openai.com.Distinguished only for cost-defaults bookkeeping.
anthropicGET <endpoint>/v1/models with x-api-key: <key> and anthropic-version header.
googleGET <endpoint>/models?key=<key>.Google AI Studio and equivalents.
bedrockAWS SigV4 hand-shake against <endpoint>. Requires AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION.The wizard detects all three before validating.
huggingfaceGET <endpoint>/models with bearer token.The wizard requires a model id.

The wizard’s “Skip validation” checkbox bypasses the round-trip and trusts the user. deputyctl model test runs the same path post-apply.

All 15 transcribed providers

Rendered from deputyctl/etc/providers.json — the source of truth. Some columns trimmed for fit; full detail lives in the JSON file.

iddisplay_namekindendpoint_defaultkey_env_varkey_format hintdefault_model
openrouterOpenRouteropenai-compatiblehttps://openrouter.ai/api/v1OPENROUTER_API_KEYsk-or-v1-...anthropic/claude-sonnet-4.6
anthropicAnthropicanthropichttps://api.anthropic.comANTHROPIC_API_KEYsk-ant-...claude-sonnet-4-6
openaiOpenAIopenaihttps://api.openai.com/v1OPENAI_API_KEYsk-...gpt-4o
google-ai-studioGoogle AI Studiogooglehttps://generativelanguage.googleapis.com/v1betaGOOGLE_AI_STUDIO_API_KEYAIza...gemini-2.0-flash
bedrockAWS Bedrockbedrockhttps://bedrock-runtime.us-east-1.amazonaws.comAWS_ACCESS_KEY_IDAKIA... (+ secret + region)anthropic.claude-sonnet-4-6
nous-portalNous Portalopenai-compatiblehttps://inference-api.nousresearch.com/v1NOUS_PORTAL_API_KEYsk-nous-...Hermes-3-Llama-3.1-405B
nvidia-nimNVIDIA NIMopenai-compatiblehttps://integrate.api.nvidia.com/v1NVIDIA_NIM_API_KEYnvapi-...nemotron-4-340b-instruct
ollama-cloudOllama Cloudopenai-compatiblehttps://api.ollama.com/v1OLLAMA_CLOUD_API_KEYollama-...llama-3.3-70b
local-ollamaLocal Ollamaopenai-compatiblehttp://127.0.0.1:11434/v1LOCAL_OLLAMA_BASE_URLURL only; no key requiredllama3.2:3b
zai-glmz.ai / GLMopenai-compatiblehttps://api.z.ai/api/paas/v4ZAI_API_KEY(z.ai key)glm-4.6
kimi-moonshotKimi / Moonshotopenai-compatiblehttps://api.moonshot.cn/v1MOONSHOT_API_KEYsk-...moonshot-v1-128k
minimaxMiniMaxopenai-compatiblehttps://api.minimaxi.com/v1MINIMAX_API_KEY(MiniMax key)abab6.5s-chat
xiaomi-mimoXiaomi MiMoopenai-compatiblehttps://api.mimo.xiaomi.com/v1XIAOMI_MIMO_API_KEY(Xiaomi key)mimo-7b-rl
huggingfaceHugging Face Inferencehuggingfacehttps://api-inference.huggingface.coHUGGINGFACE_API_KEYhf_...(model required)
customCustom OpenAI-compatibleopenai-compatible(empty)CUSTOM_OPENAI_API_KEYmay be empty(user-set)

local-ollama is offered only on offline-build images that bake in a model — the wizard hides it on online-build images so users don’t pick a provider that won’t work.

The key_env_var contract

When the wizard finishes, deputyctl model set writes /etc/deputyos/secrets.env (mode 0600, owned by root:agent so the gateway services that EnvironmentFile=-/etc/deputyos/secrets.env can read it). The line is exactly <key_env_var>=<value> — no quoting, no comments. deputyctl model list parses it back via model::load_secrets_from, which tolerates lines without =, #-comments, and one optional layer of surrounding " or '.

See Security / Secrets storage for the file mode, ownership, and factory-reset behaviour.

cost-defaults.json — per-provider rate sheet

/etc/deputyos/cost-defaults.json is the bootstrap rate sheet the cost ledger uses when a provider’s per-message response omits cost_usd. It is not authoritative — the per-message ledger writeback is — and is updated during routine release prep against each provider’s public pricing page.

Schema

{
  "providers": {
    "<provider-id>": {
      "default_model": "<id>",
      "input_per_1m_usd":  <number>,
      "output_per_1m_usd": <number>
    }
  }
}

Full file

{
  "_comment": "Default per-1M-token rates per provider (USD). Sourced from each provider's public pricing as of 2026-04-27. NOT authoritative — used only as a sane bootstrap when the agent profile's ledger entry omits cost_usd. Update during routine release prep; the per-message ledger writeback is the source of truth.",
  "providers": {
    "openrouter": {
      "default_model": "anthropic/claude-sonnet-4-6",
      "input_per_1m_usd": 3.00,
      "output_per_1m_usd": 15.00
    },
    "anthropic": {
      "default_model": "claude-sonnet-4-6",
      "input_per_1m_usd": 3.00,
      "output_per_1m_usd": 15.00
    },
    "openai": {
      "default_model": "gpt-4o",
      "input_per_1m_usd": 2.50,
      "output_per_1m_usd": 10.00
    },
    "google-ai-studio": {
      "default_model": "gemini-2.0-flash",
      "input_per_1m_usd": 0.10,
      "output_per_1m_usd": 0.40
    },
    "mistral": {
      "default_model": "mistral-large-latest",
      "input_per_1m_usd": 2.00,
      "output_per_1m_usd": 6.00
    }
  }
}

Providers absent from cost-defaults.json default to zero cost; the ledger marks those messages as cost_unknown=true so the daily report doesn’t silently understate spend.

See Operations / Cost guardrails for the ledger and budget-threshold semantics.

voice.toml — voice-relay runtime config

/etc/deputyos/voice.toml is the runtime source of truth for the deputyOS voice relay (whisper.cpp + Piper bridge). It is rendered from roles/deputyos/templates/voice.toml.j2 at bake time and lives under /etc/deputyos/voice.toml. Voice config does not live in the profile manifest — the manifest surface is frozen, and voice arrived later.

The systemd unit deputyos-voice-relay.service refuses to start until both /etc/deputyos/voice.toml exists and enabled = true.

Schema

SectionFieldTypeDescription
[voice]enabledboolMaster switch. Wizard / PWA voice card flips this to true after consent + mic check.
[voice]wake_wordstringCase-insensitive substring match against the first token of each whisper transcription.
[voice]stt_modelstringOne of whisper-tiny.en, whisper-base.en, whisper-small.en.
[voice]tts_voicestringPiper voice id (e.g. en_US-amy-medium).
[voice]audio_devicestringALSA device. default routes through the user’s default soundcard; plughw:1,0 etc. for explicit cards.
[stt]model_pathstringAbsolute path to the whisper model .bin.
[stt]binarystringAbsolute path to whisper-cli.
[tts]model_pathstringAbsolute path to the Piper .onnx.
[tts]binarystringAbsolute path to piper.
[relay]socket_pathstringWhere to talk to the message-relay socket. Default /run/deputyos/relay.sock.
[relay]hook_kindstringThe HookKind to fire — convention is pre-message.
[relay]source_tagstringPayload source field — convention is voice.

Sizing per device class

Per roles/deputyos/templates/voice.toml.j2:

  • rpi5 8GB: whisper-tiny.en (default).
  • rpi5 16GB: whisper-base.en.
  • x86_64-mini-pc: whisper-small.en.

Pi 4, qemu-aarch64, and all cloud targets disable voice entirely — see the corresponding limits.json entries.

Example rendered file

[voice]
enabled      = true
wake_word    = "agent"
stt_model    = "whisper-tiny.en"
tts_voice    = "en_US-amy-medium"
audio_device = "default"

[stt]
model_path = "/opt/deputyos/voice/whisper-tiny.en.bin"
binary     = "/opt/deputyos/voice/whisper-cli"

[tts]
model_path = "/opt/deputyos/voice/piper/en_US-amy-medium.onnx"
binary     = "/opt/deputyos/voice/piper"

[relay]
socket_path = "/run/deputyos/relay.sock"
hook_kind   = "pre-message"
source_tag  = "voice"

See also

Search

Search index isn't built yet. Run npm run build to generate it (Pagefind writes to dist/pagefind/).