// Package backend owns validated, immutable OpenAI-compatible backend // definitions. package backend import ( "errors" "fmt" "go.maximumdirect.net/promptkit/internal/domain" ) const ( // OpenRouterID is the conventional OpenRouter backend identifier. OpenRouterID = "openrouter" // RakestrawHomeID is the conventional Rakestrawhome backend identifier. RakestrawHomeID = "rakestrawhome" ) // ErrBackendNotFound identifies a registry lookup for an unknown backend ID. var ErrBackendNotFound = errors.New("backend not found") // Registry is an immutable collection of validated backend definitions. type Registry struct { backends map[string]domain.Backend } // NewEffectiveRegistry stores already-validated effective backend definitions // under their exact configuration keys. Configuration validation and // normalization precede this ownership boundary. func NewEffectiveRegistry(definitions map[string]domain.Backend) *Registry { registry := &Registry{backends: make(map[string]domain.Backend, len(definitions))} for id, definition := range definitions { definition.ID = id registry.backends[id] = domain.CloneBackend(definition) } return registry } // GetBackend returns a defensive copy of the backend registered with id. func (r *Registry) GetBackend(id string) (domain.Backend, error) { if r == nil { return domain.Backend{}, fmt.Errorf("%w: %q", ErrBackendNotFound, id) } definition, ok := r.backends[id] if !ok { return domain.Backend{}, fmt.Errorf("%w: %q", ErrBackendNotFound, id) } return domain.CloneBackend(definition), nil } // CapacityPolicies returns a copy of the normalized policies for limited // backends. func (r *Registry) CapacityPolicies() map[string]domain.BackendCapacityPolicy { policies := make(map[string]domain.BackendCapacityPolicy) if r == nil { return policies } for id, definition := range r.backends { if definition.ConcurrencyLimit == 0 { continue } policies[id] = domain.BackendCapacityPolicy{ ConcurrencyLimit: definition.ConcurrencyLimit, QueueCapacity: definition.QueueCapacity, } } return policies }