Files
promptkit/internal/backend/registry.go

77 lines
2.3 KiB
Go

// Package backend owns validated, immutable OpenAI-compatible backend
// definitions.
package backend
import (
"errors"
"fmt"
"gitea.maximumdirect.net/eric/promptkit/internal/domain"
)
const (
// OpenRouterID identifies the maintained OpenRouter backend.
OpenRouterID = "openrouter"
// RakestrawHomeID identifies the maintained Rakestrawhome backend.
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, error) {
registry := &Registry{backends: make(map[string]domain.Backend, len(definitions))}
for id, definition := range definitions {
definition.ID = id
cloned, err := domain.CloneBackend(definition)
if err != nil {
return nil, fmt.Errorf("backend %q: %w", id, err)
}
registry.backends[id] = cloned
}
return registry, nil
}
// 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)
}
cloned, err := domain.CloneBackend(definition)
if err != nil {
return domain.Backend{}, fmt.Errorf("copy backend %q: %w", id, err)
}
return cloned, 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
}