Files
chatgpt-on-wechat/docs/models/custom.mdx
kirs-hi cffa590d3e feat(web): manage multiple custom (OpenAI-compatible) providers in console UI
Adds first-class support for configuring more than one custom
OpenAI-compatible provider (e.g. SiliconFlow, DeepSeek, local vLLM)
and switching the active one from the web console, addressing #2838.

Backend:
- config: new `custom_providers` (list) and `custom_active_provider`
  fields, fully backward compatible with the legacy single
  `open_ai_api_base`/`model` fields (used as fallback).
- models/custom_provider.py: centralized resolver
  `resolve_custom_credentials()` returning (api_key, api_base, model),
  with active-provider selection and graceful fallback.
- chat_gpt_bot.py wired to use the resolver.
- web_channel.py: `_provider_overview` expands `custom_providers` into
  one card per provider (id `custom:<name>`, active flag, masked key);
  new POST actions `set_custom_provider`, `delete_custom_provider`,
  `set_active_custom_provider` with hermetic persistence + bridge reset.

Frontend:
- console.js: dedicated "Custom providers" section with add / edit /
  delete / set-active actions, masked-key keep-existing handling, and
  ~20 new zh/en i18n strings.
- chat.html: custom provider modal.

Tests:
- tests/test_custom_provider.py (11) - resolver/config behavior.
- tests/test_custom_provider_handlers.py (18) - write-side handlers and
  overview expansion, including duplicate-name rejection.

All 29 unit tests pass.
2026-06-10 18:12:30 +08:00

97 lines
2.9 KiB
Plaintext

---
title: Custom
description: Custom vendor configuration for third-party API proxies and local models
---
For model services accessed via the OpenAI-compatible protocol or locally deployed models, such as:
- **Third-party API proxies**: call multiple models through a unified API base
- **Local models**: models deployed locally with tools like Ollama, vLLM, LocalAI
- **Private deployments**: model services deployed inside an enterprise
<Note>
Difference from the `openai` vendor: when a custom vendor is selected, switching models via `/config model` does not automatically switch the vendor type — the custom API address is always used.
</Note>
## Text Chat
### Third-party API proxy
```json
{
"bot_type": "custom",
"model": "",
"custom_api_key": "YOUR_API_KEY",
"custom_api_base": "https://{your-proxy.com}/v1"
}
```
| Parameter | Description |
| --- | --- |
| `bot_type` | Must be set to `custom` |
| `model` | Model name; any model name supported by the proxy service |
| `custom_api_key` | API key provided by the proxy service |
| `custom_api_base` | API endpoint provided by the proxy service; must be OpenAI-compatible |
### Local models
Local models usually do not require an API key — only the API base needs to be filled in:
```json
{
"bot_type": "custom",
"model": "qwen3.5:27b",
"custom_api_base": "http://localhost:11434/v1"
}
```
Common local deployment tools and their default endpoints:
| Tool | Default API Base |
| --- | --- |
| [Ollama](https://ollama.com) | `http://localhost:11434/v1` |
| [vLLM](https://docs.vllm.ai) | `http://localhost:8000/v1` |
| [LocalAI](https://localai.io) | `http://localhost:8080/v1` |
### Switching Models
Switching models under a custom vendor only changes `model` — `bot_type` and the API endpoint remain unchanged:
```
/config model qwen3.5:27b
```
## Configuring Multiple Custom Providers
If you need to configure several OpenAI-compatible third-party services at once (e.g. SiliconFlow, Qiniu), use the `custom_providers` list and select the active one with `custom_active_provider`:
```json
{
"bot_type": "custom",
"custom_active_provider": "siliconflow",
"custom_providers": [
{
"name": "siliconflow",
"api_key": "YOUR_SILICONFLOW_KEY",
"api_base": "https://api.siliconflow.cn/v1",
"model": "deepseek-ai/DeepSeek-V3"
},
{
"name": "qiniu",
"api_key": "YOUR_QINIU_KEY",
"api_base": "https://api.qnaigc.com/v1",
"model": "deepseek-v3"
}
]
}
```
| Parameter | Description |
| --- | --- |
| `custom_providers` | List of custom providers; each item has `name`, `api_key`, `api_base`, and an optional `model` |
| `custom_active_provider` | The `name` of the active provider; when empty, the first entry in the list is used |
<Note>
When `custom_providers` is empty, CowAgent automatically falls back to the single-provider `custom_api_key` / `custom_api_base` fields above, so existing configurations keep working without any changes.
</Note>