Build

Providers and models

Provider components, credentials, models.json for custom gateways, and model selection.

Providers are WASM components like any other extension, distinguished by exporting the provider interface. Core dispatches each request by the model's api field to the component that declares it. Seven components cover the common ground:

Component API Providers
oino.anthropic anthropic-messages anthropic (API key or Claude Pro/Max OAuth), minimax, minimax-cn
oino.openai-responses openai-responses openai, xai, meta
oino.openai-compat openai-completions openrouter, groq, deepseek, together, fireworks, cerebras, huggingface, nvidia, moonshotai, kimi-coding, qwen-token-plan*, xiaomi*, zai, opencode, baseten, ant-ling, vercel-ai-gateway, ollama, lmstudio, mistral, deepinfra, chutes, perplexity
oino.openai-codex openai-codex-responses openai-codex (ChatGPT sign-in)
oino.google google-generative-ai, google-vertex google, google-vertex
oino.azure azure-openai-responses azure
oino.bedrock bedrock-converse-stream amazon-bedrock

A provider may list models that use another wire (a gateway's Claude models, for instance): dispatch is per model, not per provider.

Credentials#

Resolution order, per provider:

  1. --api-key <key> (with --model), for one run;
  2. ~/.oino/auth.json;
  3. the provider's environment variables.

auth.json is written with mode 0600:

json
{
  "anthropic": { "type": "api_key", "key": "sk-ant-..." },
  "openrouter": { "type": "api_key", "key": "sk-or-..." }
}

Common environment variables: ANTHROPIC_API_KEY (also ANTHROPIC_AUTH_TOKEN, ANTHROPIC_OAUTH_TOKEN), OPENAI_API_KEY, XAI_API_KEY, META_API_KEY, OPENROUTER_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY, MINIMAX_API_KEY, ZAI_API_KEY, MOONSHOT_API_KEY, HF_TOKEN, AI_GATEWAY_API_KEY; most others follow <NAME>_API_KEY. Ollama and LM Studio are local servers (localhost:11434, localhost:1234) and need no key. /login [provider] in the TUI runs an OAuth flow (Anthropic Claude Pro/Max, GitHub Copilot, OpenAI Codex, OpenAI Sign in with ChatGPT) and stores the credential in auth.json; /logout clears it.

oino --list-models [search] lists every model you have credentials for. Providers marked models: "dynamic" (Ollama, LM Studio, Mistral, DeepInfra, Chutes, Perplexity) list their models at startup; --offline or OINO_OFFLINE=1 skips that.

models.json#

~/.oino/models.json adds providers and models or overrides built-in ones:

json
{
  "providers": {
    "my-gateway": {
      "baseUrl": "https://llm.example.com/v1",
      "api": "openai-completions",
      "apiKey": "MY_GATEWAY_KEY",
      "authHeader": true,
      "models": [
        {
          "id": "qwen3-coder",
          "name": "Qwen3 Coder",
          "contextWindow": 262144,
          "maxTokens": 32768,
          "reasoning": true,
          "input": ["text"],
          "cost": { "input": 0.3, "output": 1.2 }
        }
      ]
    },
    "openrouter": { "baseUrl": "https://my-proxy.example.com/api/v1" }
  }
}
  • api must be implemented by a loaded component: openai-completions, openai-responses, anthropic-messages, openai-codex-responses, google-generative-ai, azure-openai-responses or bedrock-converse-stream.
  • apiKey is a literal, an environment variable name, or !command to read it from a command.
  • authHeader: true sends Authorization: Bearer <key>.
  • An entry with only baseUrl/headers/models patches an existing provider.

Choosing models#

--model accepts provider/id, a bare id, or a fuzzy pattern, with an optional :thinking suffix (--model sonnet:high). --models a,b,c (globs work, ctrl+p cycles) scopes the session. Without flags, defaultProvider/defaultModel from settings apply, then the first available model. Thinking levels: off, minimal, low, medium, high, xhigh, max, clamped to what the model supports.

Virtual models#

Extensions can register virtual models and route each request per call (route-model in the WIT world); the footer shows the routed model next to the selected one. This is how model-fusion style setups (a cheap model drafting under a strong model's supervision) are built without touching core.

Writing a provider#

A provider is a component exporting stream, list-models and optional OAuth flows. Build it with the provider feature of oino-extension; oino-provider-kit in extensions/sdk/ implements the wire protocols so a new gateway is mostly a manifest and a base URL. The shipping providers under extensions/providers/ are the reference.