From 69d66e0d6ac3869f4767db12a89222d5b3ae2508 Mon Sep 17 00:00:00 2001 From: chengyongru Date: Thu, 11 Jun 2026 15:19:32 +0800 Subject: [PATCH] docs: document named custom providers maintainer edit: explain how to configure arbitrary OpenAI-compatible provider names, including multiple endpoints, model presets, and troubleshooting guidance. --- docs/configuration.md | 1 + docs/provider-cookbook.md | 41 +++++++++++++++++++++++++++++++++++++++ docs/providers.md | 39 ++++++++++++++++++++++++++++++++++++- docs/troubleshooting.md | 2 +- 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 0e4ab2bca..e63c8f2bf 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -205,6 +205,7 @@ Tracing covers the providers that go through nanobot's OpenAI-compatible client > - **Step Fun (Mainland China)**: If your API key is from Step Fun's mainland China platform (stepfun.com), set `"apiBase": "https://api.stepfun.com/v1"` in your stepfun provider config. > - **Xiaomi MiMo thinking mode**: MiMo models (e.g. `mimo-v2.5-pro`) default to enabled thinking. Use `agents.defaults.reasoningEffort: "none"` to disable it, or `"low"` / `"medium"` / `"high"` to keep it on. Omitting the field preserves the provider's per-model default. > - **Xiaomi MiMo Token Plan**: If you're on MiMo's token plan, set `"apiBase": "https://token-plan-sgp.xiaomimimo.com/v1"` in your xiaomi_mimo provider config. +> - **Custom OpenAI-compatible providers**: Besides the built-in `custom` provider, any extra key under `providers` can define its own OpenAI-compatible endpoint. For example, `providers.companyProxy.apiBase` plus `modelPresets.primary.provider: "companyProxy"` creates a separate custom provider. Set `apiBase`; set `apiKey` only when the endpoint requires it. | Provider | Purpose | Get API Key | |----------|---------|-------------| diff --git a/docs/provider-cookbook.md b/docs/provider-cookbook.md index 92315c6eb..cfcb240ae 100644 --- a/docs/provider-cookbook.md +++ b/docs/provider-cookbook.md @@ -207,6 +207,47 @@ nanobot agent -m "Hello!" `apiBase` is the HTTP base URL, not the model name. Include the version path when the service expects it, such as `/v1`. If the service requires a non-empty key but does not validate it, use a placeholder such as `"apiKey": "EMPTY"`. +For multiple custom endpoints, do not overload the single `custom` block. Name each endpoint under `providers` and reference that same name from the preset: + +```json +{ + "providers": { + "workProxy": { + "apiKey": "${WORK_PROXY_API_KEY}", + "apiBase": "https://proxy.example.com/v1" + }, + "lab-local": { + "apiBase": "http://127.0.0.1:8000/v1" + } + }, + "modelPresets": { + "work": { + "label": "Work proxy", + "provider": "workProxy", + "model": "gpt-4o-mini", + "maxTokens": 4096, + "contextWindowTokens": 65536, + "temperature": 0.1 + }, + "lab": { + "label": "Lab local", + "provider": "lab-local", + "model": "served-model-name", + "maxTokens": 4096, + "contextWindowTokens": 65536, + "temperature": 0.1 + } + }, + "agents": { + "defaults": { + "modelPreset": "work" + } + } +} +``` + +These custom names behave like direct OpenAI-compatible providers: `apiBase` is required, `apiKey` is optional when the endpoint allows anonymous or placeholder credentials, and `apiType` should be left unset. + ## Recipe: Ollama Local Model This recipe applies when Ollama is already installed and the model has been pulled locally. diff --git a/docs/providers.md b/docs/providers.md index 5e6a381c1..32ec2fa40 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -150,7 +150,7 @@ Anthropic direct uses the native Anthropic provider. Do not use an OpenRouter mo ### Custom OpenAI-Compatible Endpoint -The `custom` provider fits OpenAI-compatible endpoints that are not represented by a named provider. +The `custom` provider fits one OpenAI-compatible endpoint that is not represented by a named provider. ```json { @@ -178,6 +178,43 @@ The `custom` provider fits OpenAI-compatible endpoints that are not represented `custom` does not infer a default base URL. Set `apiBase`. +If you have more than one custom OpenAI-compatible endpoint, give each endpoint its own provider key under `providers` and use that same key in the model preset. The key can be a name that makes sense in your environment, such as `companyProxy`, `tenant-a`, or `dev-local`. + +```json +{ + "providers": { + "companyProxy": { + "apiKey": "${COMPANY_PROXY_API_KEY}", + "apiBase": "https://llm-proxy.example.com/v1" + }, + "tenant-a": { + "apiBase": "https://tenant-a.example.com/v1" + } + }, + "modelPresets": { + "company": { + "provider": "companyProxy", + "model": "gpt-4o-mini", + "maxTokens": 8192, + "contextWindowTokens": 65536 + }, + "tenantA": { + "provider": "tenant-a", + "model": "served-model-name", + "maxTokens": 8192, + "contextWindowTokens": 65536 + } + }, + "agents": { + "defaults": { + "modelPreset": "company" + } + } +} +``` + +Custom provider keys are treated as direct OpenAI-compatible providers. `apiBase` is required because nanobot cannot know the endpoint URL. `apiKey` is optional for local servers or private proxies that do not require one. Do not set `apiType` on custom provider keys; `apiType` is only for `providers.openai`. + ### Ollama Start Ollama separately, then point nanobot at the OpenAI-compatible endpoint. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 8e26101cf..3c19fa025 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -102,7 +102,7 @@ Common config mistakes: | Symptom | Check | |---|---| | JSON parse error | Validate commas, braces, and quotes. Most docs examples are partial snippets to merge. | -| Unknown or missing provider | Use provider registry names such as `openrouter`, `anthropic`, `openai`, `ollama`, `vllm`, `lm_studio`. | +| Unknown or missing provider | Use provider registry names such as `openrouter`, `anthropic`, `openai`, `ollama`, `vllm`, `lm_studio`, or define a custom OpenAI-compatible provider key under `providers` and reference that exact key from the active preset. | | snake_case vs camelCase confusion | Both are accepted, but docs use camelCase because nanobot writes config with aliases such as `apiKey`, `modelPresets`, `intervalS`. | | Environment variable error | `${VAR_NAME}` references are resolved at startup. Set the variable before running nanobot. | | Edited config but behavior did not change | Restart `nanobot gateway`; long-running processes read config at startup. |