diff --git a/internal/providers/config.go b/internal/providers/config.go index c2d468da..dd2a5bfc 100644 --- a/internal/providers/config.go +++ b/internal/providers/config.go @@ -580,8 +580,8 @@ func isVertexProviderConfig(p config.RawProviderConfig) bool { } func validVertexProviderConfig(p config.RawProviderConfig) bool { - if !hasResolvedProviderValue(p.BaseURL) && - (!hasResolvedProviderValue(p.VertexProject) || !hasResolvedProviderValue(p.VertexLocation)) { + if !HasResolvedProviderValue(p.BaseURL) && + (!HasResolvedProviderValue(p.VertexProject) || !HasResolvedProviderValue(p.VertexLocation)) { return false } authType := strings.ToLower(strings.TrimSpace(p.AuthType)) @@ -589,15 +589,21 @@ func validVertexProviderConfig(p config.RawProviderConfig) bool { case "", "gcp_adc", "adc", "google_adc": return true case "gcp_service_account", "service_account": - return hasResolvedProviderValue(p.ServiceAccountFile) || - hasResolvedProviderValue(p.ServiceAccountJSON) || - hasResolvedProviderValue(p.ServiceAccountJSONBase64) + return HasResolvedProviderValue(p.ServiceAccountFile) || + HasResolvedProviderValue(p.ServiceAccountJSON) || + HasResolvedProviderValue(p.ServiceAccountJSONBase64) default: return false } } -func hasResolvedProviderValue(value string) bool { +// HasResolvedProviderValue reports whether a provider-config field carries a +// usable string value. It returns false for empty/whitespace input and false +// when the value still contains a literal `${` substring — that signals an +// unresolved YAML environment-variable placeholder such as `${OPENAI_API_KEY}` +// which the env-substitution pass failed to fill in. Provider builders use +// this to drop providers whose credentials never resolved. +func HasResolvedProviderValue(value string) bool { value = strings.TrimSpace(value) return value != "" && !strings.Contains(value, "${") } diff --git a/internal/providers/gemini/gemini.go b/internal/providers/gemini/gemini.go index 828c76de..ce8e3fc5 100644 --- a/internal/providers/gemini/gemini.go +++ b/internal/providers/gemini/gemini.go @@ -172,8 +172,8 @@ func (p *Provider) validateConfig(providerCfg providers.ProviderConfig) { p.configErr = fmt.Errorf("vertex Gemini requires gcp_adc or gcp_service_account auth") return } - if p.backend == geminiBackendVertex && !hasResolvedProviderValue(providerCfg.BaseURL) && - (!hasResolvedProviderValue(providerCfg.VertexProject) || !hasResolvedProviderValue(providerCfg.VertexLocation)) { + if p.backend == geminiBackendVertex && !providers.HasResolvedProviderValue(providerCfg.BaseURL) && + (!providers.HasResolvedProviderValue(providerCfg.VertexProject) || !providers.HasResolvedProviderValue(providerCfg.VertexLocation)) { p.configErr = fmt.Errorf("vertex Gemini requires base_url or vertex_project and vertex_location") return } @@ -263,11 +263,6 @@ func normalizeGeminiBackend(cfg providers.ProviderConfig) string { return geminiBackendAIStudio } -func hasResolvedProviderValue(value string) bool { - value = strings.TrimSpace(value) - return value != "" && !strings.Contains(value, "${") -} - func normalizeGeminiAuthType(backend string, cfg providers.ProviderConfig) string { authType := strings.ToLower(strings.TrimSpace(cfg.AuthType)) switch authType { diff --git a/internal/providers/vertex/vertex.go b/internal/providers/vertex/vertex.go index 7ffb6144..b5f8091c 100644 --- a/internal/providers/vertex/vertex.go +++ b/internal/providers/vertex/vertex.go @@ -75,8 +75,8 @@ func newProvider(providerCfg providers.ProviderConfig, opts providers.ProviderOp } func (p *Provider) validateConfig(providerCfg providers.ProviderConfig) { - if !hasResolvedProviderValue(providerCfg.BaseURL) && - (!hasResolvedProviderValue(providerCfg.VertexProject) || !hasResolvedProviderValue(providerCfg.VertexLocation)) { + if !providers.HasResolvedProviderValue(providerCfg.BaseURL) && + (!providers.HasResolvedProviderValue(providerCfg.VertexProject) || !providers.HasResolvedProviderValue(providerCfg.VertexLocation)) { p.configErr = fmt.Errorf("vertex AI requires base_url or vertex_project and vertex_location") return } @@ -106,11 +106,6 @@ func validAuthType(authType string) bool { } } -func hasResolvedProviderValue(value string) bool { - value = strings.TrimSpace(value) - return value != "" && !strings.Contains(value, "${") -} - func normalizeAuthType(providerCfg providers.ProviderConfig) string { return googleauth.NormalizeAuthType(providerCfg.AuthType, googleauth.HasServiceAccount(buildGoogleAuthConfig(providerCfg))) }