feat: Implement provider groupings with account calculator and compre… (#113)

* feat: Implement provider groupings with account calculator and comprehensive fixes

- Add provider detection utilities (detectProvider, PROVIDER_REGISTRY) for Claude/Gemini/Others categorization
- Implement grouping logic (groupModelsByProvider, calculateProviderStats, calculateAccountStats) with health status calculation
- Create useProviderGrouping hook for collapsible state management and persistence
- Add ProviderGroup component with health indicators, progress bars, and model visibility integration
- Enhance CloudAccountList with account-level calculator showing overall percentage and earliest reset time
- Implement grid layout selector (auto/2-col/3-col/list) with config persistence and tooltips
- Add global quota aggregate bar across all accounts in top statistics
- Fix model visibility settings regression by accessing account.quota.models instead of account.quota
- Show 'Rate Limited' instead of '0%' for exhausted quotas with consistent getQuotaLabel function
- Add comprehensive i18n translations for layout selector and rate limited labels (en, zh-CN, ru)
- Disable batch operations when provider groupings are enabled to prevent conflicts
- Include unit tests for provider detection logic and grouping functionality

Addresses critical issues: model list regression, rate limited display, layout control, global quota visibility, and consistent quota labeling across all components.

* fix: resolve ESLint no-ex-assign violations in proxy service

- Fix exception parameter reassignment in catch blocks
- Rename catch parameters to avoid no-ex-assign rule violations
- Maintain same error handling logic while complying with linting rules

* fix: add missing Models tab to settings page

- Add Models tab between General and Proxy tabs
- Import and integrate ModelVisibilitySettings component
- Fix critical regression where model visibility settings were inaccessible

* fix: add missing React hook imports in settings route

* test: remove obsolete tests for removed controller APIs

---------

Co-authored-by: Draculabo <[email protected]>
This commit is contained in:
ArtemisAIandDraculabo authored and GitHub committed 2026-02-18 16:38:15 +08:00
1 parent 118fad567e
commit 1e59a1c901
12 files changed
+1237 -97

No files matched your search

+122
View File
@@ -138,6 +138,38 @@ i18n
default: 'Default',
restoreDefaults: 'Restore Defaults',
},
modelVisibility: {
title: 'Model Visibility',
description:
"Control which models are visible in account cards. Hidden models won't appear in the quota display.",
searchPlaceholder: 'Search models...',
showAll: 'Show All',
hideAll: 'Hide All',
reset: 'Reset to Defaults',
save: 'Save Changes',
noModels: 'No models found',
modelsShown: '{{visible}} of {{total}} models visible',
quotaManagement: 'Quota Management',
hidden: 'Hidden',
noModelsFound: 'No models found',
totalModels: 'Total',
visibleModels: 'Visible',
hiddenModels: 'Hidden',
saving: 'Saving...',
},
providerGroupings: {
title: 'Provider Groupings',
description: 'Group models by provider for better organization',
enabled: 'Enable Provider Groupings',
models: '{{count}} models',
avgLabel: 'avg',
resetLabel: 'reset',
overall: 'Overall',
healthy: 'Healthy',
degraded: 'Degraded',
limited: 'Limited',
critical: 'Critical',
},
examples: {
title: 'Usage Examples',
@@ -215,10 +247,18 @@ i18n
title: 'Accounts',
description: 'Manage your Google Gemini account pool.',
autoSwitch: 'Auto-Switch',
providerGroupings: 'Provider Groupings',
addAccount: 'Add Account',
syncFromIDE: 'Sync from IDE',
checkQuota: 'Check Quota Now',
polling: 'Polling triggered',
globalQuota: 'Global Quota',
layout: {
auto: 'Auto',
twoCol: '2 Columns',
threeCol: '3 Columns',
list: 'List',
},
authDialog: {
title: 'Add Google Account',
description: 'To add an account, you need to authorize the application.',
@@ -242,6 +282,7 @@ i18n
refresh: 'Refresh Quota',
delete: 'Delete Account',
noQuota: 'No quota data',
rateLimitedQuota: 'Rate Limited',
resetPrefix: 'reset',
resetTime: 'Reset time',
resetUnknown: 'Unknown',
@@ -480,6 +521,37 @@ i18n
default: '默认',
restoreDefaults: '恢复默认配置',
},
modelVisibility: {
title: '模型可见性',
description: '控制哪些模型在账号卡片中可见。隐藏的模型不会在配额显示中出现。',
searchPlaceholder: '搜索模型...',
showAll: '显示全部',
hideAll: '隐藏全部',
reset: '重置为默认',
save: '保存更改',
noModels: '未找到模型',
modelsShown: '{{visible}} / {{total}} 个模型可见',
quotaManagement: '配额管理',
hidden: '已隐藏',
noModelsFound: '未找到模型',
totalModels: '总数',
visibleModels: '可见',
hiddenModels: '隐藏',
saving: '保存中...',
},
providerGroupings: {
title: '模型分组',
description: '按供应商分组模型以便更好地管理',
enabled: '启用供应商分组',
models: '{{count}} 个模型',
avgLabel: '平均',
resetLabel: '重置',
overall: '总览',
healthy: '正常',
degraded: '降级',
limited: '受限',
critical: '严重',
},
examples: {
title: '使用示例',
@@ -556,10 +628,18 @@ i18n
title: '账号列表',
description: '管理您的 Google Gemini 账号池。',
autoSwitch: '自动切换',
providerGroupings: '提供商分组',
addAccount: '添加账号',
syncFromIDE: '从 IDE 同步',
checkQuota: '立即检查配额',
polling: '已触发轮询',
globalQuota: '全局配额',
layout: {
auto: '自动',
twoCol: '2 列',
threeCol: '3 列',
list: '列表',
},
authDialog: {
title: '添加 Google 账号',
description: '添加账号需要进行应用授权。',
@@ -582,6 +662,7 @@ i18n
refresh: '刷新配额',
delete: '删除账号',
noQuota: '无配额数据',
rateLimitedQuota: '已达限额',
resetPrefix: '重置',
resetTime: '重置时间',
resetUnknown: '未知',
@@ -822,6 +903,38 @@ i18n
default: 'По умолчанию',
restoreDefaults: 'Сбросить по умолчанию',
},
modelVisibility: {
title: 'Видимость моделей',
description:
'Управляйте тем, какие модели отображаются в карточках аккаунтов. Скрытые модели не будут показаны в отображении квот.',
searchPlaceholder: 'Поиск моделей...',
showAll: 'Показать все',
hideAll: 'Скрыть все',
reset: 'Сбросить по умолчанию',
save: 'Сохранить изменения',
noModels: 'Модели не найдены',
modelsShown: '{{visible}} из {{total}} моделей видно',
quotaManagement: 'Управление квотами',
hidden: 'Скрыто',
noModelsFound: 'Модели не найдены',
totalModels: 'Всего',
visibleModels: 'Видно',
hiddenModels: 'Скрыто',
saving: 'Сохранение...',
},
providerGroupings: {
title: 'Группировка провайдеров',
description: 'Группировка моделей по провайдерам для лучшей организации',
enabled: 'Включить группировку провайдеров',
models: '{{count}} моделей',
avgLabel: 'сред.',
resetLabel: 'сброс',
overall: 'Общее',
healthy: 'Исправно',
degraded: 'Снижено',
limited: 'Ограничено',
critical: 'Критично',
},
examples: {
title: 'Примеры использования',
description: 'Примеры команд для вызова локального API прокси.',
@@ -898,10 +1011,18 @@ i18n
title: 'Аккаунты',
description: 'Управление пулом аккаунтов Google Gemini.',
autoSwitch: 'Авто-переключение',
providerGroupings: 'Группировка по провайдерам',
addAccount: 'Добавить аккаунт',
syncFromIDE: 'Синхр. из IDE',
checkQuota: 'Проверить квоту',
polling: 'Опрос запущен',
globalQuota: 'Глобальная квота',
layout: {
auto: 'Авто',
twoCol: '2 колонки',
threeCol: '3 колонки',
list: 'Список',
},
authDialog: {
title: 'Добавить Google Аккаунт',
description: 'Для добавления аккаунта необходимо авторизовать приложение.',
@@ -925,6 +1046,7 @@ i18n
refresh: 'Обновить квоту',
delete: 'Удалить аккаунт',
noQuota: 'Нет данных',
rateLimitedQuota: 'Лимит исчерпан',
resetPrefix: 'Сброс',
resetTime: 'Время сброса',
resetUnknown: 'Неизвестно',