package providers import ( "fmt" "sync" ) // registry holds all registered providers. var ( registry = make(map[string]Provider) mu sync.RWMutex ) // Register adds a provider to the registry. func Register(p Provider) { mu.Lock() defer mu.Unlock() registry[p.ID()] = p } // Get returns a provider by ID. func Get(id string) (Provider, error) { mu.RLock() defer mu.RUnlock() p, ok := registry[id] if !ok { return nil, fmt.Errorf("unknown provider: %s", id) } return p, nil } // List returns all registered provider IDs. func List() []string { mu.RLock() defer mu.RUnlock() ids := make([]string, 0, len(registry)) for id := range registry { ids = append(ids, id) } return ids } // ── Provider Type Metadata ────────────────── // ProviderTypeMeta describes a registered provider type for the admin API. type ProviderTypeMeta struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description"` DefaultEndpoint string `json:"default_endpoint"` ProfileSchema ProfileSchema `json:"profile_schema"` } var providerTypes = map[string]ProviderTypeMeta{} // RegisterType adds a provider type with its metadata to the type registry. // Called by Init() for built-in types. External types can be registered at startup. func RegisterType(meta ProviderTypeMeta, p Provider) { mu.Lock() defer mu.Unlock() registry[meta.ID] = p providerTypes[meta.ID] = meta } // ListTypes returns metadata for all registered provider types. func ListTypes() []ProviderTypeMeta { mu.RLock() defer mu.RUnlock() out := make([]ProviderTypeMeta, 0, len(providerTypes)) for _, m := range providerTypes { out = append(out, m) } return out } // Init registers all built-in providers. func Init() { RegisterType(ProviderTypeMeta{ ID: "openai", Name: "OpenAI", Description: "OpenAI and any OpenAI-compatible API (Ollama, LiteLLM, etc.)", DefaultEndpoint: "https://api.openai.com/v1", ProfileSchema: GetProfileSchema("openai"), }, &OpenAIProvider{}) RegisterType(ProviderTypeMeta{ ID: "anthropic", Name: "Anthropic", Description: "Anthropic Messages API (Claude models)", DefaultEndpoint: "https://api.anthropic.com", ProfileSchema: GetProfileSchema("anthropic"), }, &AnthropicProvider{}) RegisterType(ProviderTypeMeta{ ID: "venice", Name: "Venice", Description: "Venice.ai — privacy-focused, OpenAI-compatible with extensions", DefaultEndpoint: "https://api.venice.ai/api/v1", ProfileSchema: GetProfileSchema("venice"), }, &VeniceProvider{}) RegisterType(ProviderTypeMeta{ ID: "openrouter", Name: "OpenRouter", Description: "OpenRouter — unified API for 300+ models with per-model pricing", DefaultEndpoint: "https://openrouter.ai/api/v1", ProfileSchema: GetProfileSchema("openrouter"), }, &OpenRouterProvider{}) }