feat(providers): add Novita AI as new LLM provider (#444)

Add Novita AI as a new LLM provider with OpenAI-compatible API endpoint.

- Add ProviderNovita constant and valid type entry
- Add Novita to ProvidersConfig with APIBaseForType and HasAnyProvider
- Register Novita provider in gateway startup (config and DB paths)
- Add Novita case in HTTP handler's registerInMemory
- Add Novita to UI provider selection dropdown

Default model: moonshotai/kimi-k2.5
Default endpoint: https://api.novita.ai/openai
This commit is contained in:
Alex authored and GitHub committed 2026-03-29 10:15:14 +07:00
1 parent 0c6cd02285
commit bd1411028b
5 files changed
+30 -1

No files matched your search

+16
View File
@@ -136,6 +136,16 @@ func registerProviders(registry *providers.Registry, cfg *config.Config) {
slog.Info("registered provider", "name", "ollama-cloud")
}
// Novita AI — OpenAI-compatible endpoint.
if cfg.Providers.Novita.APIKey != "" {
base := cfg.Providers.Novita.APIBase
if base == "" {
base = "https://api.novita.ai/openai"
}
registry.Register(providers.NewOpenAIProvider("novita", cfg.Providers.Novita.APIKey, base, "moonshotai/kimi-k2.5"))
slog.Info("registered provider", "name", "novita")
}
// Claude CLI provider (subscription-based, no API key needed)
if cfg.Providers.ClaudeCLI.CLIPath != "" {
cliPath := cfg.Providers.ClaudeCLI.CLIPath
@@ -341,6 +351,12 @@ func registerProvidersFromDB(registry *providers.Registry, provStore store.Provi
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, base, "")
prov.WithProviderType(p.ProviderType)
registry.RegisterForTenant(p.TenantID, prov)
case store.ProviderNovita:
base := p.APIBase
if base == "" {
base = "https://api.novita.ai/openai"
}
registry.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, "moonshotai/kimi-k2.5"))
default:
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, p.APIBase, "")
prov.WithProviderType(p.ProviderType)
+5 -1
View File
@@ -213,6 +213,7 @@ type ProvidersConfig struct {
OllamaCloud ProviderConfig `json:"ollama_cloud"` // Ollama Cloud (API key required)
ClaudeCLI ClaudeCLIConfig `json:"claude_cli"`
ACP ACPConfig `json:"acp"`
Novita ProviderConfig `json:"novita"` // Novita AI (OpenAI-compatible endpoint)
}
// OllamaConfig configures a local (or self-hosted) Ollama instance.
@@ -281,6 +282,8 @@ func (p *ProvidersConfig) APIBaseForType(providerType string) string {
return p.ZaiCoding.APIBase
case "ollama_cloud":
return p.OllamaCloud.APIBase
case "novita":
return p.Novita.APIBase
default:
return ""
}
@@ -307,7 +310,8 @@ func (c *Config) HasAnyProvider() bool {
p.Ollama.Host != "" ||
p.OllamaCloud.APIKey != "" ||
p.ClaudeCLI.CLIPath != "" ||
p.ACP.Binary != ""
p.ACP.Binary != "" ||
p.Novita.APIKey != ""
}
// QuotaWindow defines request limits per time window. Zero means unlimited.
+6
View File
@@ -176,6 +176,12 @@ func (h *ProvidersHandler) registerInMemory(p *store.LLMProviderData) {
base = "https://coding-intl.dashscope.aliyuncs.com/v1"
}
h.providerReg.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, "qwen3.5-plus"))
case store.ProviderNovita:
base := apiBase
if base == "" {
base = "https://api.novita.ai/openai"
}
h.providerReg.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, "moonshotai/kimi-k2.5"))
default:
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, apiBase, "")
if p.ProviderType == store.ProviderMiniMax {
+2
View File
@@ -31,6 +31,7 @@ const (
ProviderOllama = "ollama" // local or self-hosted Ollama (no API key)
ProviderOllamaCloud = "ollama_cloud" // Ollama Cloud (Bearer token required)
ProviderACP = "acp" // ACP (Agent Client Protocol) agent subprocess
ProviderNovita = "novita" // Novita AI (OpenAI-compatible endpoint)
)
// ValidProviderTypes lists all accepted provider_type values.
@@ -57,6 +58,7 @@ var ValidProviderTypes = map[string]bool{
ProviderOllama: true,
ProviderOllamaCloud: true,
ProviderACP: true,
ProviderNovita: true,
}
// LLMProviderData represents an LLM provider configuration.
+1
View File
@@ -22,6 +22,7 @@ export const PROVIDER_TYPES: ProviderTypeInfo[] = [
{ value: "mistral", label: "Mistral AI", apiBase: "https://api.mistral.ai/v1", placeholder: "" },
{ value: "xai", label: "xAI (Grok)", apiBase: "https://api.x.ai/v1", placeholder: "" },
{ value: "minimax_native", label: "MiniMax (Native)", apiBase: "https://api.minimax.io/v1", placeholder: "" },
{ value: "novita", label: "Novita AI", apiBase: "https://api.novita.ai/openai", placeholder: "" },
{ value: "cohere", label: "Cohere", apiBase: "https://api.cohere.ai/compatibility/v1", placeholder: "" },
{ value: "perplexity", label: "Perplexity", apiBase: "https://api.perplexity.ai", placeholder: "" },
{ value: "dashscope", label: "DashScope (Qwen)", apiBase: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", placeholder: "" },