165 lines
3.5 KiB
Go
165 lines
3.5 KiB
Go
package backend
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
// NewWithName constructs a Backend for the given backend name.
|
|
// If name is empty, falls back to backends.conf default, then OLLIE_BACKEND env.
|
|
func NewWithName(name string) (Backend, error) {
|
|
cfg := loadConfig()
|
|
if name == "" {
|
|
name = cfg.Default
|
|
}
|
|
if name == "" {
|
|
name = os.Getenv("OLLIE_BACKEND")
|
|
}
|
|
if name == "" {
|
|
return nil, fmt.Errorf("no backend specified: set 'backend' in backends.conf, OLLIE_BACKEND, or pass backend= to the session")
|
|
}
|
|
return newBackendFromConfig(name, cfg)
|
|
}
|
|
|
|
func newBackend(which string) (Backend, error) {
|
|
return newBackendFromConfig(which, loadConfig())
|
|
}
|
|
|
|
func newBackendFromConfig(which string, cfg configFile) (Backend, error) {
|
|
bc := cfg.Backends[which]
|
|
|
|
switch which {
|
|
case "ollama":
|
|
host := bc.Host
|
|
if host == "" {
|
|
host = os.Getenv("OLLAMA_HOST")
|
|
}
|
|
b, err := NewOllama(host)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
case "openai":
|
|
url := bc.URL
|
|
if url == "" {
|
|
url = os.Getenv("OLLIE_OPENAI_URL")
|
|
}
|
|
key := bc.Key
|
|
if key == "" {
|
|
key = os.Getenv("OLLIE_OPENAI_KEY")
|
|
}
|
|
if key == "" {
|
|
return nil, fmt.Errorf("openai: key required (backends.conf [openai] key= or OLLIE_OPENAI_KEY)")
|
|
}
|
|
b, err := NewOpenAI("openai", url, key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
case "openrouter":
|
|
url := bc.URL
|
|
if url == "" {
|
|
url = os.Getenv("OLLIE_OPENAI_URL")
|
|
}
|
|
if url == "" {
|
|
url = "https://openrouter.ai/api"
|
|
}
|
|
key := bc.Key
|
|
if key == "" {
|
|
key = os.Getenv("OLLIE_OPENAI_KEY")
|
|
}
|
|
if key == "" {
|
|
return nil, fmt.Errorf("openrouter: key required (backends.conf [openrouter] key= or OLLIE_OPENAI_KEY)")
|
|
}
|
|
b, err := NewOpenAI("openrouter", url, key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
case "anthropic":
|
|
key := bc.Key
|
|
if key == "" {
|
|
key = os.Getenv("OLLIE_ANTHROPIC_KEY")
|
|
}
|
|
if key == "" {
|
|
return nil, fmt.Errorf("anthropic: key required (backends.conf [anthropic] key= or OLLIE_ANTHROPIC_KEY)")
|
|
}
|
|
b, err := NewAnthropic(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
case "copilot":
|
|
token := bc.Key
|
|
if token == "" {
|
|
token = os.Getenv("OLLIE_COPILOT_TOKEN")
|
|
}
|
|
if token == "" {
|
|
return nil, fmt.Errorf("copilot: key required (backends.conf [copilot] key= or OLLIE_COPILOT_TOKEN)")
|
|
}
|
|
b, err := NewCopilot(token)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
case "kiro", "codewhisperer":
|
|
token := bc.Key
|
|
if token == "" {
|
|
token = os.Getenv("OLLIE_KIRO_TOKEN")
|
|
}
|
|
b, err := NewCodeWhisperer(token)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
case "gemini":
|
|
key := bc.Key
|
|
if key == "" {
|
|
key = os.Getenv("OLLIE_GEMINI_KEY")
|
|
}
|
|
if key == "" {
|
|
return nil, fmt.Errorf("gemini: key required (backends.conf [gemini] key= or OLLIE_GEMINI_KEY)")
|
|
}
|
|
b, err := NewGemini(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if bc.Model != "" {
|
|
b.SetModel(bc.Model)
|
|
}
|
|
return b, nil
|
|
|
|
default:
|
|
return nil, fmt.Errorf("unknown backend %q (supported: ollama, openai, openrouter, anthropic, copilot, kiro, gemini)", which)
|
|
}
|
|
}
|
|
|
|
// Backends returns the list of supported backend names.
|
|
func Backends() []string {
|
|
return []string{"ollama", "openai", "openrouter", "anthropic", "copilot", "kiro", "gemini"}
|
|
}
|