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.
This commit is contained in:
Vishnuvardhan Reddy 2026-02-26 10:40:08 +00:00
parent 8a1fb03974
commit 583dc06424
3 changed files with 23 additions and 11 deletions

View file

@ -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.

View file

@ -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

View file

@ -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)
}
}