fix: address review comments - extract shared quota detection utility and fix translation typos

This commit is contained in:
Daniel Riccio 2025-07-04 17:32:42 -05:00
parent f2255d900d
commit 3905dcbd5d
No known key found for this signature in database
GPG key ID: FFD5FD825F8E8209
6 changed files with 38 additions and 60 deletions

View file

@ -3,7 +3,7 @@
"authenticationFailed": "Không thể tạo nhúng: Xác thực không thành công. Vui lòng kiểm tra khóa API của bạn.",
"failedWithStatus": "Không thể tạo nhúng sau {{attempts}} lần thử: HTTP {{statusCode}} - {{errorMessage}}",
"failedWithError": "Không thể tạo nhúng sau {{attempts}} lần thử: {{errorMessage}}",
"insufficientQuota": "Không tạo được embedding: Không đủ hạn ngạch. Vui lòng kiểm tra số dư tài khoản OpenAI của bạn và nạp thêm tín dụng để tiếp tục.",
"insufficientQuota": "Không tạo được nhúng: Không đủ hạn ngạch. Vui lòng kiểm tra số dư tài khoản OpenAI của bạn và nạp thêm tín dụng để tiếp tục.",
"failedMaxAttempts": "Không thể tạo nhúng sau {{attempts}} lần thử",
"textExceedsTokenLimit": "Văn bản tại chỉ mục {{index}} vượt quá giới hạn mã thông báo tối đa ({{itemTokens}} > {{maxTokens}}). Bỏ qua.",
"textWithPrefixExceedsTokenLimit": "Văn bản tại chỉ mục {{index}} có tiền tố vượt quá giới hạn mã thông báo tối đa ({{estimatedTokens}} > {{maxTokens}}). Không thêm tiền tố.",

View file

@ -3,7 +3,7 @@
"authenticationFailed": "创建嵌入失败:身份验证失败。请检查您的 API 密钥。",
"failedWithStatus": "尝试 {{attempts}} 次后创建嵌入失败HTTP {{statusCode}} - {{errorMessage}}",
"failedWithError": "尝试 {{attempts}} 次后创建嵌入失败:{{errorMessage}}",
"insufficientQuota": "创建嵌入失败:配额不足。请检查您的 OpenAI 帐户余额添加积分以继续。",
"insufficientQuota": "创建嵌入失败:配额不足。请检查您的 OpenAI 帐户余额添加积分以继续。",
"failedMaxAttempts": "尝试 {{attempts}} 次后创建嵌入失败",
"textExceedsTokenLimit": "索引 {{index}} 处的文本超过最大令牌限制 ({{itemTokens}} > {{maxTokens}})。正在跳过。",
"textWithPrefixExceedsTokenLimit": "索引 {{index}} 处带前缀的文本超过了最大令牌限制 ({{estimatedTokens}} > {{maxTokens}})。不添加前缀。",

View file

