feat: proactive token refresh 10 minutes before expiry

Amp-Thread-ID: https://ampcode.com/threads/T-019bd618-7e42-715a-960d-dd45425851e3
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
781456868@qq.com
2026-01-19 20:09:38 +08:00
parent 87edc6f35e
commit f87fe0a0e8
2 changed files with 20 additions and 11 deletions
+10 -1
View File
@@ -217,6 +217,15 @@ func (s *FileTokenStore) readAuthFile(path, baseDir string) (*cliproxyauth.Auth,
return nil, fmt.Errorf("stat file: %w", err) return nil, fmt.Errorf("stat file: %w", err)
} }
id := s.idFor(path, baseDir) id := s.idFor(path, baseDir)
// Calculate NextRefreshAfter from expires_at (10 minutes before expiry)
var nextRefreshAfter time.Time
if expiresAtStr, ok := metadata["expires_at"].(string); ok && expiresAtStr != "" {
if expiresAt, err := time.Parse(time.RFC3339, expiresAtStr); err == nil {
nextRefreshAfter = expiresAt.Add(-10 * time.Minute)
}
}
auth := &cliproxyauth.Auth{ auth := &cliproxyauth.Auth{
ID: id, ID: id,
Provider: provider, Provider: provider,
@@ -228,7 +237,7 @@ func (s *FileTokenStore) readAuthFile(path, baseDir string) (*cliproxyauth.Auth,
CreatedAt: info.ModTime(), CreatedAt: info.ModTime(),
UpdatedAt: info.ModTime(), UpdatedAt: info.ModTime(),
LastRefreshedAt: time.Time{}, LastRefreshedAt: time.Time{},
NextRefreshAfter: time.Time{}, NextRefreshAfter: nextRefreshAfter,
} }
if email, ok := metadata["email"].(string); ok && email != "" { if email, ok := metadata["email"].(string); ok && email != "" {
auth.Attributes["email"] = email auth.Attributes["email"] = email
+10 -10
View File
@@ -52,9 +52,9 @@ func (a *KiroAuthenticator) Provider() string {
} }
// RefreshLead indicates how soon before expiry a refresh should be attempted. // RefreshLead indicates how soon before expiry a refresh should be attempted.
// Set to 5 minutes to match Antigravity and avoid frequent refresh checks while still ensuring timely token refresh. // Set to 10 minutes for proactive refresh before token expiry.
func (a *KiroAuthenticator) RefreshLead() *time.Duration { func (a *KiroAuthenticator) RefreshLead() *time.Duration {
d := 5 * time.Minute d := 10 * time.Minute
return &d return &d
} }
@@ -126,8 +126,8 @@ func (a *KiroAuthenticator) createAuthRecord(tokenData *kiroauth.KiroTokenData,
UpdatedAt: now, UpdatedAt: now,
Metadata: metadata, Metadata: metadata,
Attributes: attributes, Attributes: attributes,
// NextRefreshAfter is aligned with RefreshLead (5min) // NextRefreshAfter: 10 minutes before expiry
NextRefreshAfter: expiresAt.Add(-5 * time.Minute), NextRefreshAfter: expiresAt.Add(-10 * time.Minute),
} }
if tokenData.Email != "" { if tokenData.Email != "" {
@@ -208,8 +208,8 @@ func (a *KiroAuthenticator) LoginWithAuthCode(ctx context.Context, cfg *config.C
"source": "aws-builder-id-authcode", "source": "aws-builder-id-authcode",
"email": tokenData.Email, "email": tokenData.Email,
}, },
// NextRefreshAfter is aligned with RefreshLead (5min) // NextRefreshAfter: 10 minutes before expiry
NextRefreshAfter: expiresAt.Add(-5 * time.Minute), NextRefreshAfter: expiresAt.Add(-10 * time.Minute),
} }
if tokenData.Email != "" { if tokenData.Email != "" {
@@ -292,8 +292,8 @@ func (a *KiroAuthenticator) ImportFromKiroIDE(ctx context.Context, cfg *config.C
"email": tokenData.Email, "email": tokenData.Email,
"region": tokenData.Region, "region": tokenData.Region,
}, },
// NextRefreshAfter is aligned with RefreshLead (5min) // NextRefreshAfter: 10 minutes before expiry
NextRefreshAfter: expiresAt.Add(-5 * time.Minute), NextRefreshAfter: expiresAt.Add(-10 * time.Minute),
} }
// Display the email if extracted // Display the email if extracted
@@ -361,8 +361,8 @@ func (a *KiroAuthenticator) Refresh(ctx context.Context, cfg *config.Config, aut
updated.Metadata["refresh_token"] = tokenData.RefreshToken updated.Metadata["refresh_token"] = tokenData.RefreshToken
updated.Metadata["expires_at"] = tokenData.ExpiresAt updated.Metadata["expires_at"] = tokenData.ExpiresAt
updated.Metadata["last_refresh"] = now.Format(time.RFC3339) // For double-check optimization updated.Metadata["last_refresh"] = now.Format(time.RFC3339) // For double-check optimization
// NextRefreshAfter is aligned with RefreshLead (5min) // NextRefreshAfter: 10 minutes before expiry
updated.NextRefreshAfter = expiresAt.Add(-5 * time.Minute) updated.NextRefreshAfter = expiresAt.Add(-10 * time.Minute)
return updated, nil return updated, nil
} }