grok_spending_reauth.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package service
  2. import (
  3. "context"
  4. "strings"
  5. "time"
  6. )
  7. // Spending-limit is recoverable at the end of the observed billing period.
  8. // When no billing snapshot is available, use a short probe rather than
  9. // fabricating a 24h boundary from the error arrival time.
  10. const grokSpendingLimitProbeCooldown = 10 * time.Minute
  11. func grokSpendingLimitResetAt(account *Account, now time.Time) time.Time {
  12. if account != nil {
  13. if billing, err := grokBillingSnapshotFromExtra(account.Extra); err == nil && billing != nil {
  14. for _, raw := range []string{billing.PeriodEnd, billing.BillingPeriodEnd} {
  15. if resetAt, err := time.Parse(time.RFC3339, strings.TrimSpace(raw)); err == nil && resetAt.After(now) {
  16. return resetAt
  17. }
  18. }
  19. }
  20. }
  21. return now.Add(grokSpendingLimitProbeCooldown)
  22. }
  23. // clearGrokNeedsReauthExtra drops the soft reauth flag after successful refresh
  24. // or reauth. Best-effort; never fails the request path.
  25. func clearGrokNeedsReauthExtra(ctx context.Context, repo AccountRepository, accountID int64) {
  26. if repo == nil || accountID <= 0 {
  27. return
  28. }
  29. stateCtx, cancel := openAIAccountStateContext(ctx)
  30. defer cancel()
  31. _ = repo.UpdateExtra(stateCtx, accountID, map[string]any{
  32. "grok_needs_reauth": false,
  33. "grok_needs_reauth_reason": "",
  34. "grok_needs_reauth_at": "",
  35. })
  36. }
  37. func accountGrokNeedsReauth(account *Account) bool {
  38. if account == nil {
  39. return false
  40. }
  41. if account.Status == StatusError {
  42. msg := strings.ToLower(account.ErrorMessage)
  43. if strings.Contains(msg, "spending limit") || strings.Contains(msg, "reauthorize") {
  44. return true
  45. }
  46. }
  47. if v, ok := account.Extra["grok_needs_reauth"].(bool); ok && v {
  48. return true
  49. }
  50. if s, ok := account.Extra["grok_needs_reauth"].(string); ok {
  51. return strings.EqualFold(s, "true") || s == "1"
  52. }
  53. return false
  54. }