package provider import ( "fmt" "sort" "llm-gateway/internal/config" ) // Route maps a model to a specific provider with pricing. type Route struct { Provider Provider ProviderModel string Priority int InputPrice float64 // per 1M tokens OutputPrice float64 // per 1M tokens } // Registry maps model names to provider routes. type Registry struct { routes map[string][]Route order []string // preserves config order } func NewRegistry(cfg *config.Config) (*Registry, error) { // Build providers providers := make(map[string]Provider) for _, pc := range cfg.Providers { providers[pc.Name] = NewOpenAIProvider(pc.Name, pc.BaseURL, pc.APIKey, pc.Timeout) } // Build routes (preserving config order) routes := make(map[string][]Route) order := make([]string, 0, len(cfg.Models)) for _, mc := range cfg.Models { var modelRoutes []Route for _, rc := range mc.Routes { p, ok := providers[rc.Provider] if !ok { return nil, fmt.Errorf("model %s: unknown provider %s", mc.Name, rc.Provider) } pc := cfg.ProviderByName(rc.Provider) priority := pc.Priority modelRoutes = append(modelRoutes, Route{ Provider: p, ProviderModel: rc.Model, Priority: priority, InputPrice: rc.Pricing.Input, OutputPrice: rc.Pricing.Output, }) } // Sort by priority (lower = higher priority) sort.Slice(modelRoutes, func(i, j int) bool { return modelRoutes[i].Priority < modelRoutes[j].Priority }) routes[mc.Name] = modelRoutes order = append(order, mc.Name) } return &Registry{routes: routes, order: order}, nil } // Lookup returns the routes for a model name. func (r *Registry) Lookup(model string) ([]Route, bool) { routes, ok := r.routes[model] return routes, ok } // ModelNames returns all registered model names in config order. func (r *Registry) ModelNames() []string { return r.order }