Providers: add xAI compat support
This commit is contained in:
parent
7eba27c3c4
commit
85186fbe46
11 changed files with 46 additions and 0 deletions
|
|
@ -393,6 +393,7 @@ PicoClaw supports 30+ LLM providers through the `model_list` configuration. Use
|
|||
| [Groq](https://console.groq.com/keys) | `groq/` | Required | Fast inference (Llama, Mixtral) |
|
||||
| [Moonshot (Kimi)](https://platform.moonshot.cn/console/api-keys) | `moonshot/` | Required | Kimi models |
|
||||
| [Minimax](https://platform.minimaxi.com/user-center/basic-information/interface-key) | `minimax/` | Required | MiniMax models |
|
||||
| [xAI](https://console.x.ai/) | `xai/` | Required | Grok models |
|
||||
| [Mistral](https://console.mistral.ai/api-keys) | `mistral/` | Required | Mistral Large, Codestral |
|
||||
| [NVIDIA NIM](https://build.nvidia.com/) | `nvidia/` | Required | NVIDIA hosted models |
|
||||
| [Cerebras](https://cloud.cerebras.ai/) | `cerebras/` | Required | Fast inference |
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@
|
|||
"model": "venice/venice-uncensored",
|
||||
"api_key": "your-venice-api-key"
|
||||
},
|
||||
{
|
||||
"model_name": "grok-4",
|
||||
"model": "xai/grok-4",
|
||||
"api_key": "your-xai-api-key"
|
||||
},
|
||||
{
|
||||
"model_name": "lmstudio-local",
|
||||
"model": "lmstudio/openai/gpt-oss-20b"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
| `nvidia` | LLM (NVIDIA NIM) | [build.nvidia.com](https://build.nvidia.com) |
|
||||
| `moonshot` | LLM (Kimi/Moonshot direct) | [platform.moonshot.cn](https://platform.moonshot.cn) |
|
||||
| `minimax` | LLM (Minimax direct) | [platform.minimaxi.com](https://platform.minimaxi.com) |
|
||||
| `xai` | LLM (xAI Grok direct) | [console.x.ai](https://console.x.ai) |
|
||||
| `avian` | LLM (Avian direct) | [avian.io](https://avian.io) |
|
||||
| `mistral` | LLM (Mistral direct) | [console.mistral.ai](https://console.mistral.ai) |
|
||||
| `longcat` | LLM (Longcat direct) | [longcat.ai](https://longcat.ai) |
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
| `anthropic` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) |
|
||||
| `openai` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) |
|
||||
| `venice` | LLM (Venice AI 直连) | [venice.ai](https://venice.ai) |
|
||||
| `xai` | LLM (xAI Grok 直连) | [console.x.ai](https://console.x.ai) |
|
||||
| `deepseek` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||
| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||
| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
| ------------------- | ----------------- | --------------------------------------------------- | --------- | ----------------------------------------------------------------- |
|
||||
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) |
|
||||
| **Venice AI** | `venice/` | `https://api.venice.ai/api/v1` | OpenAI | [获取密钥](https://venice.ai) |
|
||||
| **xAI** | `xai/` | `https://api.x.ai/v1` | OpenAI | [获取密钥](https://console.x.ai) |
|
||||
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) |
|
||||
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [获取密钥](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
|
||||
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) |
|
||||
|
|
|
|||
|
|
@ -192,6 +192,13 @@ func DefaultConfig() *Config {
|
|||
APIBase: "https://api.venice.ai/api/v1",
|
||||
},
|
||||
|
||||
// xAI - https://console.x.ai/
|
||||
{
|
||||
ModelName: "grok-4",
|
||||
Model: "xai/grok-4",
|
||||
APIBase: "https://api.x.ai/v1",
|
||||
},
|
||||
|
||||
// Google Gemini - https://ai.google.dev/
|
||||
{
|
||||
ModelName: "gemini-2.0-flash",
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ var protocolMetaByName = map[string]protocolMeta{
|
|||
"cerebras": {defaultAPIBase: "https://api.cerebras.ai/v1"},
|
||||
"vivgrid": {defaultAPIBase: "https://api.vivgrid.com/v1"},
|
||||
"volcengine": {defaultAPIBase: "https://ark.cn-beijing.volces.com/api/v3"},
|
||||
"xai": {defaultAPIBase: "https://api.x.ai/v1"},
|
||||
"x-ai": {defaultAPIBase: "https://api.x.ai/v1"},
|
||||
"x.ai": {defaultAPIBase: "https://api.x.ai/v1"},
|
||||
"qwen": {defaultAPIBase: "https://dashscope.aliyuncs.com/compatible-mode/v1"},
|
||||
"qwen-intl": {defaultAPIBase: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"},
|
||||
"qwen-international": {defaultAPIBase: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"},
|
||||
|
|
@ -214,6 +217,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
|||
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
||||
"vivgrid", "volcengine", "vllm", "qwen", "qwen-intl", "qwen-international", "dashscope-intl",
|
||||
"qwen-us", "dashscope-us", "mistral", "avian", "longcat", "modelscope", "novita",
|
||||
"xai", "x-ai", "x.ai",
|
||||
"coding-plan", "alibaba-coding", "qwen-coding", "mimo":
|
||||
// All other OpenAI-compatible HTTP providers
|
||||
if cfg.APIKey() == "" && cfg.APIBase == "" && !isEmptyAPIKeyAllowed(protocol) {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ func TestCreateProviderFromConfig_DefaultAPIBase(t *testing.T) {
|
|||
{"openrouter", "openrouter"},
|
||||
{"cerebras", "cerebras"},
|
||||
{"vivgrid", "vivgrid"},
|
||||
{"xai", "xai"},
|
||||
{"x-ai", "x-ai"},
|
||||
{"x.ai", "x.ai"},
|
||||
{"qwen", "qwen"},
|
||||
{"vllm", "vllm"},
|
||||
{"deepseek", "deepseek"},
|
||||
|
|
@ -751,6 +754,15 @@ func TestGetDefaultAPIBase_QwenUSAliases(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetDefaultAPIBase_XAI(t *testing.T) {
|
||||
expectedURL := "https://api.x.ai/v1"
|
||||
for _, protocol := range []string{"xai", "x-ai", "x.ai"} {
|
||||
if got := getDefaultAPIBase(protocol); got != expectedURL {
|
||||
t.Fatalf("getDefaultAPIBase(%q) = %q, want %q", protocol, got, expectedURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateProviderFromConfig_MinimaxInjectsReasoningSplit(t *testing.T) {
|
||||
var requestBody map[string]any
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ func NormalizeProvider(provider string) string {
|
|||
return "zhipu"
|
||||
case "google":
|
||||
return "gemini"
|
||||
case "x-ai", "x.ai":
|
||||
return "xai"
|
||||
case "alibaba-coding", "qwen-coding":
|
||||
return "coding-plan"
|
||||
case "alibaba-coding-anthropic":
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ func TestNormalizeProvider(t *testing.T) {
|
|||
{"glm", "zhipu"},
|
||||
{"google", "gemini"},
|
||||
{"groq", "groq"},
|
||||
{"xai", "xai"},
|
||||
{"x-ai", "xai"},
|
||||
{"x.ai", "xai"},
|
||||
// Alibaba Coding Plan aliases
|
||||
{"alibaba-coding", "coding-plan"},
|
||||
{"qwen-coding", "coding-plan"},
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ var stripModelPrefixProviders = map[string]struct{}{
|
|||
"google": {},
|
||||
"openrouter": {},
|
||||
"zhipu": {},
|
||||
"xai": {},
|
||||
"mistral": {},
|
||||
"vivgrid": {},
|
||||
"minimax": {},
|
||||
|
|
|
|||
|
|
@ -484,6 +484,11 @@ func TestProviderChat_StripsKnownProviderPrefixes(t *testing.T) {
|
|||
input: "venice/venice-uncensored",
|
||||
wantModel: "venice-uncensored",
|
||||
},
|
||||
{
|
||||
name: "strips xai prefix",
|
||||
input: "xai/grok-4",
|
||||
wantModel: "grok-4",
|
||||
},
|
||||
{
|
||||
name: "strips deepseek prefix",
|
||||
input: "deepseek/deepseek-chat",
|
||||
|
|
@ -595,6 +600,9 @@ func TestNormalizeModel_UsesAPIBase(t *testing.T) {
|
|||
if got := normalizeModel("venice/venice-uncensored", "https://api.venice.ai/api/v1"); got != "venice-uncensored" {
|
||||
t.Fatalf("normalizeModel(venice) = %q, want %q", got, "venice-uncensored")
|
||||
}
|
||||
if got := normalizeModel("xai/grok-4", "https://api.x.ai/v1"); got != "grok-4" {
|
||||
t.Fatalf("normalizeModel(xai) = %q, want %q", got, "grok-4")
|
||||
}
|
||||
if got := normalizeModel("openrouter/auto", "https://openrouter.ai/api/v1"); got != "openrouter/auto" {
|
||||
t.Fatalf("normalizeModel(openrouter) = %q, want %q", got, "openrouter/auto")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue