Files
antigravity-claude-proxy/public/js/translations/pt.js
Badri Narayanan S 5a85f0cfcc feat: comprehensive rate limit handling overhaul (inspired by opencode-antigravity-auth)
This commit addresses "Max retries exceeded" errors during stress testing where
all accounts would become exhausted simultaneously due to short per-second rate
limits triggering cascading failures.

## Rate Limit Parser (`rate-limit-parser.js`)
- Remove 2s buffer enforcement that caused cascading failures when API returned
  short reset times (200-600ms). Now adds 200ms buffer for sub-500ms resets
- Add `parseRateLimitReason()` for smart backoff based on error type:
  QUOTA_EXHAUSTED, RATE_LIMIT_EXCEEDED, MODEL_CAPACITY_EXHAUSTED, SERVER_ERROR

## Message/Streaming Handlers
- Add per-account+model rate limit state tracking with exponential backoff
- For short rate limits (< 1 second), wait and retry on same account instead
  of switching - prevents thundering herd when all accounts hit per-second limits
- Add throttle wait support for fallback modes (emergency/lastResort)
- Add `calculateSmartBackoff()` with progressive tiers by error type

## HybridStrategy (`hybrid-strategy.js`)
- Refactor `#getCandidates()` to return 4 fallback levels:
  - `normal`: All filters pass (health, tokens, quota)
  - `quota`: Bypass critical quota check
  - `emergency`: Bypass health check when ALL accounts unhealthy
  - `lastResort`: Bypass BOTH health AND token bucket checks
- Add throttle wait times: 500ms for lastResort, 250ms for emergency
- Fix LRU calculation to use seconds (matches opencode-antigravity-auth)

## Health Tracker
- Increase `recoveryPerHour` from 2 to 10 for faster recovery (1 hour vs 5 hours)

## Account Manager
- Add consecutive failure tracking: `getConsecutiveFailures()`,
  `incrementConsecutiveFailures()`, `resetConsecutiveFailures()`
- Add cooldown mechanism separate from rate limits with `CooldownReason`
- Reset consecutive failures on successful request

## Base Strategy
- Add `isAccountCoolingDown()` check in `isAccountUsable()`

## Constants
- Replace fixed `CAPACITY_RETRY_DELAY_MS` with progressive `CAPACITY_BACKOFF_TIERS_MS`
- Add `BACKOFF_BY_ERROR_TYPE` for smart backoff
- Add `QUOTA_EXHAUSTED_BACKOFF_TIERS_MS` for progressive quota backoff
- Add `MIN_BACKOFF_MS` floor to prevent "Available in 0s" loops
- Increase `MAX_CAPACITY_RETRIES` from 3 to 5
- Reduce `RATE_LIMIT_DEDUP_WINDOW_MS` from 5s to 2s

## Frontend
- Remove `capacityRetryDelayMs` config (replaced by progressive tiers)
- Update default `maxCapacityRetries` display from 3 to 5

## Testing
- Add `tests/stress-test.cjs` for concurrent request stress testing

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-24 22:43:53 +05:30

309 lines
14 KiB
JavaScript

