docs: document custom providers and updated insecure flag [release=skip]
Cover named custom providers in models.json (provider-level baseUrl and api format, model-level baseUrl override, derived API-key env vars, /login support, no-probe key storage). Note built-in models stay visible and correct the credential-resolution order. Update the --insecure description to cover models.json baseUrl endpoints.
- commit
- 1d7dc39fe8e72164bd19034c8b7c39542cef119b
- author
- patriceckhart · · 2026-06-16 18:31 UTC
- parent
- 1dc884a
- signature
- unsigned
2 files · +59 -6
M README.md +22 -2
| @@ -141,7 +141,7 @@ zot --help | |||
| 141 | 141 | | `--model <id>` | Pick the model (see `--list-models`). | | |
| 142 | 142 | | `--api-key <key>` | Override the API key. | | |
| 143 | 143 | | `--base-url <url>` | Override the provider base URL (tests, self-hosted). | | |
| 144 | - | | `--insecure` | Skip TLS certificate verification, only for the explicit `--base-url` endpoint (self-signed local/internal inference servers). Built-in providers, auth, and model discovery keep normal TLS verification. | | |
| 144 | + | | `--insecure` | Skip TLS certificate verification for the explicit `--base-url` endpoint or a `baseUrl` defined for a user model in `models.json` (self-signed local/internal inference servers). Built-in providers, auth, and model discovery keep normal TLS verification. | | |
| 145 | 145 | | `--system-prompt <text>` | Replace the default system prompt for this run (also overrides `$ZOT_HOME/SYSTEM.md`). | | |
| 146 | 146 | | `--append-system-prompt <text>` | Append text to the system prompt (repeatable). | | |
| 147 | 147 | | `--reasoning off\|minimum\|low\|medium\|high\|maximum` | Set thinking level on supported models (default: off). | | |
| @@ -383,7 +383,27 @@ Supported fields per model: `id` (required), `name`, `reasoning`, `contextWindow | |||
| 383 | 383 | ||
| 384 | 384 | Provider keys are normalized: `openai-codex` and `openai-responses` map to `openai`, `anthropic-messages` maps to `anthropic`, `moonshot`, `moonshot-ai`, and `kimi-code` map to `kimi`, and `deepseek-chat` and `deepseek-ai` map to `deepseek`. Built-in provider ids such as `groq`, `openrouter`, `github-copilot`, `amazon-bedrock`, `google-vertex`, `azure-openai-responses`, `fireworks`, `vercel-ai-gateway`, `mistral`, and `xai` can also be used directly. | |
| 385 | 385 | ||
| 386 | - | User-defined models show `source: user` in `--list-models` and take precedence over both the baked-in catalog and live-discovered models. Missing or invalid files are silently ignored. | |
| 386 | + | User-defined models show `source: user` in `--list-models` and take precedence over both the baked-in catalog and live-discovered models. Adding a `models.json` does not hide the built-in catalog; entries are merged on top of it. Missing or invalid files are silently ignored. | |
| 387 | + | ||
| 388 | + | #### Custom providers | |
| 389 | + | ||
| 390 | + | A top-level provider key that is not a built-in id defines a custom provider. Give it a provider-level `baseUrl` and an `api` wire format (`openai` for OpenAI-compatible chat completions, the default, or `anthropic` for the Anthropic messages API). A model-level `baseUrl` overrides the provider-level one for that model; an unknown `api` value falls back to `openai` with a warning. | |
| 391 | + | ||
| 392 | + | ```json | |
| 393 | + | { | |
| 394 | + | "providers": { | |
| 395 | + | "my-company": { | |
| 396 | + | "baseUrl": "https://llm.mycompany.com/v1", | |
| 397 | + | "api": "openai", | |
| 398 | + | "models": [ | |
| 399 | + | { "id": "company-llm-v2", "name": "Company LLM v2" } | |
| 400 | + | ] | |
| 401 | + | } | |
| 402 | + | } | |
| 403 | + | } | |
| 404 | + | ``` | |
| 405 | + | ||
| 406 | + | Custom providers are first-class: they appear in `--list-models`, `/model`, and `/login`. `models.json` never stores secrets. Supply the key through `/login`, `--api-key`, or a derived environment variable in upper snake case (so `my-company` reads `MY_COMPANY_API_KEY`). Because many self-hosted gateways do not expose a model-list endpoint, custom provider keys are accepted and stored without a verification probe; an invalid key surfaces on the first model call. | |
| 387 | 407 | ||
| 388 | 408 | ### Kimi Code | |
| 389 | 409 | ||
| @@ -141,7 +141,7 @@ zot --help | |||||
| 141 | | `--model <id>` | Pick the model (see `--list-models`). | | 141 | | `--model <id>` | Pick the model (see `--list-models`). | | ||
| 142 | | `--api-key <key>` | Override the API key. | | 142 | | `--api-key <key>` | Override the API key. | | ||
| 143 | | `--base-url <url>` | Override the provider base URL (tests, self-hosted). | | 143 | | `--base-url <url>` | Override the provider base URL (tests, self-hosted). | | ||
| 144 | - | | `--insecure` | Skip TLS certificate verification, only for the explicit `--base-url` endpoint (self-signed local/internal inference servers). Built-in providers, auth, and model discovery keep normal TLS verification. | | 144 | + | | `--insecure` | Skip TLS certificate verification for the explicit `--base-url` endpoint or a `baseUrl` defined for a user model in `models.json` (self-signed local/internal inference servers). Built-in providers, auth, and model discovery keep normal TLS verification. | |
| 145 | | `--system-prompt <text>` | Replace the default system prompt for this run (also overrides `$ZOT_HOME/SYSTEM.md`). | | 145 | | `--system-prompt <text>` | Replace the default system prompt for this run (also overrides `$ZOT_HOME/SYSTEM.md`). | | ||
| 146 | | `--append-system-prompt <text>` | Append text to the system prompt (repeatable). | | 146 | | `--append-system-prompt <text>` | Append text to the system prompt (repeatable). | | ||
| 147 | | `--reasoning off\|minimum\|low\|medium\|high\|maximum` | Set thinking level on supported models (default: off). | | 147 | | `--reasoning off\|minimum\|low\|medium\|high\|maximum` | Set thinking level on supported models (default: off). | | ||
| @@ -383,7 +383,27 @@ Supported fields per model: `id` (required), `name`, `reasoning`, `contextWindow | |||||
| 383 | 383 | ||||
| 384 | Provider keys are normalized: `openai-codex` and `openai-responses` map to `openai`, `anthropic-messages` maps to `anthropic`, `moonshot`, `moonshot-ai`, and `kimi-code` map to `kimi`, and `deepseek-chat` and `deepseek-ai` map to `deepseek`. Built-in provider ids such as `groq`, `openrouter`, `github-copilot`, `amazon-bedrock`, `google-vertex`, `azure-openai-responses`, `fireworks`, `vercel-ai-gateway`, `mistral`, and `xai` can also be used directly. | 384 | Provider keys are normalized: `openai-codex` and `openai-responses` map to `openai`, `anthropic-messages` maps to `anthropic`, `moonshot`, `moonshot-ai`, and `kimi-code` map to `kimi`, and `deepseek-chat` and `deepseek-ai` map to `deepseek`. Built-in provider ids such as `groq`, `openrouter`, `github-copilot`, `amazon-bedrock`, `google-vertex`, `azure-openai-responses`, `fireworks`, `vercel-ai-gateway`, `mistral`, and `xai` can also be used directly. | ||
| 385 | 385 | ||||
| 386 | - | User-defined models show `source: user` in `--list-models` and take precedence over both the baked-in catalog and live-discovered models. Missing or invalid files are silently ignored. | 386 | + | User-defined models show `source: user` in `--list-models` and take precedence over both the baked-in catalog and live-discovered models. Adding a `models.json` does not hide the built-in catalog; entries are merged on top of it. Missing or invalid files are silently ignored. |
| 387 | + | ||||
| 388 | + | #### Custom providers | |||
| 389 | + | ||||
| 390 | + | A top-level provider key that is not a built-in id defines a custom provider. Give it a provider-level `baseUrl` and an `api` wire format (`openai` for OpenAI-compatible chat completions, the default, or `anthropic` for the Anthropic messages API). A model-level `baseUrl` overrides the provider-level one for that model; an unknown `api` value falls back to `openai` with a warning. | |||
| 391 | + | ||||
| 392 | + | ```json | |||
| 393 | + | { | |||
| 394 | + | "providers": { | |||
| 395 | + | "my-company": { | |||
| 396 | + | "baseUrl": "https://llm.mycompany.com/v1", | |||
| 397 | + | "api": "openai", | |||
| 398 | + | "models": [ | |||
| 399 | + | { "id": "company-llm-v2", "name": "Company LLM v2" } | |||
| 400 | + | ] | |||
| 401 | + | } | |||
| 402 | + | } | |||
| 403 | + | } | |||
| 404 | + | ``` | |||
| 405 | + | ||||
| 406 | + | Custom providers are first-class: they appear in `--list-models`, `/model`, and `/login`. `models.json` never stores secrets. Supply the key through `/login`, `--api-key`, or a derived environment variable in upper snake case (so `my-company` reads `MY_COMPANY_API_KEY`). Because many self-hosted gateways do not expose a model-list endpoint, custom provider keys are accepted and stored without a verification probe; an invalid key surfaces on the first model call. | |||
| 387 | 407 | ||||
| 388 | ### Kimi Code | 408 | ### Kimi Code | ||
| 389 | 409 | ||||
M docs/providers.md +37 -4
| @@ -196,15 +196,48 @@ Other API-key providers are stored under `additional_api_key_creds`. Prefer | |||
| 196 | 196 | ||
| 197 | 197 | Use `$ZOT_HOME/models.json` for private models, deployment aliases, local | |
| 198 | 198 | servers, or OpenAI-compatible gateways that are not in the built-in catalog. | |
| 199 | - | User entries override built-in entries with the same provider and model ID. | |
| 199 | + | User entries override built-in entries with the same provider and model ID, and | |
| 200 | + | adding a `models.json` no longer hides the built-in catalog: your entries are | |
| 201 | + | merged on top of the baked-in and live-discovered models. | |
| 202 | + | ||
| 203 | + | A top-level provider key that is not a built-in id defines a custom provider. | |
| 204 | + | Give it a provider-level `baseUrl` and an `api` wire format (`openai` for | |
| 205 | + | OpenAI-compatible chat completions, the default, or `anthropic` for the | |
| 206 | + | Anthropic messages API). A model-level `baseUrl` overrides the provider-level | |
| 207 | + | one for that model, and an unknown `api` value falls back to `openai` with a | |
| 208 | + | warning. | |
| 209 | + | ||
| 210 | + | ```json | |
| 211 | + | { | |
| 212 | + | "providers": { | |
| 213 | + | "my-company": { | |
| 214 | + | "baseUrl": "https://llm.mycompany.com/v1", | |
| 215 | + | "api": "openai", | |
| 216 | + | "models": [ | |
| 217 | + | { "id": "company-llm-v2", "name": "Company LLM v2" } | |
| 218 | + | ] | |
| 219 | + | } | |
| 220 | + | } | |
| 221 | + | } | |
| 222 | + | ``` | |
| 223 | + | ||
| 224 | + | Custom providers are first-class: they appear in `--list-models`, `/model`, and | |
| 225 | + | `/login`. `models.json` never stores secrets. Supply the key through `/login`, | |
| 226 | + | `--api-key`, or a derived environment variable in upper snake case, so | |
| 227 | + | `my-company` reads `MY_COMPANY_API_KEY`. Because many self-hosted gateways do | |
| 228 | + | not expose a model-list endpoint, custom provider keys are accepted and stored | |
| 229 | + | without a verification probe; an invalid key surfaces on the first model call. | |
| 200 | 230 | ||
| 201 | 231 | ## Credential resolution | |
| 202 | 232 | ||
| 203 | 233 | For each request, zot checks credentials in this order: | |
| 204 | 234 | ||
| 205 | 235 | 1. Explicit CLI key, such as `--api-key`. | |
| 206 | - | 2. Provider-specific environment variables. | |
| 207 | - | 3. `$ZOT_HOME/auth.json`. | |
| 208 | - | 4. Custom provider credentials from `$ZOT_HOME/models.json`, when configured. | |
| 236 | + | 2. Provider-specific environment variables (including derived custom-provider | |
| 237 | + | variables such as `MY_COMPANY_API_KEY`). | |
| 238 | + | 3. `$ZOT_HOME/auth.json`, including custom provider keys saved by `/login`. | |
| 239 | + | ||
| 240 | + | `models.json` itself never stores credentials; it only describes models and | |
| 241 | + | their endpoints. | |
| 209 | 242 | ||
| 210 | 243 | Bedrock then uses the AWS SDK credential chain for the actual request. | |
| @@ -196,15 +196,48 @@ Other API-key providers are stored under `additional_api_key_creds`. Prefer | |||||
| 196 | 196 | ||||
| 197 | Use `$ZOT_HOME/models.json` for private models, deployment aliases, local | 197 | Use `$ZOT_HOME/models.json` for private models, deployment aliases, local | ||
| 198 | servers, or OpenAI-compatible gateways that are not in the built-in catalog. | 198 | servers, or OpenAI-compatible gateways that are not in the built-in catalog. | ||
| 199 | - | User entries override built-in entries with the same provider and model ID. | 199 | + | User entries override built-in entries with the same provider and model ID, and |
| 200 | + | adding a `models.json` no longer hides the built-in catalog: your entries are | |||
| 201 | + | merged on top of the baked-in and live-discovered models. | |||
| 202 | + | ||||
| 203 | + | A top-level provider key that is not a built-in id defines a custom provider. | |||
| 204 | + | Give it a provider-level `baseUrl` and an `api` wire format (`openai` for | |||
| 205 | + | OpenAI-compatible chat completions, the default, or `anthropic` for the | |||
| 206 | + | Anthropic messages API). A model-level `baseUrl` overrides the provider-level | |||
| 207 | + | one for that model, and an unknown `api` value falls back to `openai` with a | |||
| 208 | + | warning. | |||
| 209 | + | ||||
| 210 | + | ```json | |||
| 211 | + | { | |||
| 212 | + | "providers": { | |||
| 213 | + | "my-company": { | |||
| 214 | + | "baseUrl": "https://llm.mycompany.com/v1", | |||
| 215 | + | "api": "openai", | |||
| 216 | + | "models": [ | |||
| 217 | + | { "id": "company-llm-v2", "name": "Company LLM v2" } | |||
| 218 | + | ] | |||
| 219 | + | } | |||
| 220 | + | } | |||
| 221 | + | } | |||
| 222 | + | ``` | |||
| 223 | + | ||||
| 224 | + | Custom providers are first-class: they appear in `--list-models`, `/model`, and | |||
| 225 | + | `/login`. `models.json` never stores secrets. Supply the key through `/login`, | |||
| 226 | + | `--api-key`, or a derived environment variable in upper snake case, so | |||
| 227 | + | `my-company` reads `MY_COMPANY_API_KEY`. Because many self-hosted gateways do | |||
| 228 | + | not expose a model-list endpoint, custom provider keys are accepted and stored | |||
| 229 | + | without a verification probe; an invalid key surfaces on the first model call. | |||
| 200 | 230 | ||||
| 201 | ## Credential resolution | 231 | ## Credential resolution | ||
| 202 | 232 | ||||
| 203 | For each request, zot checks credentials in this order: | 233 | For each request, zot checks credentials in this order: | ||
| 204 | 234 | ||||
| 205 | 1. Explicit CLI key, such as `--api-key`. | 235 | 1. Explicit CLI key, such as `--api-key`. | ||
| 206 | - | 2. Provider-specific environment variables. | 236 | + | 2. Provider-specific environment variables (including derived custom-provider |
| 207 | - | 3. `$ZOT_HOME/auth.json`. | 237 | + | variables such as `MY_COMPANY_API_KEY`). |
| 208 | - | 4. Custom provider credentials from `$ZOT_HOME/models.json`, when configured. | 238 | + | 3. `$ZOT_HOME/auth.json`, including custom provider keys saved by `/login`. |
| 239 | + | ||||
| 240 | + | `models.json` itself never stores credentials; it only describes models and | |||
| 241 | + | their endpoints. | |||
| 209 | 242 | ||||
| 210 | Bedrock then uses the AWS SDK credential chain for the actual request. | 243 | Bedrock then uses the AWS SDK credential chain for the actual request. | ||