antigravity-claude-proxy 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +4 -11
- package/package.json +1 -1
- package/public/app.js +7 -4
- package/public/css/src/input.css +379 -216
- package/public/css/style.css +1 -1
- package/public/favicon.svg +4 -8
- package/public/index.html +78 -72
- package/public/js/components/claude-config.js +0 -8
- package/public/js/components/dashboard/charts.js +25 -51
- package/public/js/components/dashboard/stats.js +1 -1
- package/public/js/components/dashboard.js +16 -21
- package/public/js/components/logs-viewer.js +1 -1
- package/public/js/components/models.js +12 -12
- package/public/js/components/server-config.js +1 -9
- package/public/js/data-store.js +2 -2
- package/public/js/store.js +1 -1
- package/public/js/translations/en.js +37 -39
- package/public/js/translations/id.js +36 -37
- package/public/js/translations/pt.js +37 -38
- package/public/js/translations/tr.js +37 -39
- package/public/js/translations/zh.js +0 -2
- package/public/js/utils/error-handler.js +0 -2
- package/public/js/utils/ui-logger.js +4 -3
- package/public/views/accounts.html +34 -38
- package/public/views/dashboard.html +86 -99
- package/public/views/logs.html +4 -4
- package/public/views/models.html +32 -36
- package/public/views/settings.html +50 -50
- package/src/account-manager/index.js +0 -4
- package/src/account-manager/rate-limits.js +0 -5
- package/src/account-manager/strategies/base-strategy.js +4 -4
- package/src/account-manager/strategies/hybrid-strategy.js +3 -3
- package/src/auth/database.js +1 -0
- package/src/auth/oauth.js +43 -41
- package/src/auth/token-extractor.js +1 -1
- package/src/cli/accounts.js +2 -1
- package/src/cloudcode/model-registry.js +0 -3
- package/src/cloudcode/rate-limit-state.js +1 -7
- package/src/config.js +1 -1
- package/src/constants.js +0 -2
- package/src/format/content-converter.js +0 -4
- package/src/format/request-converter.js +1 -6
- package/src/format/response-converter.js +0 -3
- package/src/format/schema-sanitizer.js +3 -22
- package/src/format/thinking-utils.js +1 -13
- package/src/index.js +1 -6
- package/src/modules/usage-stats.js +1 -1
- package/src/server.js +1 -28
- package/src/utils/claude-config.js +2 -6
- package/src/utils/native-module-helper.js +0 -4
- package/src/utils/proxy.js +1 -10
- package/src/utils/version-detector.js +14 -5
- package/src/webui/index.js +1 -37
|
@@ -8,23 +8,23 @@ window.translations.tr = {
|
|
|
8
8
|
accounts: "Hesaplar",
|
|
9
9
|
logs: "Günlükler",
|
|
10
10
|
settings: "Ayarlar",
|
|
11
|
-
online: "
|
|
12
|
-
offline: "
|
|
13
|
-
totalAccounts: "
|
|
14
|
-
active: "
|
|
11
|
+
online: "Çevrimiçi",
|
|
12
|
+
offline: "Çevrimdışı",
|
|
13
|
+
totalAccounts: "Toplam hesap",
|
|
14
|
+
active: "Aktif",
|
|
15
15
|
operational: "Çalışıyor",
|
|
16
|
-
rateLimited: "
|
|
16
|
+
rateLimited: "Hız sınırlandı",
|
|
17
17
|
quotasDepleted: "{count}/{total} Kota Tükendi",
|
|
18
|
-
quotasDepletedTitle: "
|
|
18
|
+
quotasDepletedTitle: "Kota tükendi",
|
|
19
19
|
outOfTracked: "{total} Takip Edilen İçinden",
|
|
20
20
|
cooldown: "Soğuma",
|
|
21
21
|
searchPlaceholder: "Modelleri ara...",
|
|
22
22
|
allAccounts: "Tüm Hesaplar",
|
|
23
|
-
stat: "
|
|
24
|
-
modelIdentity: "
|
|
25
|
-
globalQuota: "
|
|
26
|
-
nextReset: "
|
|
27
|
-
distribution: "
|
|
23
|
+
stat: "Durum",
|
|
24
|
+
modelIdentity: "Model kimliği",
|
|
25
|
+
globalQuota: "Genel kota",
|
|
26
|
+
nextReset: "Sonraki sıfırlama",
|
|
27
|
+
distribution: "Hesap dağılımı",
|
|
28
28
|
systemConfig: "Sistem Yapılandırması",
|
|
29
29
|
language: "Dil",
|
|
30
30
|
pollingInterval: "Veri Güncelleme Aralığı",
|
|
@@ -41,14 +41,14 @@ window.translations.tr = {
|
|
|
41
41
|
accountManagement: "Hesap Yönetimi",
|
|
42
42
|
manageTokens: "Google Hesap jetonlarını ve yetkilendirme durumlarını yönet",
|
|
43
43
|
addAccount: "Hesap Ekle",
|
|
44
|
-
status: "
|
|
45
|
-
enabled: "
|
|
46
|
-
health: "
|
|
47
|
-
accountEmail: "
|
|
48
|
-
source: "
|
|
49
|
-
projectId: "
|
|
50
|
-
sessionState: "
|
|
51
|
-
operations: "
|
|
44
|
+
status: "Durum",
|
|
45
|
+
enabled: "Etkin",
|
|
46
|
+
health: "Sağlık",
|
|
47
|
+
accountEmail: "Hesap (e-posta)",
|
|
48
|
+
source: "Kaynak",
|
|
49
|
+
projectId: "Proje ID",
|
|
50
|
+
sessionState: "Oturum durumu",
|
|
51
|
+
operations: "İşlemler",
|
|
52
52
|
delete: "Sil",
|
|
53
53
|
confirmDelete: "Bu hesabı kaldırmak istediğinizden emin misiniz?",
|
|
54
54
|
cannotDeleteDatabase: "Silinemez: Bu hesap Antigravity veritabanından (salt okunur)",
|
|
@@ -72,8 +72,8 @@ window.translations.tr = {
|
|
|
72
72
|
tabServer: "Sunucu Ayarları",
|
|
73
73
|
// Dashboard
|
|
74
74
|
linkedAccounts: "Bağlı Hesaplar",
|
|
75
|
-
noSignal: "
|
|
76
|
-
establishingUplink: "
|
|
75
|
+
noSignal: "Sinyal yok",
|
|
76
|
+
establishingUplink: "Bağlantı kuruluyor...",
|
|
77
77
|
goToAccounts: "Hesaplara Git",
|
|
78
78
|
// Settings - Models
|
|
79
79
|
modelsDesc: "Model görünürlüğünü, sabitlemeyi ve istek yönlendirmeyi yapılandırın.",
|
|
@@ -86,13 +86,12 @@ window.translations.tr = {
|
|
|
86
86
|
actions: "İşlemler",
|
|
87
87
|
pinToTop: "En Üste Sabitle",
|
|
88
88
|
toggleVisibility: "Görünürlüğü Değiştir",
|
|
89
|
-
noModels: "
|
|
89
|
+
noModels: "Model algılanmadı",
|
|
90
90
|
modelMappingHint: "Sunucu tarafı model yönlendirme. Claude Code kullanıcıları: istemci tarafı kurulumu için 'Claude CLI' sekmesine bakın.",
|
|
91
|
-
modelMapping: "Eşleştirme (Hedef Model ID)",
|
|
92
91
|
// Settings - Claude
|
|
93
92
|
proxyConnection: "Proxy Bağlantısı",
|
|
94
93
|
modelSelection: "Model Seçimi",
|
|
95
|
-
defaultModelAliases: "
|
|
94
|
+
defaultModelAliases: "Varsayılan model takma adları",
|
|
96
95
|
opusAlias: "Opus Takma Adı",
|
|
97
96
|
sonnetAlias: "Sonnet Takma Adı",
|
|
98
97
|
haikuAlias: "Haiku Takma Adı",
|
|
@@ -150,20 +149,19 @@ window.translations.tr = {
|
|
|
150
149
|
saveConfig: "Claude CLI ayarlarına kaydet",
|
|
151
150
|
envVar: "Ortam Değişkeni",
|
|
152
151
|
// New Keys
|
|
153
|
-
systemName: "
|
|
154
|
-
systemDesc: "
|
|
152
|
+
systemName: "Antigravity",
|
|
153
|
+
systemDesc: "Claude proxy sistemi",
|
|
155
154
|
connectGoogleDesc: "API kota limitinizi artırmak için bir Google Workspace hesabı bağlayın. Bu hesap, Claude isteklerini Antigravity üzerinden vekil sunucu olarak kullanmak için kullanılacaktır.",
|
|
156
155
|
useCliCommand: "CLI Komutunu Kullan",
|
|
157
156
|
close: "Kapat",
|
|
158
157
|
requestVolume: "İstek Hacmi",
|
|
159
158
|
filter: "Filtrele",
|
|
160
159
|
all: "Tümü",
|
|
161
|
-
none: "Hiçbiri",
|
|
162
160
|
noDataTracked: "Henüz veri izlenmedi",
|
|
163
161
|
selectFamilies: "Görüntülenecek aileleri seçin",
|
|
164
162
|
selectModels: "Görüntülenecek modelleri seçin",
|
|
165
163
|
noLogsMatch: "Filtreyle eşleşen günlük yok",
|
|
166
|
-
connecting: "
|
|
164
|
+
connecting: "Bağlanılıyor",
|
|
167
165
|
main: "Ana",
|
|
168
166
|
system: "Sistem",
|
|
169
167
|
refreshData: "Verileri Yenile",
|
|
@@ -172,7 +170,7 @@ window.translations.tr = {
|
|
|
172
170
|
grepLogs: "günlükleri ara...",
|
|
173
171
|
noMatchingModels: "Eşleşen model yok",
|
|
174
172
|
typeToSearch: "Aramak veya seçmek için yazın...",
|
|
175
|
-
or: "
|
|
173
|
+
or: "veya",
|
|
176
174
|
refreshingAccount: "{email} yenileniyor...",
|
|
177
175
|
refreshedAccount: "{email} yenilendi",
|
|
178
176
|
refreshFailed: "Yenileme başarısız",
|
|
@@ -199,8 +197,8 @@ window.translations.tr = {
|
|
|
199
197
|
claudeEmpty: "Claude Boş",
|
|
200
198
|
geminiActive: "Gemini Aktif",
|
|
201
199
|
geminiEmpty: "Gemini Boş",
|
|
202
|
-
synced: "
|
|
203
|
-
syncing: "
|
|
200
|
+
synced: "Eşitlendi",
|
|
201
|
+
syncing: "Eşitleniyor...",
|
|
204
202
|
// Time range labels
|
|
205
203
|
last1Hour: "Son 1S",
|
|
206
204
|
last6Hours: "Son 6S",
|
|
@@ -216,7 +214,7 @@ window.translations.tr = {
|
|
|
216
214
|
production: "Üretim",
|
|
217
215
|
configSaved: "Yapılandırma Kaydedildi",
|
|
218
216
|
enterPassword: "Web UI Parolasını Girin:",
|
|
219
|
-
ready: "
|
|
217
|
+
ready: "Hazır",
|
|
220
218
|
depleted: "Tükendi",
|
|
221
219
|
timeH: "S",
|
|
222
220
|
timeM: "D",
|
|
@@ -225,19 +223,19 @@ window.translations.tr = {
|
|
|
225
223
|
familyOther: "Diğer",
|
|
226
224
|
enabledStatus: "etkin",
|
|
227
225
|
disabledStatus: "devre dışı",
|
|
228
|
-
logLevelInfo: "
|
|
229
|
-
logLevelSuccess: "
|
|
230
|
-
logLevelWarn: "
|
|
231
|
-
logLevelError: "
|
|
226
|
+
logLevelInfo: "Bilgi",
|
|
227
|
+
logLevelSuccess: "Başarılı",
|
|
228
|
+
logLevelWarn: "Uyarı",
|
|
229
|
+
logLevelError: "Hata",
|
|
232
230
|
totalColon: "Toplam:",
|
|
233
231
|
todayColon: "Bugün:",
|
|
234
232
|
hour1Colon: "1S:",
|
|
235
233
|
frequentModels: "Sık Kullanılan",
|
|
236
234
|
smartTitle: "En çok kullanılan 5 modeli otomatik seç (24s)",
|
|
237
235
|
activeCount: "{count} Aktif",
|
|
238
|
-
allCaps: "
|
|
239
|
-
claudeCaps: "
|
|
240
|
-
geminiCaps: "
|
|
236
|
+
allCaps: "Tümü",
|
|
237
|
+
claudeCaps: "Claude",
|
|
238
|
+
geminiCaps: "Gemini",
|
|
241
239
|
modelMapping: "Eşleştirme (Hedef Model ID)",
|
|
242
240
|
systemInfo: "Sistem Bilgisi",
|
|
243
241
|
refresh: "Yenile",
|
|
@@ -88,7 +88,6 @@ window.translations.zh = {
|
|
|
88
88
|
toggleVisibility: "切换可见性",
|
|
89
89
|
noModels: "未检测到模型",
|
|
90
90
|
modelMappingHint: "服务端模型路由功能。Claude Code 用户请使用 'Claude CLI' 标签页以便捷配置。",
|
|
91
|
-
modelMapping: "映射 (目标模型 ID)",
|
|
92
91
|
// Settings - Claude
|
|
93
92
|
proxyConnection: "代理连接",
|
|
94
93
|
modelSelection: "模型选择",
|
|
@@ -179,7 +178,6 @@ window.translations.zh = {
|
|
|
179
178
|
requestVolume: "请求量",
|
|
180
179
|
filter: "筛选",
|
|
181
180
|
all: "全选",
|
|
182
|
-
none: "清空",
|
|
183
181
|
noDataTracked: "暂无追踪数据",
|
|
184
182
|
selectFamilies: "选择要显示的系列",
|
|
185
183
|
selectModels: "选择要显示的模型",
|
|
@@ -21,7 +21,6 @@ window.ErrorHandler.safeAsync = async function(fn, errorMessage = null, options
|
|
|
21
21
|
try {
|
|
22
22
|
return await fn();
|
|
23
23
|
} catch (error) {
|
|
24
|
-
// Log error for debugging
|
|
25
24
|
console.error(`[ErrorHandler] ${defaultErrorMessage}:`, error);
|
|
26
25
|
|
|
27
26
|
// Show toast notification
|
|
@@ -86,7 +85,6 @@ window.ErrorHandler.withLoading = async function(asyncFn, context, loadingKey =
|
|
|
86
85
|
context[loadingKey] = true;
|
|
87
86
|
|
|
88
87
|
try {
|
|
89
|
-
// Execute the async function with error handling
|
|
90
88
|
const result = await window.ErrorHandler.safeAsync(asyncFn, options.errorMessage, options);
|
|
91
89
|
return result;
|
|
92
90
|
} finally {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
// Check localStorage
|
|
29
29
|
try {
|
|
30
30
|
return localStorage.getItem('ag_debug') === 'true';
|
|
31
|
-
} catch
|
|
31
|
+
} catch {
|
|
32
32
|
return false;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
debugEnabled = true;
|
|
54
54
|
console.info('[UILogger] Debug mode enabled. Refresh page to see all logs.');
|
|
55
55
|
} catch (e) {
|
|
56
|
-
console.warn('[UILogger] Could not save debug preference');
|
|
56
|
+
console.warn('[UILogger] Could not save debug preference', e);
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
debugEnabled = false;
|
|
67
67
|
console.info('[UILogger] Debug mode disabled.');
|
|
68
68
|
} catch (e) {
|
|
69
|
-
|
|
69
|
+
console.warn('[UILogger] Could not clear debug preference', e);
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
*/
|
|
104
104
|
log(...args) {
|
|
105
105
|
if (debugEnabled) {
|
|
106
|
+
// aislop-ignore-next-line console-leftover -- UILogger's own output sink
|
|
106
107
|
console.log(...args);
|
|
107
108
|
}
|
|
108
109
|
},
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
<div x-data="accountManager" class="view-container">
|
|
2
2
|
<!-- Compact Header -->
|
|
3
|
-
<div class="flex items-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<h1 class="text-2xl font-bold text-white tracking-tight" x-text="$store.global.t('accountManagement')">
|
|
3
|
+
<div class="flex items-end justify-between gap-4">
|
|
4
|
+
<div class="flex flex-col gap-1">
|
|
5
|
+
<h1 class="font-display text-[1.5rem] leading-tight font-bold text-white tracking-[-0.01em]" x-text="$store.global.t('accountManagement')">
|
|
7
6
|
Account Management
|
|
8
7
|
</h1>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Manage Google Account tokens and authorization states
|
|
13
|
-
</span>
|
|
14
|
-
</div>
|
|
8
|
+
<p class="text-sm text-gray-500" x-text="$store.global.t('manageTokens')">
|
|
9
|
+
Manage Google Account tokens and authorization states
|
|
10
|
+
</p>
|
|
15
11
|
</div>
|
|
16
12
|
|
|
17
13
|
<!-- Action Buttons -->
|
|
@@ -68,7 +64,7 @@
|
|
|
68
64
|
:class="$store.data.accounts.length >= $store.data.maxAccounts ? 'text-yellow-400' : 'text-gray-400'"
|
|
69
65
|
x-text="$store.data.accounts.length + '/' + $store.data.maxAccounts"></span>
|
|
70
66
|
</div>
|
|
71
|
-
<button class="btn bg-neon-purple hover:bg-
|
|
67
|
+
<button class="btn bg-neon-purple hover:bg-[#7fdbe4] border-none text-space-950 btn-xs gap-2 h-8"
|
|
72
68
|
:class="{ 'opacity-50 cursor-not-allowed': $store.data.accounts.length >= $store.data.maxAccounts }"
|
|
73
69
|
:disabled="$store.data.accounts.length >= $store.data.maxAccounts"
|
|
74
70
|
@click="$store.data.accounts.length < $store.data.maxAccounts && document.getElementById('add_account_modal').showModal()">
|
|
@@ -85,13 +81,13 @@
|
|
|
85
81
|
<table class="w-full">
|
|
86
82
|
<thead x-show="$store.data.accounts.length > 0">
|
|
87
83
|
<tr class="bg-space-900/50 border-b border-space-border/50">
|
|
88
|
-
<th class="pl-6 py-3 text-left text-[
|
|
89
|
-
<th class="py-3 text-left text-[
|
|
90
|
-
<th class="py-3 text-left text-[
|
|
91
|
-
<th class="py-3 text-left text-[
|
|
92
|
-
<th class="py-3 text-left text-[
|
|
93
|
-
<th class="py-3 text-left text-[
|
|
94
|
-
<th class="py-3 pr-6 text-right text-[
|
|
84
|
+
<th class="pl-6 py-3 text-left text-[11px] font-medium text-gray-500 w-16" x-text="$store.global.t('enabled')">Enabled</th>
|
|
85
|
+
<th class="py-3 text-left text-[11px] font-medium text-gray-500 flex-1 min-w-[200px]" x-text="$store.global.t('accountEmail')">Account (Email)</th>
|
|
86
|
+
<th class="py-3 text-left text-[11px] font-medium text-gray-500 w-20" x-text="$store.global.t('source')">Source</th>
|
|
87
|
+
<th class="py-3 text-left text-[11px] font-medium text-gray-500 w-16" x-text="$store.global.t('tier')">Tier</th>
|
|
88
|
+
<th class="py-3 text-left text-[11px] font-medium text-gray-500 w-32" x-text="$store.global.t('quota')">Quota</th>
|
|
89
|
+
<th class="py-3 text-left text-[11px] font-medium text-gray-500 w-24" x-text="$store.global.t('health')">Health</th>
|
|
90
|
+
<th class="py-3 pr-6 text-right text-[11px] font-medium text-gray-500 w-32" x-text="$store.global.t('operations')">Operations</th>
|
|
95
91
|
</tr>
|
|
96
92
|
</thead>
|
|
97
93
|
<tbody>
|
|
@@ -111,7 +107,7 @@
|
|
|
111
107
|
Get started by adding a Google account via OAuth, or use the CLI command to import credentials.
|
|
112
108
|
</p>
|
|
113
109
|
<div class="flex items-center gap-4 mt-2">
|
|
114
|
-
<button class="btn bg-neon-purple hover:bg-
|
|
110
|
+
<button class="btn bg-neon-purple hover:bg-[#7fdbe4] border-none text-space-950 btn-sm gap-2"
|
|
115
111
|
onclick="document.getElementById('add_account_modal').showModal()">
|
|
116
112
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
117
113
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
|
@@ -181,7 +177,7 @@
|
|
|
181
177
|
<span class="text-xs text-gray-600">-</span>
|
|
182
178
|
</template>
|
|
183
179
|
<div x-show="acc.quotaThreshold !== undefined"
|
|
184
|
-
class="text-[
|
|
180
|
+
class="text-[11px] font-mono text-neon-yellow/60 mt-0.5"
|
|
185
181
|
x-text="'min: ' + getEffectiveThreshold(acc)"></div>
|
|
186
182
|
</div>
|
|
187
183
|
</td>
|
|
@@ -199,7 +195,7 @@
|
|
|
199
195
|
x-text="acc.status.toUpperCase()">
|
|
200
196
|
</span>
|
|
201
197
|
<p x-show="acc.status === 'banned'"
|
|
202
|
-
class="text-[
|
|
198
|
+
class="text-[10px] text-red-600/70 mt-0.5 max-w-[200px] leading-tight"
|
|
203
199
|
x-text="acc.error || 'Gemini disabled for ToS violation'">
|
|
204
200
|
</p>
|
|
205
201
|
</div>
|
|
@@ -208,7 +204,7 @@
|
|
|
208
204
|
<div class="flex justify-end gap-2">
|
|
209
205
|
<!-- Fix Button -->
|
|
210
206
|
<button x-show="acc.status === 'invalid'"
|
|
211
|
-
class="px-3 py-1 text-[
|
|
207
|
+
class="px-3 py-1 text-[11px] font-medium rounded bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20 border border-yellow-500/30 hover:border-yellow-500/50 transition-all"
|
|
212
208
|
@click="fixAccount(acc.email)"
|
|
213
209
|
x-text="$store.global.t('fix')">
|
|
214
210
|
FIX
|
|
@@ -216,7 +212,7 @@
|
|
|
216
212
|
<!-- Appeal Button (banned accounts only) -->
|
|
217
213
|
<a x-show="acc.status === 'banned'"
|
|
218
214
|
href="mailto:gemini-code-assist-user-feedback@google.com"
|
|
219
|
-
class="px-3 py-1 text-[
|
|
215
|
+
class="px-3 py-1 text-[11px] font-medium rounded bg-red-900/20 text-red-400 hover:bg-red-900/30 border border-red-800/30 hover:border-red-800/50 transition-all"
|
|
220
216
|
title="Email Google to appeal this ban">
|
|
221
217
|
APPEAL
|
|
222
218
|
</a>
|
|
@@ -293,7 +289,7 @@
|
|
|
293
289
|
<button class="w-full flex items-center justify-between px-6 py-3 bg-space-900/50 border-b border-space-border/50 hover:bg-space-900/70 transition-colors"
|
|
294
290
|
@click="$store.settings.toggle('healthInspectorOpen'); if ($store.settings.healthInspectorOpen && !healthData.strategy) fetchHealthData()">
|
|
295
291
|
<div class="flex items-center gap-3">
|
|
296
|
-
<span class="text-[
|
|
292
|
+
<span class="text-[10px] font-medium px-1.5 py-0.5 rounded bg-neon-purple/20 text-neon-purple border border-neon-purple/30">DEV</span>
|
|
297
293
|
<span class="text-sm font-semibold text-gray-300" x-text="$store.global.t('strategyHealthInspector')">Strategy Health Inspector</span>
|
|
298
294
|
</div>
|
|
299
295
|
<svg class="w-4 h-4 text-gray-500 transition-transform" :class="{ 'rotate-180': $store.settings.healthInspectorOpen }"
|
|
@@ -331,14 +327,14 @@
|
|
|
331
327
|
<table class="w-full">
|
|
332
328
|
<thead>
|
|
333
329
|
<tr class="border-b border-space-border/50">
|
|
334
|
-
<th class="py-2 text-left text-[
|
|
335
|
-
<th class="py-2 text-left text-[
|
|
330
|
+
<th class="py-2 text-left text-[11px] font-medium text-gray-500">Email</th>
|
|
331
|
+
<th class="py-2 text-left text-[11px] font-medium text-gray-500 w-40"
|
|
336
332
|
x-text="$store.global.t('healthScore')">Health Score</th>
|
|
337
|
-
<th class="py-2 text-left text-[
|
|
333
|
+
<th class="py-2 text-left text-[11px] font-medium text-gray-500 w-28"
|
|
338
334
|
x-text="$store.global.t('tokenBucket')">Tokens</th>
|
|
339
|
-
<th class="py-2 text-left text-[
|
|
335
|
+
<th class="py-2 text-left text-[11px] font-medium text-gray-500 w-20"
|
|
340
336
|
x-text="$store.global.t('consecutiveFailures')">Failures</th>
|
|
341
|
-
<th class="py-2 text-left text-[
|
|
337
|
+
<th class="py-2 text-left text-[11px] font-medium text-gray-500 w-20">Status</th>
|
|
342
338
|
</tr>
|
|
343
339
|
</thead>
|
|
344
340
|
<tbody>
|
|
@@ -375,7 +371,7 @@
|
|
|
375
371
|
x-text="acc.consecutiveFailures"></span>
|
|
376
372
|
</td>
|
|
377
373
|
<td class="py-2">
|
|
378
|
-
<span class="text-[
|
|
374
|
+
<span class="text-[11px] font-medium capitalize px-1.5 py-0.5 rounded"
|
|
379
375
|
:class="acc.isUsable ? 'bg-neon-green/10 text-neon-green border border-neon-green/20' : 'bg-red-500/10 text-red-400 border border-red-500/20'"
|
|
380
376
|
x-text="acc.isUsable ? 'OK' : 'DEGRADED'"></span>
|
|
381
377
|
</td>
|
|
@@ -387,7 +383,7 @@
|
|
|
387
383
|
|
|
388
384
|
<!-- Scoring reference -->
|
|
389
385
|
<div x-show="healthData.trackers !== null && healthData.trackers?.accounts?.length > 0" class="mt-3 px-3 py-2 rounded bg-space-900/40 border border-space-border/30">
|
|
390
|
-
<p class="text-[
|
|
386
|
+
<p class="text-[11px] text-gray-500 font-mono leading-relaxed">
|
|
391
387
|
Score is adjusted for successes, rate limits, and failures with passive recovery.
|
|
392
388
|
<br>
|
|
393
389
|
Selection uses weighted health, token usage, quota, and recency (LRU).
|
|
@@ -444,7 +440,7 @@
|
|
|
444
440
|
</dialog>
|
|
445
441
|
|
|
446
442
|
<!-- Quota Distribution Modal -->
|
|
447
|
-
<dialog id="quota_modal" class="modal
|
|
443
|
+
<dialog id="quota_modal" class="modal">
|
|
448
444
|
<div class="modal-box max-w-2xl w-full bg-space-900 border border-space-border text-gray-300 shadow-2xl p-6">
|
|
449
445
|
<h3 class="font-bold text-xl text-white mb-2 flex items-center gap-2">
|
|
450
446
|
<svg class="w-6 h-6 text-neon-cyan" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
@@ -474,9 +470,9 @@
|
|
|
474
470
|
</div>
|
|
475
471
|
|
|
476
472
|
<div class="flex justify-between items-center">
|
|
477
|
-
<span class="text-[
|
|
473
|
+
<span class="text-[11px] text-gray-500 capitalize font-medium" x-text="$store.data.getModelFamily(modelId)"></span>
|
|
478
474
|
<template x-if="limit.resetTime">
|
|
479
|
-
<span class="text-[
|
|
475
|
+
<span class="text-[11px] text-yellow-500/80 font-mono italic"
|
|
480
476
|
x-text="$store.global.t('resetsIn', { time: window.utils.formatTimeUntil(limit.resetTime) })"></span>
|
|
481
477
|
</template>
|
|
482
478
|
</div>
|
|
@@ -502,7 +498,7 @@
|
|
|
502
498
|
</dialog>
|
|
503
499
|
|
|
504
500
|
<!-- Threshold Settings Modal -->
|
|
505
|
-
<dialog id="threshold_modal" class="modal
|
|
501
|
+
<dialog id="threshold_modal" class="modal">
|
|
506
502
|
<div class="modal-box max-w-md w-full bg-space-900 border border-space-border text-gray-300 shadow-2xl p-6">
|
|
507
503
|
<h3 class="font-bold text-xl text-white mb-2 flex items-center gap-2">
|
|
508
504
|
<svg class="w-6 h-6 text-neon-yellow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
@@ -546,7 +542,7 @@
|
|
|
546
542
|
<span class="text-gray-500 text-xs">%</span>
|
|
547
543
|
</div>
|
|
548
544
|
</div>
|
|
549
|
-
<p class="text-[
|
|
545
|
+
<p class="text-[11px] text-gray-600 mt-1">
|
|
550
546
|
Leave empty to use the global threshold from Settings.
|
|
551
547
|
</p>
|
|
552
548
|
</div>
|
|
@@ -585,7 +581,7 @@
|
|
|
585
581
|
:value="threshold"
|
|
586
582
|
@input="updateModelThreshold(modelId, $event.target.value)"
|
|
587
583
|
aria-label="Model threshold">
|
|
588
|
-
<span class="text-gray-500 text-[
|
|
584
|
+
<span class="text-gray-500 text-[11px]">%</span>
|
|
589
585
|
</div>
|
|
590
586
|
<button class="btn btn-xs btn-ghost text-gray-500 hover:text-red-400 px-1"
|
|
591
587
|
@click="removeModelThreshold(modelId)">
|
|
@@ -597,7 +593,7 @@
|
|
|
597
593
|
</template>
|
|
598
594
|
|
|
599
595
|
<template x-if="Object.keys(thresholdDialog.modelQuotaThresholds).length === 0">
|
|
600
|
-
<p class="text-[
|
|
596
|
+
<p class="text-[11px] text-gray-600 text-center py-2">
|
|
601
597
|
No per-model overrides configured.
|
|
602
598
|
</p>
|
|
603
599
|
</template>
|