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:
--api-key <key>(with--model), for one run;~/.oino/auth.json;- the provider's environment variables.
auth.json is written with mode 0600:
{
"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:
{
"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" }
}
}apimust be implemented by a loaded component:openai-completions,openai-responses,anthropic-messages,openai-codex-responses,google-generative-ai,azure-openai-responsesorbedrock-converse-stream.apiKeyis a literal, an environment variable name, or!commandto read it from a command.authHeader: truesendsAuthorization: Bearer <key>.- An entry with only
baseUrl/headers/modelspatches 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.