/**
* Portuguese (PT-BR) Translations
* Based on contribution by Pedro Farias in PR #108
*/
window.translations = window.translations || {};
window.translations.pt = {
dashboard: "Painel",
models: "Modelos",
accounts: "Contas",
logs: "Logs",
settings: "Configurações",
online: "ONLINE",
offline: "OFFLINE",
totalAccounts: "TOTAL DE CONTAS",
active: "ATIVO",
operational: "Operacional",
rateLimited: "TAXA LIMITADA",
quotasDepleted: "{count}/{total} Cotas Esgotadas",
quotasDepletedTitle: "COTAS ESGOTADAS",
outOfTracked: "De {total} Rastreados",
cooldown: "Resfriamento",
searchPlaceholder: "Buscar modelos...",
allAccounts: "Todas as Contas",
stat: "ESTATÍSTICA",
modelIdentity: "IDENTIDADE DO MODELO",
globalQuota: "COTA GLOBAL",
nextReset: "PRÓXIMO RESET",
distribution: "DISTRIBUIÇÃO DE CONTAS",
systemConfig: "Configuração do Sistema",
language: "Idioma",
pollingInterval: "Intervalo de Atualização",
maxDisplayLogs: "Máximo de Logs Exibidos",
showExhausted: "Mostrar Modelos Esgotados",
showExhaustedDesc: "Exibir modelos mesmo se tiverem 0% de cota restante.",
compactMode: "Modo Compacto",
compactModeDesc: "Reduzir espaçamento nas tabelas para maior densidade de informação.",
saveChanges: "Salvar Alterações",
autoScroll: "Rolagem Automática",
clearLogs: "Limpar Logs",
accountManagement: "Gerenciamento de Contas",
manageTokens: "Gerenciar tokens e estados de autorização de Contas Google",
addAccount: "Adicionar Conta",
status: "STATUS",
enabled: "HABILITADO",
health: "SAÚDE",
accountEmail: "CONTA (EMAIL)",
source: "FONTE",
projectId: "ID DO PROJETO",
sessionState: "ESTADO DA SESSÃO",
operations: "OPERAÇÕES",
delete: "Excluir",
confirmDelete: "Tem certeza de que deseja remover esta conta?",
cannotDeleteDatabase: "Não é possível excluir: Esta conta é do banco de dados Antigravity (somente leitura)",
connectGoogle: "Conectar Conta Google",
reauthenticated: "reautenticado",
added: "adicionado",
successfully: "com sucesso",
accountAddedSuccess: "Conta adicionada com sucesso",
accountReauthSuccess: "Conta reautenticada com sucesso",
failedToGetAuthUrl: "Falha ao obter URL de autenticação",
failedToStartOAuth: "Falha ao iniciar fluxo OAuth",
oauthInProgress: "OAuth em andamento. Por favor, conclua a autenticação na janela popup...",
family: "Família",
model: "Modelo",
activeSuffix: "Ativo",
// Tabs
tabInterface: "Interface",
tabClaude: "Claude CLI",
tabModels: "Modelos",
tabServer: "Configurações do Servidor",
// Dashboard
linkedAccounts: "Contas Vinculadas",
noSignal: "SEM SINAL DETECTADO",
establishingUplink: "ESTABELECENDO LINK...",
goToAccounts: "Ir para Contas",
// Settings - Models
modelsDesc: "Configurar visibilidade, fixação e roteamento de requisições de modelos.",
modelsPageDesc: "Cota e status em tempo real para todos os modelos disponíveis.",
showHidden: "Mostrar Modelos Ocultos",
modelId: "ID do Modelo",
actions: "Ações",
pinToTop: "Fixar no topo",
toggleVisibility: "Alternar Visibilidade",
noModels: "NENHUM MODELO DETECTADO",
modelMappingHint: "Roteamento de modelo no servidor. Usuários do Claude Code: veja a aba 'Claude CLI' para configuração no cliente.",
modelMapping: "Mapeamento (ID do Modelo Alvo)",
// Settings - Claude
proxyConnection: "Conexão Proxy",
modelSelection: "Seleção de Modelo",
defaultModelAliases: "ALIASES DE MODELO PADRÃO",
opusAlias: "Alias Opus",
sonnetAlias: "Alias Sonnet",
haikuAlias: "Alias Haiku",
claudeSettingsAlertPrefix: "As configurações abaixo modificam diretamente",
claudeSettingsAlertSuffix: "Reinicie o Claude CLI para aplicar.",
applyToClaude: "Aplicar ao Claude CLI",
// Settings - Server
port: "Porta",
uiVersion: "Versão da UI",
debugMode: "Modo de Depuração",
environment: "Ambiente",
serverReadOnly: "Configurações gerenciadas via config.json. Reinicie o servidor para aplicar alterações.",
advancedSettings: "Configurações Avançadas",
reloadConfigTitle: "Recarregar Config de Contas",
reloadConfigDesc: "Forçar recarregamento de accounts.json do disco",
reload: "Recarregar",
// Config Specific
primaryModel: "Modelo Primário",
subAgentModel: "Modelo Sub-agente",
advancedOverrides: "Substituições de Modelo Padrão",
opusModel: "Modelo Opus",
sonnetModel: "Modelo Sonnet",
haikuModel: "Modelo Haiku",
authToken: "Token de Autenticação",
saveConfig: "Salvar nas configurações do Claude CLI",
envVar: "Env",
// New Keys
systemName: "ANTIGRAVITY",
systemDesc: "SISTEMA DE PROXY CLAUDE",
connectGoogleDesc: "Conecte uma conta Google Workspace para aumentar seu limite de cota da API. A conta será usada para fazer proxy das requisições Claude via Antigravity.",
useCliCommand: "Usar Comando CLI",
close: "Fechar",
requestVolume: "Volume de Requisições",
filter: "Filtrar",
all: "Todos",
none: "Nenhum",
noDataTracked: "Nenhum dado rastreado ainda",
selectFamilies: "Selecione famílias para exibir",
selectModels: "Selecione modelos para exibir",
noLogsMatch: "Nenhum log corresponde ao filtro",
connecting: "CONECTANDO",
main: "Principal",
system: "Sistema",
refreshData: "Atualizar Dados",
connectionLost: "Conexão Perdida",
lastUpdated: "Última Atualização",
grepLogs: "grep logs...",
noMatchingModels: "Nenhum modelo correspondente",
typeToSearch: "Digite para buscar ou selecione...",
or: "OU",
refreshingAccount: "Atualizando {email}...",
refreshedAccount: "Atualizado {email}",
refreshFailed: "Falha na atualização",
accountToggled: "Conta {email} {status}",
toggleFailed: "Falha ao alternar",
reauthenticating: "Reautenticando {email}...",
authUrlFailed: "Falha ao obter URL de autenticação",
deletedAccount: "Excluído {email}",
deleteFailed: "Falha ao excluir",
accountsReloaded: "Contas recarregadas",
reloadFailed: "Falha ao recarregar",
claudeConfigSaved: "Configuração do Claude salva",
claudeConfigRestored: "Claude CLI restaurado para o padrão",
saveConfigFailed: "Falha ao salvar configuração",
restoreConfigFailed: "Falha ao restaurar configuração",
restoreDefault: "Restaurar Padrão",
confirmRestoreTitle: "Confirmar Restauração",
confirmRestoreMessage: "Tem certeza de que deseja restaurar o Claude CLI para as configurações padrão? Isso removerá a configuração de proxy.",
confirmRestore: "Confirmar Restauração",
claudeActive: "Claude Ativo",
claudeEmpty: "Claude Vazio",
geminiActive: "Gemini Ativo",
geminiEmpty: "Gemini Vazio",
synced: "SINCRONIZADO",
syncing: "SINCRONIZANDO...",
// Time range labels
last1Hour: "Última 1H",
last6Hours: "Últimas 6H",
last24Hours: "Últimas 24H",
last7Days: "Últimos 7D",
allTime: "Todo o Período",
groupBy: "Agrupar Por",
// Additional
reloading: "Recarregando...",
reloaded: "Recarregado",
lines: "linhas",
enabledSeeLogs: "Habilitado (Ver Logs)",
production: "Produção",
configSaved: "Configuração Salva",
enterPassword: "Digite a Senha da Web UI:",
ready: "PRONTO",
depleted: "Esgotado",
timeH: "H",
timeM: "M",
familyClaude: "Claude",
familyGemini: "Gemini",
familyOther: "Outro",
enabledStatus: "habilitado",
disabledStatus: "desabilitado",
logLevelInfo: "INFO",
logLevelSuccess: "SUCESSO",
logLevelWarn: "AVISO",
logLevelError: "ERRO",
totalColon: "Total:",
todayColon: "Hoje:",
hour1Colon: "1H:",
frequentModels: "Frequentes",
smartTitle: "Auto-selecionar os 5 modelos mais usados (24h)",
activeCount: "{count} Ativos",
allCaps: "TODOS",
claudeCaps: "CLAUDE",
geminiCaps: "GEMINI",
systemInfo: "Informações do Sistema",
refresh: "Atualizar",
runtimeConfig: "Configuração em Tempo de Execução",
debugDesc: "Habilitar log detalhado (Ver aba Logs)",
networkRetry: "Configurações de Retentativa de Rede",
maxRetries: "Máximo de Retentativas",
retryBaseDelay: "Atraso Base de Retentativa (ms)",
retryMaxDelay: "Atraso Máximo de Retentativa (ms)",
persistentSessions: "Sessões Persistentes",
persistTokenDesc: "Salvar sessões OAuth no disco para reinicializações mais rápidas",
rateLimiting: "Limitação de Taxa de Conta & Timeouts",
defaultCooldown: "Tempo de Resfriamento Padrão",
defaultCooldownDesc: "Resfriamento de fallback quando a API não fornece tempo de reset.",
maxWaitThreshold: "Limiar Máximo de Espera (Sticky)",
maxWaitDesc: "Tempo máximo para aguardar uma conta sticky resetar antes de trocar.",
// Ajuste de Tratamento de Erros
errorHandlingTuning: "Ajuste de Tratamento de Erros",
rateLimitDedupWindow: "Janela de Deduplicação de Rate Limit",
rateLimitDedupWindowDesc: "Previne tempestades de retry quando múltiplas requisições atingem rate limits simultaneamente.",
maxConsecutiveFailures: "Máx. Falhas Consecutivas",
maxConsecutiveFailuresDesc: "Número de falhas consecutivas antes de aplicar resfriamento estendido.",
extendedCooldown: "Resfriamento Estendido",
extendedCooldownDesc: "Duração do resfriamento aplicado após atingir máx. de falhas consecutivas.",
maxCapacityRetries: "Máx. Retries de Capacidade",
maxCapacityRetriesDesc: "Máximo de retries para esgotamento de capacidade antes de trocar conta.",
saveConfigServer: "Salvar Configuração",
serverRestartAlert: "Alterações salvas em {path}. Reinicie o servidor para aplicar algumas configurações.",
changePassword: "Alterar Senha da WebUI",
changePasswordDesc: "Atualizar a senha para acessar este painel",
currentPassword: "Senha Atual",
newPassword: "Nova Senha",
confirmNewPassword: "Confirmar Nova Senha",
passwordEmptyDesc: "Deixe em branco se nenhuma senha estiver definida",
passwordLengthDesc: "Pelo menos 6 caracteres",
passwordConfirmDesc: "Redigite a nova senha",
cancel: "Cancelar",
passwordsNotMatch: "Senhas não coincidem",
passwordTooShort: "A senha deve ter pelo menos 6 caracteres",
// Dashboard drill-down
clickToViewAllAccounts: "Clique para ver todas as contas",
clickToViewModels: "Clique para ver a página de Modelos",
clickToViewLimitedAccounts: "Clique para ver contas limitadas",
clickToFilterClaude: "Clique para filtrar modelos Claude",
clickToFilterGemini: "Clique para filtrar modelos Gemini",
// Accounts page
searchAccounts: "Buscar contas...",
noAccountsYet: "Nenhuma Conta Ainda",
noAccountsDesc: "Comece adicionando uma conta Google via OAuth, ou use o comando CLI para importar credenciais.",
addFirstAccount: "Adicione Sua Primeira Conta",
noSearchResults: "Nenhuma conta corresponde à sua busca",
clearSearch: "Limpar Busca",
disabledAccountsNote: "<strong>Contas desabilitadas</strong> não serão usadas para roteamento de requisições, mas permanecem na configuração. As estatísticas do painel incluem apenas contas habilitadas.",
dangerousOperation: "⚠️ Operação Perigosa",
confirmDeletePrompt: "Tem certeza de que deseja excluir a conta",
deleteWarning: "⚠️ Esta ação não pode ser desfeita. Todas as configurações e registros históricos serão excluídos permanentemente.",
// OAuth progress
oauthWaiting: "Aguardando autorização OAuth...",
oauthWaitingDesc: "Por favor, complete a autenticação na janela popup. Isso pode levar até 2 minutos.",
oauthCancelled: "Autorização OAuth cancelada",
oauthTimeout: "⏱️ Autorização OAuth expirou. Por favor, tente novamente.",
oauthWindowClosed: "A janela OAuth foi fechada. A autorização pode estar incompleta.",
cancelOAuth: "Cancelar",
// MCP CLI & Gemini 1M
mcpCliExperimental: "CLI MCP Experimental",
mcpCliDesc: "Habilita integração MCP experimental para uso confiável de ferramentas com consumo reduzido de contexto.",
gemini1mMode: "Modo de Contexto Gemini 1M",
gemini1mDesc: "Adiciona sufixo [1m] aos modelos Gemini para suporte a janela de contexto de 1M.",
gemini1mWarning: "⚠ Contexto grande pode reduzir o desempenho do Gemini-3-Pro.",
clickToSet: "Clique para configurar...",
none: "Nenhum",
// Quota Distribution
quotaDistribution: "Distribuição de Quota",
resetsIn: "Reseta em {time}",
noQuotaData: "Dados de quota ainda não disponíveis para esta conta.",
// Manual OAuth Mode
manualMode: "Modo Manual",
manualModeDesc: "(para ambientes onde callback não consegue alcançar)",
authLinkLabel: "Link de Autorização:",
linkCopied: "Link copiado para a área de transferência",
pasteCallbackLabel: "Cole a URL de callback ou código:",
pasteCallbackPlaceholder: "http://localhost:51121/oauth-callback?code=... ou 4/0xxx...",
completeAuth: "Completar Autorização",
authFailed: "Falha na autorização",
// Import/Export
export: "Exportar",
import: "Importar",
exportAccounts: "Exportar Contas",
importAccounts: "Importar Contas",
exportSuccess: "Exportadas {count} contas",
exportFailed: "Falha ao exportar",
importSuccess: "Importação concluída:",
importFailed: "Falha ao importar",
// Account Selection Strategy translations
accountSelectionStrategy: "Estratégia de Seleção de Conta",
selectionStrategy: "Estratégia de Seleção",
strategyStickyLabel: "Fixo (Otimizado para Cache)",
strategyRoundRobinLabel: "Rodízio (Balanceamento de Carga)",
strategyHybridLabel: "Híbrido (Distribuição Inteligente)",
strategyStickyDesc: "Permanece na mesma conta até atingir limite. Melhor para cache de prompts.",
strategyRoundRobinDesc: "Alterna para próxima conta a cada requisição. Máximo throughput.",
strategyHybridDesc: "Seleção inteligente baseada em saúde, tokens e frescor.",
strategyUpdated: "Estratégia atualizada para: {strategy}",
failedToUpdateStrategy: "Falha ao atualizar estratégia",
invalidStrategy: "Estratégia inválida selecionada",
};