feat(provider): add Venice AI support and update related documentation (#2238)
* feat(provider): add Venice AI support and update related documentation * revert(asr): restore asr files to previous commit * feat(config): add Venice API base URL and local LM Studio configuration * fix(config): update Venice API base URL to correct endpoint
This commit is contained in:
parent
9ac21c5908
commit
bbcfeaa361
8 changed files with 63 additions and 1 deletions
|
|
@ -48,6 +48,11 @@
|
||||||
"model": "deepseek/deepseek-chat",
|
"model": "deepseek/deepseek-chat",
|
||||||
"api_key": "sk-your-deepseek-key"
|
"api_key": "sk-your-deepseek-key"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"model_name": "venice-uncensored",
|
||||||
|
"model": "venice/venice-uncensored",
|
||||||
|
"api_key": "your-venice-api-key"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"model_name": "lmstudio-local",
|
"model_name": "lmstudio-local",
|
||||||
"model": "lmstudio/openai/gpt-oss-20b"
|
"model": "lmstudio/openai/gpt-oss-20b"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) |
|
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) |
|
||||||
| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
|
| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
|
||||||
| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
|
| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
|
||||||
|
| `venice` | LLM (Venice AI direct) | [venice.ai](https://venice.ai) |
|
||||||
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||||
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
|
@ -46,6 +47,7 @@ This design also enables **multi-agent support** with flexible provider selectio
|
||||||
| Vendor | `model` Prefix | Default API Base | Protocol | API Key |
|
| Vendor | `model` Prefix | Default API Base | Protocol | API Key |
|
||||||
| ------------------- | ----------------- |-----------------------------------------------------| --------- | ---------------------------------------------------------------- |
|
| ------------------- | ----------------- |-----------------------------------------------------| --------- | ---------------------------------------------------------------- |
|
||||||
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) |
|
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) |
|
||||||
|
| **Venice AI** | `venice/` | `https://api.venice.ai/api/v1` | OpenAI | [Get Key](https://venice.ai) |
|
||||||
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) |
|
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) |
|
||||||
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
|
| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
|
||||||
| **Z.AI Coding Plan** | `openai/` | `https://api.z.ai/api/coding/paas/v4` | OpenAI | [Get Key](https://z.ai/manage-apikey/apikey-list) |
|
| **Z.AI Coding Plan** | `openai/` | `https://api.z.ai/api/coding/paas/v4` | OpenAI | [Get Key](https://z.ai/manage-apikey/apikey-list) |
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
| `openrouter` | LLM (推荐,可访问所有模型) | [openrouter.ai](https://openrouter.ai) |
|
| `openrouter` | LLM (推荐,可访问所有模型) | [openrouter.ai](https://openrouter.ai) |
|
||||||
| `anthropic` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) |
|
| `anthropic` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) |
|
||||||
| `openai` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) |
|
| `openai` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) |
|
||||||
|
| `venice` | LLM (Venice AI 直连) | [venice.ai](https://venice.ai) |
|
||||||
| `deepseek` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||||
| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
|
@ -44,6 +45,7 @@
|
||||||
| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key |
|
| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key |
|
||||||
| ------------------- | ----------------- | --------------------------------------------------- | --------- | ----------------------------------------------------------------- |
|
| ------------------- | ----------------- | --------------------------------------------------- | --------- | ----------------------------------------------------------------- |
|
||||||
| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) |
|
| **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) |
|
||||||
| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) |
|
| **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) |
|
| **智谱 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) |
|
| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) |
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,13 @@ func DefaultConfig() *Config {
|
||||||
APIBase: "https://api.deepseek.com/v1",
|
APIBase: "https://api.deepseek.com/v1",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Venice AI - https://venice.ai
|
||||||
|
{
|
||||||
|
ModelName: "venice-uncensored",
|
||||||
|
Model: "venice/venice-uncensored",
|
||||||
|
APIBase: "https://api.venice.ai/api/v1",
|
||||||
|
},
|
||||||
|
|
||||||
// Google Gemini - https://ai.google.dev/
|
// Google Gemini - https://ai.google.dev/
|
||||||
{
|
{
|
||||||
ModelName: "gemini-2.0-flash",
|
ModelName: "gemini-2.0-flash",
|
||||||
|
|
@ -335,6 +342,13 @@ func DefaultConfig() *Config {
|
||||||
APIBase: "http://localhost:8000/v1",
|
APIBase: "http://localhost:8000/v1",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// LM Studio (local) - http://localhost:1234
|
||||||
|
{
|
||||||
|
ModelName: "lmstudio-local",
|
||||||
|
Model: "lmstudio/openai/gpt-oss-20b",
|
||||||
|
APIBase: "http://localhost:1234/v1",
|
||||||
|
},
|
||||||
|
|
||||||
// Azure OpenAI - https://portal.azure.com
|
// Azure OpenAI - https://portal.azure.com
|
||||||
// model_name is a user-friendly alias; the model field's path after "azure/" is your deployment name
|
// model_name is a user-friendly alias; the model field's path after "azure/" is your deployment name
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ type protocolMeta struct {
|
||||||
|
|
||||||
var protocolMetaByName = map[string]protocolMeta{
|
var protocolMetaByName = map[string]protocolMeta{
|
||||||
"openai": {defaultAPIBase: "https://api.openai.com/v1"},
|
"openai": {defaultAPIBase: "https://api.openai.com/v1"},
|
||||||
|
"venice": {defaultAPIBase: "https://api.venice.ai/api/v1"},
|
||||||
"openrouter": {defaultAPIBase: "https://openrouter.ai/api/v1"},
|
"openrouter": {defaultAPIBase: "https://openrouter.ai/api/v1"},
|
||||||
"litellm": {defaultAPIBase: "http://localhost:4000/v1"},
|
"litellm": {defaultAPIBase: "http://localhost:4000/v1"},
|
||||||
"lmstudio": {defaultAPIBase: "http://localhost:1234/v1", emptyAPIKeyAllowed: true},
|
"lmstudio": {defaultAPIBase: "http://localhost:1234/v1", emptyAPIKeyAllowed: true},
|
||||||
|
|
@ -209,7 +210,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
}
|
}
|
||||||
return provider, modelID, nil
|
return provider, modelID, nil
|
||||||
|
|
||||||
case "litellm", "lmstudio", "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
case "litellm", "lmstudio", "openrouter", "groq", "zhipu", "gemini", "nvidia", "venice",
|
||||||
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
||||||
"vivgrid", "volcengine", "vllm", "qwen", "qwen-intl", "qwen-international", "dashscope-intl",
|
"vivgrid", "volcengine", "vllm", "qwen", "qwen-intl", "qwen-international", "dashscope-intl",
|
||||||
"qwen-us", "dashscope-us", "mistral", "avian", "longcat", "modelscope", "novita",
|
"qwen-us", "dashscope-us", "mistral", "avian", "longcat", "modelscope", "novita",
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ func TestCreateProviderFromConfig_DefaultAPIBase(t *testing.T) {
|
||||||
protocol string
|
protocol string
|
||||||
}{
|
}{
|
||||||
{"openai", "openai"},
|
{"openai", "openai"},
|
||||||
|
{"venice", "venice"},
|
||||||
{"groq", "groq"},
|
{"groq", "groq"},
|
||||||
{"novita", "novita"},
|
{"novita", "novita"},
|
||||||
{"openrouter", "openrouter"},
|
{"openrouter", "openrouter"},
|
||||||
|
|
@ -160,6 +161,12 @@ func TestGetDefaultAPIBase_LMStudio(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetDefaultAPIBase_Venice(t *testing.T) {
|
||||||
|
if got := getDefaultAPIBase("venice"); got != "https://api.venice.ai/api/v1" {
|
||||||
|
t.Fatalf("getDefaultAPIBase(%q) = %q, want %q", "venice", got, "https://api.venice.ai/api/v1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateProviderFromConfig_LiteLLM(t *testing.T) {
|
func TestCreateProviderFromConfig_LiteLLM(t *testing.T) {
|
||||||
cfg := &config.ModelConfig{
|
cfg := &config.ModelConfig{
|
||||||
ModelName: "test-litellm",
|
ModelName: "test-litellm",
|
||||||
|
|
@ -362,6 +369,28 @@ func TestCreateProviderFromConfig_Mimo(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateProviderFromConfig_Venice(t *testing.T) {
|
||||||
|
cfg := &config.ModelConfig{
|
||||||
|
ModelName: "test-venice",
|
||||||
|
Model: "venice/venice-uncensored",
|
||||||
|
}
|
||||||
|
cfg.SetAPIKey("test-key")
|
||||||
|
|
||||||
|
provider, modelID, err := CreateProviderFromConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CreateProviderFromConfig() error = %v", err)
|
||||||
|
}
|
||||||
|
if provider == nil {
|
||||||
|
t.Fatal("CreateProviderFromConfig() returned nil provider")
|
||||||
|
}
|
||||||
|
if modelID != "venice-uncensored" {
|
||||||
|
t.Errorf("modelID = %q, want %q", modelID, "venice-uncensored")
|
||||||
|
}
|
||||||
|
if _, ok := provider.(*HTTPProvider); !ok {
|
||||||
|
t.Fatalf("expected *HTTPProvider, got %T", provider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetDefaultAPIBase_Mimo(t *testing.T) {
|
func TestGetDefaultAPIBase_Mimo(t *testing.T) {
|
||||||
if got := getDefaultAPIBase("mimo"); got != "https://api.xiaomimimo.com/v1" {
|
if got := getDefaultAPIBase("mimo"); got != "https://api.xiaomimimo.com/v1" {
|
||||||
t.Fatalf("getDefaultAPIBase(%q) = %q, want %q", "mimo", got, "https://api.xiaomimimo.com/v1")
|
t.Fatalf("getDefaultAPIBase(%q) = %q, want %q", "mimo", got, "https://api.xiaomimimo.com/v1")
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ const defaultRequestTimeout = common.DefaultRequestTimeout
|
||||||
|
|
||||||
var stripModelPrefixProviders = map[string]struct{}{
|
var stripModelPrefixProviders = map[string]struct{}{
|
||||||
"litellm": {},
|
"litellm": {},
|
||||||
|
"venice": {},
|
||||||
"moonshot": {},
|
"moonshot": {},
|
||||||
"nvidia": {},
|
"nvidia": {},
|
||||||
"groq": {},
|
"groq": {},
|
||||||
|
|
|
||||||
|
|
@ -479,6 +479,11 @@ func TestProviderChat_StripsKnownProviderPrefixes(t *testing.T) {
|
||||||
input: "lmstudio/openai/gpt-oss-20b",
|
input: "lmstudio/openai/gpt-oss-20b",
|
||||||
wantModel: "openai/gpt-oss-20b",
|
wantModel: "openai/gpt-oss-20b",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "strips venice prefix",
|
||||||
|
input: "venice/venice-uncensored",
|
||||||
|
wantModel: "venice-uncensored",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "strips deepseek prefix",
|
name: "strips deepseek prefix",
|
||||||
input: "deepseek/deepseek-chat",
|
input: "deepseek/deepseek-chat",
|
||||||
|
|
@ -587,6 +592,9 @@ func TestNormalizeModel_UsesAPIBase(t *testing.T) {
|
||||||
if got := normalizeModel("lmstudio/openai/gpt-oss-20b", "http://localhost:1234/v1"); got != "openai/gpt-oss-20b" {
|
if got := normalizeModel("lmstudio/openai/gpt-oss-20b", "http://localhost:1234/v1"); got != "openai/gpt-oss-20b" {
|
||||||
t.Fatalf("normalizeModel(lmstudio) = %q, want %q", got, "openai/gpt-oss-20b")
|
t.Fatalf("normalizeModel(lmstudio) = %q, want %q", got, "openai/gpt-oss-20b")
|
||||||
}
|
}
|
||||||
|
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("openrouter/auto", "https://openrouter.ai/api/v1"); got != "openrouter/auto" {
|
if got := normalizeModel("openrouter/auto", "https://openrouter.ai/api/v1"); got != "openrouter/auto" {
|
||||||
t.Fatalf("normalizeModel(openrouter) = %q, want %q", got, "openrouter/auto")
|
t.Fatalf("normalizeModel(openrouter) = %q, want %q", got, "openrouter/auto")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue