Merge pull request #844 from avianion/feat/add-avian-provider
feat: add Avian as a named LLM provider
This commit is contained in:
commit
325af2163b
7 changed files with 61 additions and 5 deletions
|
|
@ -224,6 +224,10 @@
|
||||||
"mistral": {
|
"mistral": {
|
||||||
"api_key": "",
|
"api_key": "",
|
||||||
"api_base": "https://api.mistral.ai/v1"
|
"api_base": "https://api.mistral.ai/v1"
|
||||||
|
},
|
||||||
|
"avian": {
|
||||||
|
"api_key": "",
|
||||||
|
"api_base": "https://api.avian.io/v1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
|
|
|
||||||
|
|
@ -431,6 +431,7 @@ type ProvidersConfig struct {
|
||||||
Antigravity ProviderConfig `json:"antigravity"`
|
Antigravity ProviderConfig `json:"antigravity"`
|
||||||
Qwen ProviderConfig `json:"qwen"`
|
Qwen ProviderConfig `json:"qwen"`
|
||||||
Mistral ProviderConfig `json:"mistral"`
|
Mistral ProviderConfig `json:"mistral"`
|
||||||
|
Avian ProviderConfig `json:"avian"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty checks if all provider configs are empty (no API keys or API bases set)
|
// IsEmpty checks if all provider configs are empty (no API keys or API bases set)
|
||||||
|
|
@ -454,7 +455,8 @@ func (p ProvidersConfig) IsEmpty() bool {
|
||||||
p.GitHubCopilot.APIKey == "" && p.GitHubCopilot.APIBase == "" &&
|
p.GitHubCopilot.APIKey == "" && p.GitHubCopilot.APIBase == "" &&
|
||||||
p.Antigravity.APIKey == "" && p.Antigravity.APIBase == "" &&
|
p.Antigravity.APIKey == "" && p.Antigravity.APIBase == "" &&
|
||||||
p.Qwen.APIKey == "" && p.Qwen.APIBase == "" &&
|
p.Qwen.APIKey == "" && p.Qwen.APIBase == "" &&
|
||||||
p.Mistral.APIKey == "" && p.Mistral.APIBase == ""
|
p.Mistral.APIKey == "" && p.Mistral.APIBase == "" &&
|
||||||
|
p.Avian.APIKey == "" && p.Avian.APIBase == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements custom JSON marshaling for ProvidersConfig
|
// MarshalJSON implements custom JSON marshaling for ProvidersConfig
|
||||||
|
|
|
||||||
|
|
@ -308,6 +308,20 @@ func DefaultConfig() *Config {
|
||||||
APIKey: "",
|
APIKey: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Avian - https://avian.io
|
||||||
|
{
|
||||||
|
ModelName: "deepseek-v3.2",
|
||||||
|
Model: "avian/deepseek/deepseek-v3.2",
|
||||||
|
APIBase: "https://api.avian.io/v1",
|
||||||
|
APIKey: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ModelName: "kimi-k2.5",
|
||||||
|
Model: "avian/moonshotai/kimi-k2.5",
|
||||||
|
APIBase: "https://api.avian.io/v1",
|
||||||
|
APIKey: "",
|
||||||
|
},
|
||||||
|
|
||||||
// VLLM (local) - http://localhost:8000
|
// VLLM (local) - http://localhost:8000
|
||||||
{
|
{
|
||||||
ModelName: "local-model",
|
ModelName: "local-model",
|
||||||
|
|
|
||||||
|
|
@ -373,6 +373,23 @@ func ConvertProvidersToModelList(cfg *Config) []ModelConfig {
|
||||||
}, true
|
}, true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
providerNames: []string{"avian"},
|
||||||
|
protocol: "avian",
|
||||||
|
buildConfig: func(p ProvidersConfig) (ModelConfig, bool) {
|
||||||
|
if p.Avian.APIKey == "" && p.Avian.APIBase == "" {
|
||||||
|
return ModelConfig{}, false
|
||||||
|
}
|
||||||
|
return ModelConfig{
|
||||||
|
ModelName: "avian",
|
||||||
|
Model: "avian/deepseek/deepseek-v3.2",
|
||||||
|
APIKey: p.Avian.APIKey,
|
||||||
|
APIBase: p.Avian.APIBase,
|
||||||
|
Proxy: p.Avian.Proxy,
|
||||||
|
RequestTimeout: p.Avian.RequestTimeout,
|
||||||
|
}, true
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process each provider migration
|
// Process each provider migration
|
||||||
|
|
|
||||||
|
|
@ -160,14 +160,15 @@ func TestConvertProvidersToModelList_AllProviders(t *testing.T) {
|
||||||
Antigravity: ProviderConfig{AuthMethod: "oauth"},
|
Antigravity: ProviderConfig{AuthMethod: "oauth"},
|
||||||
Qwen: ProviderConfig{APIKey: "key17"},
|
Qwen: ProviderConfig{APIKey: "key17"},
|
||||||
Mistral: ProviderConfig{APIKey: "key18"},
|
Mistral: ProviderConfig{APIKey: "key18"},
|
||||||
|
Avian: ProviderConfig{APIKey: "key19"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
result := ConvertProvidersToModelList(cfg)
|
result := ConvertProvidersToModelList(cfg)
|
||||||
|
|
||||||
// All 19 providers should be converted
|
// All 20 providers should be converted
|
||||||
if len(result) != 19 {
|
if len(result) != 20 {
|
||||||
t.Errorf("len(result) = %d, want 19", len(result))
|
t.Errorf("len(result) = %d, want 20", len(result))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,15 @@ func resolveProviderSelection(cfg *config.Config) (providerSelection, error) {
|
||||||
sel.model = "deepseek-chat"
|
sel.model = "deepseek-chat"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "avian":
|
||||||
|
if cfg.Providers.Avian.APIKey != "" {
|
||||||
|
sel.apiKey = cfg.Providers.Avian.APIKey
|
||||||
|
sel.apiBase = cfg.Providers.Avian.APIBase
|
||||||
|
sel.proxy = cfg.Providers.Avian.Proxy
|
||||||
|
if sel.apiBase == "" {
|
||||||
|
sel.apiBase = "https://api.avian.io/v1"
|
||||||
|
}
|
||||||
|
}
|
||||||
case "mistral":
|
case "mistral":
|
||||||
if cfg.Providers.Mistral.APIKey != "" {
|
if cfg.Providers.Mistral.APIKey != "" {
|
||||||
sel.apiKey = cfg.Providers.Mistral.APIKey
|
sel.apiKey = cfg.Providers.Mistral.APIKey
|
||||||
|
|
@ -300,6 +309,13 @@ func resolveProviderSelection(cfg *config.Config) (providerSelection, error) {
|
||||||
if sel.apiBase == "" {
|
if sel.apiBase == "" {
|
||||||
sel.apiBase = "https://api.mistral.ai/v1"
|
sel.apiBase = "https://api.mistral.ai/v1"
|
||||||
}
|
}
|
||||||
|
case strings.HasPrefix(model, "avian/") && cfg.Providers.Avian.APIKey != "":
|
||||||
|
sel.apiKey = cfg.Providers.Avian.APIKey
|
||||||
|
sel.apiBase = cfg.Providers.Avian.APIBase
|
||||||
|
sel.proxy = cfg.Providers.Avian.Proxy
|
||||||
|
if sel.apiBase == "" {
|
||||||
|
sel.apiBase = "https://api.avian.io/v1"
|
||||||
|
}
|
||||||
case cfg.Providers.VLLM.APIBase != "":
|
case cfg.Providers.VLLM.APIBase != "":
|
||||||
sel.apiKey = cfg.Providers.VLLM.APIKey
|
sel.apiKey = cfg.Providers.VLLM.APIKey
|
||||||
sel.apiBase = cfg.Providers.VLLM.APIBase
|
sel.apiBase = cfg.Providers.VLLM.APIBase
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
|
|
||||||
case "litellm", "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
case "litellm", "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
||||||
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
||||||
"volcengine", "vllm", "qwen", "mistral":
|
"volcengine", "vllm", "qwen", "mistral", "avian":
|
||||||
// All other OpenAI-compatible HTTP providers
|
// All other OpenAI-compatible HTTP providers
|
||||||
if cfg.APIKey == "" && cfg.APIBase == "" {
|
if cfg.APIKey == "" && cfg.APIBase == "" {
|
||||||
return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol)
|
return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol)
|
||||||
|
|
@ -208,6 +208,8 @@ func getDefaultAPIBase(protocol string) string {
|
||||||
return "http://localhost:8000/v1"
|
return "http://localhost:8000/v1"
|
||||||
case "mistral":
|
case "mistral":
|
||||||
return "https://api.mistral.ai/v1"
|
return "https://api.mistral.ai/v1"
|
||||||
|
case "avian":
|
||||||
|
return "https://api.avian.io/v1"
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue