mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-21 14:19:18 +08:00
fix(grok): recognize probed Free cache accounts
This commit is contained in:
@@ -15,6 +15,7 @@ const (
|
||||
grokConversationIDHeader = "X-Grok-Conv-Id"
|
||||
grokFreeCacheNativeToolsJSON = `[{"type":"web_search"},{"type":"x_search"}]`
|
||||
grokFreeCacheDisabledToolChoice = "none"
|
||||
grokFreeRolling24hTokenLimit = int64(2_000_000)
|
||||
)
|
||||
|
||||
// resolveGrokCacheIdentity derives one stable, tenant-isolated routing identity
|
||||
@@ -152,22 +153,69 @@ func isKnownGrokFreeAccount(account *Account) bool {
|
||||
if account == nil || !account.IsGrokOAuth() {
|
||||
return false
|
||||
}
|
||||
freeSignal := false
|
||||
paidSignal := false
|
||||
inferredFreeSignal := false
|
||||
if billing, err := grokBillingSnapshotFromExtra(account.Extra); err == nil && billing != nil {
|
||||
if tier := strings.TrimSpace(billing.Plan); tier != "" {
|
||||
return isGrokFreeSubscriptionTier(tier)
|
||||
if isGrokFreeSubscriptionTier(tier) {
|
||||
freeSignal = true
|
||||
} else if !isGrokUnknownSubscriptionTier(tier) {
|
||||
paidSignal = true
|
||||
}
|
||||
}
|
||||
if billing.UsagePercent != nil || billing.UsedPercent != nil ||
|
||||
(billing.MonthlyLimitCents != nil && *billing.MonthlyLimitCents > 0) {
|
||||
paidSignal = true
|
||||
}
|
||||
// xAI deliberately reports an empty plan for Free accounts; only paid
|
||||
// subscriptions receive a SuperGrok plan/monthly limit. A successful
|
||||
// monthly billing observation with no paid signal is therefore positive
|
||||
// Free evidence, not an unknown tier. Keep partial probes fail-closed.
|
||||
if strings.TrimSpace(billing.MonthlyUpdatedAt) != "" ||
|
||||
(billing.StatusCode >= http.StatusOK && billing.StatusCode < http.StatusMultipleChoices &&
|
||||
!billing.Partial && len(billing.FailedWindows) == 0) {
|
||||
inferredFreeSignal = true
|
||||
}
|
||||
}
|
||||
if snapshot, err := grokQuotaSnapshotFromExtra(account.Extra); err == nil && snapshot != nil {
|
||||
if tier := strings.TrimSpace(snapshot.SubscriptionTier); tier != "" {
|
||||
return isGrokFreeSubscriptionTier(tier)
|
||||
if isGrokFreeSubscriptionTier(tier) {
|
||||
freeSignal = true
|
||||
} else if !isGrokUnknownSubscriptionTier(tier) {
|
||||
paidSignal = true
|
||||
}
|
||||
}
|
||||
if snapshot.Tokens != nil && snapshot.Tokens.Limit != nil &&
|
||||
*snapshot.Tokens.Limit == grokFreeRolling24hTokenLimit {
|
||||
inferredFreeSignal = true
|
||||
}
|
||||
}
|
||||
return isGrokFreeSubscriptionTier(account.GetCredential("subscription_tier"))
|
||||
if tier := strings.TrimSpace(account.GetCredential("subscription_tier")); tier != "" {
|
||||
if isGrokFreeSubscriptionTier(tier) {
|
||||
freeSignal = true
|
||||
} else if !isGrokUnknownSubscriptionTier(tier) {
|
||||
paidSignal = true
|
||||
}
|
||||
}
|
||||
// Explicit paid evidence always wins over an inferred Free signal. This
|
||||
// protects upgraded/stale accounts whose previous quota snapshot still
|
||||
// carries the historical 2M Free token limit.
|
||||
return !paidSignal && (freeSignal || inferredFreeSignal)
|
||||
}
|
||||
|
||||
func isGrokFreeSubscriptionTier(tier string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(tier)) {
|
||||
case "free", "grok-free", "grok_free", "free-tier", "free_tier":
|
||||
case "free", "grok-free", "grok_free", "free-tier", "free_tier", "basic", "grok-basic", "grok_basic":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isGrokUnknownSubscriptionTier(tier string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(tier)) {
|
||||
case "", "unknown", "n/a", "none":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -296,6 +296,31 @@ func TestGrokFreeMessagesFunctionToolCacheRouteRequiresKnownFreeTier(t *testing.
|
||||
}(),
|
||||
wantMix: true,
|
||||
},
|
||||
{
|
||||
name: "free successful billing has blank plan",
|
||||
account: func() *Account {
|
||||
a := healthyGrokOAuthGatewayTestAccount(9111, "access-token")
|
||||
a.Extra = map[string]any{grokBillingExtraKey: map[string]any{
|
||||
"status_code": http.StatusOK,
|
||||
"source": "billing_probe",
|
||||
"monthly_updated_at": "2026-07-15T05:00:00Z",
|
||||
}}
|
||||
return a
|
||||
}(),
|
||||
wantMix: true,
|
||||
},
|
||||
{
|
||||
name: "free rolling token quota",
|
||||
account: func() *Account {
|
||||
a := healthyGrokOAuthGatewayTestAccount(9112, "access-token")
|
||||
a.Extra = map[string]any{grokQuotaSnapshotExtraKey: map[string]any{
|
||||
"headers_observed": true,
|
||||
"tokens": map[string]any{"limit": grokFreeRolling24hTokenLimit},
|
||||
}}
|
||||
return a
|
||||
}(),
|
||||
wantMix: true,
|
||||
},
|
||||
{
|
||||
name: "supergrok remains unchanged",
|
||||
account: func() *Account {
|
||||
@@ -304,6 +329,33 @@ func TestGrokFreeMessagesFunctionToolCacheRouteRequiresKnownFreeTier(t *testing.
|
||||
return a
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "paid billing overrides stale free quota",
|
||||
account: func() *Account {
|
||||
a := healthyGrokOAuthGatewayTestAccount(9121, "access-token")
|
||||
a.Extra = map[string]any{
|
||||
grokBillingExtraKey: map[string]any{"plan": "SuperGrok", "status_code": http.StatusOK},
|
||||
grokQuotaSnapshotExtraKey: map[string]any{
|
||||
"headers_observed": true,
|
||||
"tokens": map[string]any{"limit": grokFreeRolling24hTokenLimit},
|
||||
},
|
||||
}
|
||||
return a
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "partial billing without monthly evidence remains unknown",
|
||||
account: func() *Account {
|
||||
a := healthyGrokOAuthGatewayTestAccount(9122, "access-token")
|
||||
a.Extra = map[string]any{grokBillingExtraKey: map[string]any{
|
||||
"status_code": http.StatusOK,
|
||||
"source": "billing_probe",
|
||||
"partial": true,
|
||||
"failed_windows": []string{"monthly"},
|
||||
}}
|
||||
return a
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "unknown tier remains unchanged",
|
||||
account: healthyGrokOAuthGatewayTestAccount(913, "access-token"),
|
||||
|
||||
@@ -1473,7 +1473,11 @@ func TestForwardAsAnthropicForGrokFunctionToolUsesCacheCapableMixedRoute(t *test
|
||||
c.Set("api_key", &APIKey{ID: 5403})
|
||||
|
||||
account := healthyGrokOAuthGatewayTestAccount(58, "access-token")
|
||||
account.Credentials["subscription_tier"] = "free"
|
||||
account.Extra = map[string]any{grokBillingExtraKey: map[string]any{
|
||||
"status_code": http.StatusOK,
|
||||
"source": "billing_probe",
|
||||
"monthly_updated_at": "2026-07-15T05:00:00Z",
|
||||
}}
|
||||
repo := &grokQuotaAccountRepo{
|
||||
mockAccountRepoForPlatform: &mockAccountRepoForPlatform{
|
||||
accountsByID: map[int64]*Account{58: account},
|
||||
|
||||
Reference in New Issue
Block a user