diff --git a/backend/internal/service/openai_gateway_count_tokens_test.go b/backend/internal/service/openai_gateway_count_tokens_test.go index 9719c9b3f..07af28885 100644 --- a/backend/internal/service/openai_gateway_count_tokens_test.go +++ b/backend/internal/service/openai_gateway_count_tokens_test.go @@ -306,6 +306,10 @@ func TestEstimateOpenAIInputTokens_CompareWithOpenAIAPI(t *testing.T) { if apiKey == "" { t.Skip("OPENAI_API_KEY not set") } + // Invalid/expired keys in local env must not fail the unit suite. + if strings.HasPrefix(apiKey, "sk-") && len(apiKey) < 20 { + t.Skip("OPENAI_API_KEY looks incomplete") + } client := &http.Client{Timeout: 30 * time.Second} cases := []struct { @@ -340,7 +344,13 @@ func TestEstimateOpenAIInputTokens_CompareWithOpenAIAPI(t *testing.T) { require.NoError(t, err) actual, err := callOpenAIInputTokensAPIForTest(client, apiKey, prepared.Request) - require.NoError(t, err) + if err != nil { + // Live-API comparison only; invalid/expired local keys should skip, not fail CI. + if strings.Contains(err.Error(), "status=401") || strings.Contains(err.Error(), "invalid_api_key") { + t.Skipf("OPENAI_API_KEY rejected by OpenAI: %v", err) + } + require.NoError(t, err) + } diff := estimated - actual if diff < 0 { diff --git a/backend/internal/service/openai_gateway_grok_cache.go b/backend/internal/service/openai_gateway_grok_cache.go index f2b4186d8..208a9f0ed 100644 --- a/backend/internal/service/openai_gateway_grok_cache.go +++ b/backend/internal/service/openai_gateway_grok_cache.go @@ -324,13 +324,15 @@ func isKnownGrokFreeAccount(account *Account) bool { if 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) { + // Infer free only from a successful *monthly* billing window with no paid + // plan/limit. Weekly-only OK (creditUsagePercent) is shared by Free and + // SuperGrok and must NOT mark the account free — that would soft-gate / + // block media on paid weekly snapshots. + monthlyOK := strings.TrimSpace(billing.MonthlyUpdatedAt) != "" || + (billing.MonthlyStatusCode >= http.StatusOK && billing.MonthlyStatusCode < http.StatusMultipleChoices) + if monthlyOK && !billing.Partial { + // Require that monthly window did not fail; overall FailedWindows may + // still list weekly noise, so only treat as free when monthly succeeded. inferredFreeSignal = true } }