From 583dc06424e49ed611c1a2bbd164d8cff685a935 Mon Sep 17 00:00:00 2001 From: Vishnuvardhan Reddy Date: Thu, 26 Feb 2026 10:40:08 +0000 Subject: [PATCH] fix(providers): validate antigravity credentials at provider creation Previously, NewAntigravityProvider() would create a provider even when OAuth credentials didn't exist, only failing when Chat() was called. This prevented the fallback mechanism from working correctly. Changes: - NewAntigravityProvider() now returns (*AntigravityProvider, error) - Validates credentials exist at creation time (not during Chat()) - Updated CreateProviderFromConfig() to handle the error - Updated test to expect credential validation error This ensures that when antigravity OAuth is logged out or credentials are missing, the provider creation fails immediately, allowing the fallback chain to try alternative models/providers. Fixes issue where gemini-flash model with expired antigravity OAuth would not fall back to other configured providers. --- pkg/providers/antigravity_provider.go | 13 +++++++++++-- pkg/providers/factory_provider.go | 6 +++++- pkg/providers/factory_provider_test.go | 15 +++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/pkg/providers/antigravity_provider.go b/pkg/providers/antigravity_provider.go index d4ee528b7..0e7608cc3 100644 --- a/pkg/providers/antigravity_provider.go +++ b/pkg/providers/antigravity_provider.go @@ -33,13 +33,22 @@ type AntigravityProvider struct { } // NewAntigravityProvider creates a new Antigravity provider using stored auth credentials. -func NewAntigravityProvider() *AntigravityProvider { +// Returns an error if credentials are not available or invalid. +func NewAntigravityProvider() (*AntigravityProvider, error) { + // Validate credentials exist before creating the provider + cred, err := getCredential("google-antigravity") + if err != nil { + return nil, fmt.Errorf("loading auth credentials: %w", err) + } + if cred == nil { + return nil, fmt.Errorf("no credentials for google-antigravity. Run: picoclaw auth login --provider google-antigravity") + } return &AntigravityProvider{ tokenSource: createAntigravityTokenSource(), httpClient: &http.Client{ Timeout: 120 * time.Second, }, - } + }, nil } // Chat implements LLMProvider.Chat using the Cloud Code Assist v1internal API. diff --git a/pkg/providers/factory_provider.go b/pkg/providers/factory_provider.go index 53f7a08a0..0e710ade5 100644 --- a/pkg/providers/factory_provider.go +++ b/pkg/providers/factory_provider.go @@ -137,7 +137,11 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err ), modelID, nil case "antigravity": - return NewAntigravityProvider(), modelID, nil + provider, err := NewAntigravityProvider() + if err != nil { + return nil, "", err + } + return provider, modelID, nil case "claude-cli", "claudecli": workspace := cfg.Workspace diff --git a/pkg/providers/factory_provider_test.go b/pkg/providers/factory_provider_test.go index e0c0eddef..74bbc2e5a 100644 --- a/pkg/providers/factory_provider_test.go +++ b/pkg/providers/factory_provider_test.go @@ -160,15 +160,14 @@ func TestCreateProviderFromConfig_Antigravity(t *testing.T) { Model: "antigravity/gemini-2.0-flash", } - provider, modelID, err := CreateProviderFromConfig(cfg) - if err != nil { - t.Fatalf("CreateProviderFromConfig() error = %v", err) + // Antigravity requires OAuth credentials, which should fail in test environment + _, _, err := CreateProviderFromConfig(cfg) + if err == nil { + t.Fatal("CreateProviderFromConfig() expected error for antigravity without credentials") } - if provider == nil { - t.Fatal("CreateProviderFromConfig() returned nil provider") - } - if modelID != "gemini-2.0-flash" { - t.Errorf("modelID = %q, want %q", modelID, "gemini-2.0-flash") + // Verify error message mentions credentials + if !strings.Contains(err.Error(), "credentials") && !strings.Contains(err.Error(), "auth") { + t.Errorf("Expected credential-related error, got: %v", err) } }