@ -3,10 +3,10 @@
"authenticationFailed": "建立內嵌失敗:驗證失敗。請檢查您的 API 金鑰。",
"failedWithStatus": "嘗試 {{attempts}} 次後建立內嵌失敗HTTP {{statusCode}} - {{errorMessage}}",
"failedWithError": "嘗試 {{attempts}} 次後建立內嵌失敗:{{errorMessage}}",
"insufficientQuota": "建立失敗:額度不足。請檢查您的 OpenAI 帳戶餘額並新增點數以繼續。",
"insufficientQuota": "建立嵌失敗:額度不足。請檢查您的 OpenAI 帳戶餘額並新增點數以繼續。",
"failedMaxAttempts": "嘗試 {{attempts}} 次後建立內嵌失敗",
"textExceedsTokenLimit": "索引 {{index}} 處的文字超過最大權杖限制 ({{itemTokens}} > {{maxTokens}})。正在略過。",
"textWithPrefixExceedsTokenLimit": "索引 {{index}} 處帶前綴的文本超過了最大令牌限制 ({{estimatedTokens}} > {{maxTokens}})。不添加前綴。",
"textWithPrefixExceedsTokenLimit": "索引 {{index}} 處帶前綴的文本超過了最大權杖限制 ({{estimatedTokens}} > {{maxTokens}})。不添加前綴。",
"rateLimitRetry": "已達到速率限制,將在 {{delayMs}} 毫秒後重試(嘗試次數 {{attempt}}/{{maxRetries}}",
"ollama": {
"couldNotReadErrorBody": "無法讀取錯誤內容",

View file

@ -8,6 +8,7 @@ import {
} from "../constants"
import { getDefaultModelId, getModelQueryPrefix } from "../../../shared/embeddingModels"
import { t } from "../../../i18n"
import { isInsufficientQuotaError } from "./utils/quota-detection"
interface EmbeddingItem {
embedding: string | number[]
@ -277,7 +278,7 @@ export class OpenAICompatibleEmbedder implements IEmbedder {
const hasMoreAttempts = attempts < MAX_RETRIES - 1
// Add quota detection
const isQuotaError = this.isInsufficientQuotaError(error)
const isQuotaError = isInsufficientQuotaError(error)
if (isRateLimitError && !isQuotaError && hasMoreAttempts) {
const delayMs = INITIAL_DELAY_MS * Math.pow(2, attempts)
@ -337,31 +338,4 @@ export class OpenAICompatibleEmbedder implements IEmbedder {
name: "openai-compatible",
}
}
/**
* Detects if an error is due to insufficient quota/credits
* @param error The error object to check
* @returns True if the error indicates insufficient quota
*/
private isInsufficientQuotaError(error: any): boolean {
if (error?.status !== 429) return false
const errorMessage =
error?.message?.toLowerCase() ||
error?.response?.data?.error?.message?.toLowerCase() ||
error?.error?.message?.toLowerCase() ||
""
const quotaKeywords = [
"insufficient_quota",
"insufficient quota",
"quota exceeded",
"insufficient funds",
"billing",
"payment required",
"credits",
]
return quotaKeywords.some((keyword) => errorMessage.includes(keyword))
}
}

View file

@ -8,6 +8,7 @@ import {
MAX_BATCH_RETRIES as MAX_RETRIES,
INITIAL_RETRY_DELAY_MS as INITIAL_DELAY_MS,
} from "../constants"
import { isInsufficientQuotaError } from "./utils/quota-detection"
import { getModelQueryPrefix } from "../../../shared/embeddingModels"
import { t } from "../../../i18n"
@ -142,7 +143,7 @@ export class OpenAiEmbedder extends OpenAiNativeHandler implements IEmbedder {
const hasMoreAttempts = attempts < MAX_RETRIES - 1
// Add quota detection
const isQuotaError = this.isInsufficientQuotaError(error)
const isQuotaError = isInsufficientQuotaError(error)
if (isRateLimitError && !isQuotaError && hasMoreAttempts) {
const delayMs = INITIAL_DELAY_MS * Math.pow(2, attempts)
@ -199,31 +200,4 @@ export class OpenAiEmbedder extends OpenAiNativeHandler implements IEmbedder {
name: "openai",
}
}
/**
* Detects if an error is due to insufficient quota/credits
* @param error The error object to check
* @returns True if the error indicates insufficient quota
*/
private isInsufficientQuotaError(error: any): boolean {
if (error?.status !== 429) return false
const errorMessage =
error?.message?.toLowerCase() ||
error?.response?.data?.error?.message?.toLowerCase() ||
error?.error?.message?.toLowerCase() ||
""
const quotaKeywords = [
"insufficient_quota",
"insufficient quota",
"quota exceeded",
"insufficient funds",
"billing",
"payment required",
"credits",
]
return quotaKeywords.some((keyword) => errorMessage.includes(keyword))
}
}

View file

@ -0,0 +1,30 @@
/**
* Utility functions for detecting quota-related errors from OpenAI API
*/
/**
* Detects if an error is due to insufficient quota/credits
* @param error The error object to check
* @returns True if the error indicates insufficient quota
*/
export function isInsufficientQuotaError(error: any): boolean {
if (error?.status !== 429) return false
const errorMessage =
error?.message?.toLowerCase() ||
error?.response?.data?.error?.message?.toLowerCase() ||
error?.error?.message?.toLowerCase() ||
""
const quotaKeywords = [
"insufficient_quota",
"insufficient quota",
"quota exceeded",
"insufficient funds",
"billing",
"payment required",
"credits",
]
return quotaKeywords.some((keyword) => errorMessage.includes(keyword))
}