--- title: "Custom models" description: "Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via models.json." --- Define custom models and providers in `~/.sf/agent/models.json`. This lets you add models not in the default registry — self-hosted endpoints, fine-tuned models, proxies, or new provider releases. The file reloads each time you open `/model` — no restart needed. ## Minimal example For local models (Ollama, LM Studio, vLLM): ```json { "providers": { "ollama": { "baseUrl": "http://localhost:11434/v1", "api": "openai-completions", "apiKey": "ollama", "models": [ { "id": "llama3.1:8b" }, { "id": "qwen2.5-coder:7b" } ] } } } ``` The `apiKey` is required but Ollama ignores it — any value works. ## Supported APIs | API | Description | |-----|-------------| | `openai-completions` | OpenAI Chat Completions (most compatible) | | `openai-responses` | OpenAI Responses API | | `anthropic-messages` | Anthropic Messages API | | `google-generative-ai` | Google Generative AI | ## Provider configuration | Field | Description | |-------|-------------| | `baseUrl` | API endpoint URL | | `api` | API type | | `apiKey` | API key (supports shell commands, env vars, or literals) | | `headers` | Custom headers | | `authHeader` | Set `true` to add `Authorization: Bearer` automatically | | `models` | Array of model configurations | | `modelOverrides` | Per-model overrides for built-in models | ### Value resolution The `apiKey` and `headers` fields support three formats: ```json "apiKey": "!security find-generic-password -ws 'anthropic'" // shell command "apiKey": "MY_API_KEY" // env variable "apiKey": "sk-..." // literal value ``` ## Model configuration | Field | Required | Default | Description | |-------|----------|---------|-------------| | `id` | Yes | — | Model identifier (passed to the API) | | `name` | No | `id` | Human-readable label | | `api` | No | provider's `api` | Override per model | | `reasoning` | No | `false` | Supports extended thinking | | `input` | No | `["text"]` | `["text"]` or `["text", "image"]` | | `contextWindow` | No | `128000` | Context window size | | `maxTokens` | No | `16384` | Maximum output tokens | | `cost` | No | all zeros | Per-million tokens: `input`, `output`, `cacheRead`, `cacheWrite` | ## Overriding built-in providers Route a built-in provider through a proxy without redefining models: ```json { "providers": { "anthropic": { "baseUrl": "https://my-proxy.example.com/v1" } } } ``` All built-in Anthropic models remain available. To add custom models alongside built-in ones, include the `models` array. ## OpenAI compatibility For providers with partial OpenAI compatibility, use the `compat` field at provider or model level: ```json { "providers": { "local-llm": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "compat": { "supportsDeveloperRole": false, "supportsReasoningEffort": false }, "models": [...] } } } ``` | Field | Description | |-------|-------------| | `supportsDeveloperRole` | Use `developer` vs `system` role | | `supportsReasoningEffort` | Support for `reasoning_effort` parameter | | `supportsUsageInStreaming` | Support for `stream_options: { include_usage: true }` | | `maxTokensField` | `max_completion_tokens` or `max_tokens` | | `thinkingFormat` | `reasoning_effort`, `zai`, `qwen`, or `qwen-chat-template` | | `openRouterRouting` | OpenRouter provider selection config | | `vercelGatewayRouting` | Vercel AI Gateway provider selection | ## Community provider extensions | Extension | Provider | Models | Install | |-----------|----------|--------|---------| | [`pi-dashscope`](https://www.npmjs.com/package/pi-dashscope) | Alibaba DashScope | Qwen3, GLM-5, MiniMax M2.5, Kimi K2.5 | `sf install npm:pi-dashscope` |