82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
package textgen
|
|
|
|
import "log/slog"
|
|
|
|
// Provider Ordering Strategy
|
|
//
|
|
// Production ordering: LaoZhang (primary) -> Gemini (terminus)
|
|
//
|
|
// LaoZhang is primary because:
|
|
// - Pay-per-use pricing, no hard daily limits
|
|
// - More predictable availability for production traffic
|
|
// - Gemini's unpredictable quota exhaustion would frustrate users
|
|
// - Cost is acceptable for revenue-generating features
|
|
//
|
|
// Gemini is terminus because:
|
|
// - Daily quota limits (resets at midnight PT)
|
|
// - Free tier was reduced ~92% in December 2025
|
|
// - Terminus is ALWAYS tried regardless of cooldown
|
|
//
|
|
// The fallback strategy ensures requests succeed when possible.
|
|
|
|
// ProviderSet holds text providers for easy configuration.
|
|
type ProviderSet struct {
|
|
LaoZhang TextGenerator
|
|
Gemini TextGenerator
|
|
}
|
|
|
|
// ProductionConfig returns a ManagerConfig optimized for production workloads.
|
|
//
|
|
// Primary: LaoZhang (reliable pay-per-use)
|
|
// Terminus: Gemini (may fail on quota, but always tried as last resort)
|
|
//
|
|
// Use this for:
|
|
// - User-initiated text generation
|
|
// - Production API endpoints
|
|
// - Any feature where reliability matters more than cost
|
|
func ProductionConfig(providers ProviderSet, opts ...ConfigOption) ManagerConfig {
|
|
textProviders := []TextGenerator{}
|
|
|
|
// Build provider list in order: LaoZhang -> Gemini (terminus)
|
|
if providers.LaoZhang != nil {
|
|
textProviders = append(textProviders, providers.LaoZhang)
|
|
}
|
|
if providers.Gemini != nil {
|
|
textProviders = append(textProviders, providers.Gemini)
|
|
}
|
|
|
|
cfg := ManagerConfig{
|
|
Providers: textProviders,
|
|
Strategy: StrategyFallback,
|
|
}
|
|
for _, opt := range opts {
|
|
opt(&cfg)
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
// ConfigOption allows customizing preset configurations.
|
|
type ConfigOption func(*ManagerConfig)
|
|
|
|
// WithLogger sets a custom logger.
|
|
func WithLogger(logger *slog.Logger) ConfigOption {
|
|
return func(cfg *ManagerConfig) {
|
|
cfg.Logger = logger
|
|
}
|
|
}
|
|
|
|
// WithMetrics sets a metrics hook for observability.
|
|
func WithMetrics(hook MetricsHook) ConfigOption {
|
|
return func(cfg *ManagerConfig) {
|
|
cfg.OnMetrics = hook
|
|
}
|
|
}
|
|
|
|
// WithStrategy overrides the default fallback strategy.
|
|
// Use sparingly - the presets use StrategyFallback for a reason.
|
|
func WithStrategy(strategy Strategy) ConfigOption {
|
|
return func(cfg *ManagerConfig) {
|
|
cfg.Strategy = strategy
|
|
}
|
|
}
|