Files

91 lines
2.8 KiB
Go

package providerresolve
import (
"fmt"
"github.com/nextlevelbuilder/goclaw/internal/providers"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
// ResolveConfiguredProvider resolves the provider an agent should actually use.
// It applies ChatGPT OAuth routing from the promoted agent routing field when present.
func ResolveConfiguredProvider(registry *providers.Registry, agent *store.AgentData) (providers.Provider, error) {
if registry == nil || agent == nil {
return nil, fmt.Errorf("provider registry unavailable")
}
baseProvider, baseErr := registry.GetForTenant(agent.TenantID, agent.Provider)
if baseErr == nil {
if _, ok := baseProvider.(*providers.CodexProvider); !ok {
return baseProvider, nil
}
}
var providerDefaults *store.ChatGPTOAuthRoutingConfig
if codex, ok := baseProvider.(*providers.CodexProvider); ok {
if defaults := codex.RoutingDefaults(); defaults != nil {
providerDefaults = &store.ChatGPTOAuthRoutingConfig{
Strategy: defaults.Strategy,
ExtraProviderNames: defaults.ExtraProviderNames,
}
}
}
if routing := store.ResolveEffectiveChatGPTOAuthRouting(providerDefaults, agent.ParseChatGPTOAuthRouting()); routing != nil {
router := providers.NewChatGPTOAuthRouter(
agent.TenantID,
registry,
agent.Provider,
routing.Strategy,
routing.ExtraProviderNames,
)
if router != nil && router.HasRegisteredProviders() {
return router, nil
}
}
if baseErr == nil {
return baseProvider, nil
}
return nil, baseErr
}
// ResolveAgentProvider resolves the agent runtime provider, including generic
// per-agent model fallback when configured.
func ResolveAgentProvider(registry *providers.Registry, agent *store.AgentData) (providers.Provider, error) {
baseProvider, err := ResolveConfiguredProvider(registry, agent)
if err != nil {
return nil, err
}
if registry == nil || agent == nil {
return baseProvider, nil
}
fallbackCfg := agent.ParseModelFallback()
if fallbackCfg == nil {
return baseProvider, nil
}
candidates := make([]providers.FallbackCandidate, 0, len(fallbackCfg.Candidates))
for _, candidate := range fallbackCfg.Candidates {
provider, err := registry.GetForTenant(agent.TenantID, candidate.Provider)
if err != nil || provider == nil {
continue
}
candidates = append(candidates, providers.FallbackCandidate{
ProviderName: candidate.Provider,
Model: candidate.Model,
Provider: provider,
})
}
if len(candidates) == 0 {
return baseProvider, nil
}
cooldownEnabled := true
if fallbackCfg.CooldownEnabled != nil {
cooldownEnabled = *fallbackCfg.CooldownEnabled
}
return providers.NewModelFallbackProvider(providers.FallbackCandidate{
ProviderName: agent.Provider,
Model: agent.Model,
Provider: baseProvider,
}, candidates, fallbackCfg.MaxAttempts, cooldownEnabled), nil
}