Empryoempryo.beta
providers

Custom providers

Connect any OpenAI-compatible API to Empryo with one config block: set baseURL, key env var, models, dynamic model lists, and reasoning options.

Add any OpenAI-compatible API as a provider. No code, no plugin.

Minimal example

Add this to ~/.empryo/config.json (or .empryo/config.json for project scope):

{
  "providers": [
    {
      "id": "together",
      "name": "Together AI",
      "baseURL": "https://api.together.xyz/v1",
      "envVar": "TOGETHER_API_KEY",
      "models": ["meta-llama/Llama-3-70b-chat-hf"]
    }
  ]
}

Set the key and use it:

empryo --set-key together <your-key>
empryo --model together/meta-llama/Llama-3-70b-chat-hf

Fields

FieldRequiredWhat it does
idyesUsed in model strings (together/llama-3)
baseURLyesOpenAI-compatible endpoint
name-Display name
envVar-Env var for the key (omit for auth-less servers)
models-Fallback model list (strings or {id, name, contextWindow})
modelsAPI-URL returning OpenAI /v1/models format
reasoning-Thinking/reasoning config (see below)

More examples

Thinking / reasoning

For models that support reasoning over an OpenAI-compatible endpoint, add a reasoning block. Three styles are supported - use the one your provider accepts:

{
  "providers": [{
    "id": "dashscope",
    "baseURL": "https://dashscope.aliyuncs.com/compatible-mode/v1",
    "envVar": "DASHSCOPE_API_KEY",
    "models": ["qwen-plus"],
    "reasoning": {
      "enabled": true,
      "budget": 8192
    }
  }]
}
StyleFieldsWhen to use
OpenAI-style`effort: "low" \"medium" \"high" \"xhigh" \"none"`OpenAI-compatible reasoning models
DashScope-styleenabled: true, budget: 8192Alibaba Qwen, DashScope APIs
RawextraParams: { ... }Anything else - fields are forwarded verbatim

The fields are injected into every request body. Raw extraParams override all other keys on collision.

How effort is sent

By default effort goes out as the flat OpenAI field, { "reasoning_effort": "high" } — the field every OpenAI-compatible endpoint speaks. If your backend instead wants the nested OpenRouter shape, set effortStyle:

{
  "reasoning": {
    "effort": "high",
    "effortStyle": "nested"
  }
}
effortStyleSends
"flat" *(default)*{ "reasoning_effort": "high" }
"nested"{ "reasoning": { "effort": "high" } }
"both"both keys at once

Only reach for "both" if a router genuinely needs it. Strictly-validating backends reject a request carrying both keys outright — *"Pass either reasoning (nested object) or reasoning_effort (flat field), not both."*

Scope

  • Global - ~/.empryo/config.json applies everywhere.
  • Project - .empryo/config.json overrides global entries with the same id.

Conflicts

If your id matches a built-in (e.g. "anthropic"), Empryo renames it to {id}-custom - the built-in is never replaced. Custom providers always show [custom] in /keys and --list-providers.