ollie/backend/new.go

127 lines
2.9 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]
var b Backend
var err error
switch which {
case "ollama":
host := bc.Host
if host == "" {
host = os.Getenv("OLLAMA_HOST")
}
b, err = NewOllama(host)
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)
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)
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)
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)
case "kiro", "codewhisperer":
token := bc.Key
if token == "" {
token = os.Getenv("OLLIE_KIRO_TOKEN")
}
b, err = NewKiro(token)
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)
default:
return nil, fmt.Errorf("unknown backend %q (supported: ollama, openai, openrouter, anthropic, copilot, kiro, gemini)", which)
}
if err != nil {
return nil, err
}
if bc.Model != "" {
b.SetModel(bc.Model)
}
return b, nil
}
// Backends returns the list of supported backend names.
func Backends() []string {
return []string{"ollama", "openai", "openrouter", "anthropic", "copilot", "kiro", "gemini"}
}