Files
gnoma/internal/provider/registry.go
vikingowl 85c643fdca feat: add foundation types, streaming, and provider interface
internal/message/ — Content discriminated union, Message, Usage,
StopReason, Response. 22 tests.

internal/stream/ — Stream pull-based iterator interface, Event types,
Accumulator (assembles Response from events). 8 tests.

internal/provider/ — Provider interface, Request, ToolDefinition,
Registry with factory pattern, ProviderError with HTTP status
classification. errors.AsType[E] for Go 1.26. 13 tests.

43 tests total, all passing.
2026-04-03 10:57:54 +02:00

70 lines
1.6 KiB
Go

package provider
import (
"fmt"
"sync"
)
// ProviderConfig is the common configuration for any provider.
type ProviderConfig struct {
Name string
APIKey string
BaseURL string // override for OpenAI-compat endpoints
Model string // default model for this provider
Options map[string]any // provider-specific options
}
// Factory creates a Provider from configuration.
type Factory func(cfg ProviderConfig) (Provider, error)
// Registry maps provider names to factory functions.
type Registry struct {
mu sync.RWMutex
factories map[string]Factory
}
func NewRegistry() *Registry {
return &Registry{
factories: make(map[string]Factory),
}
}
// Register adds a provider factory. Overwrites if name already exists.
func (r *Registry) Register(name string, f Factory) {
r.mu.Lock()
defer r.mu.Unlock()
r.factories[name] = f
}
// Create instantiates a provider by name with the given config.
func (r *Registry) Create(name string, cfg ProviderConfig) (Provider, error) {
r.mu.RLock()
f, ok := r.factories[name]
r.mu.RUnlock()
if !ok {
return nil, fmt.Errorf("unknown provider: %q", name)
}
cfg.Name = name
return f(cfg)
}
// Has returns true if a factory is registered for the given name.
func (r *Registry) Has(name string) bool {
r.mu.RLock()
defer r.mu.RUnlock()
_, ok := r.factories[name]
return ok
}
// Names returns all registered provider names.
func (r *Registry) Names() []string {
r.mu.RLock()
defer r.mu.RUnlock()
names := make([]string, 0, len(r.factories))
for name := range r.factories {
names = append(names, name)
}
return names
}