@jxgame2020/dsh-token-quota 0.1.39 → 0.1.40
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/lib/client.js +125 -133
- package/lib/index.js +49 -27
- package/lib/types/client/TokenQuotaPanel.js +6 -5
- package/lib/types/index.d.ts +9 -1
- package/lib/types/index.js +68 -26
- package/lib/types/types.d.ts +0 -6
- package/lib/types/types.js +0 -6
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -7,14 +7,6 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
9
|
let react = require("react");
|
|
10
|
-
//#region lib/types/types.js
|
|
11
|
-
/**
|
|
12
|
-
* Provider route keys the host knows how to query for account balance. A
|
|
13
|
-
* directory provider outside this list renders as "not integrated for query"
|
|
14
|
-
* in the balance window.
|
|
15
|
-
*/
|
|
16
|
-
const TOKEN_QUOTA_BALANCE_PROVIDERS = ["deepseek"];
|
|
17
|
-
//#endregion
|
|
18
10
|
//#region lib/types/client/store.js
|
|
19
11
|
/**
|
|
20
12
|
* Token-quota panel store: the shared, remount-surviving view state. The
|
|
@@ -123,7 +115,7 @@ window.__ModuleLoader__.load({
|
|
|
123
115
|
d.musicOnlyCurrentSession = only;
|
|
124
116
|
},
|
|
125
117
|
setUpgrade: (d, upgrade) => {
|
|
126
|
-
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.
|
|
118
|
+
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.40" ? upgrade : null;
|
|
127
119
|
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
|
|
128
120
|
d.upgrade = normalized;
|
|
129
121
|
},
|
|
@@ -253,142 +245,142 @@ window.__ModuleLoader__.load({
|
|
|
253
245
|
document.head.appendChild(tag);
|
|
254
246
|
}
|
|
255
247
|
var TokenQuotaPanel_module_css_default = {
|
|
256
|
-
"
|
|
257
|
-
"selectBtn": "NPLLIq_selectBtn",
|
|
258
|
-
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
259
|
-
"fillIdle": "NPLLIq_fillIdle",
|
|
260
|
-
"balanceBarText": "NPLLIq_balanceBarText",
|
|
261
|
-
"balanceWinBody": "NPLLIq_balanceWinBody",
|
|
262
|
-
"monitorRow": "NPLLIq_monitorRow",
|
|
263
|
-
"resetSelect": "NPLLIq_resetSelect",
|
|
264
|
-
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
265
|
-
"rowDrag": "NPLLIq_rowDrag",
|
|
266
|
-
"logClearDate": "NPLLIq_logClearDate",
|
|
267
|
-
"headerText": "NPLLIq_headerText",
|
|
268
|
-
"noteWinBtn": "NPLLIq_noteWinBtn",
|
|
269
|
-
"fillOver": "NPLLIq_fillOver",
|
|
270
|
-
"copyBtn": "NPLLIq_copyBtn",
|
|
271
|
-
"balanceBarLow": "NPLLIq_balanceBarLow",
|
|
272
|
-
"switch": "NPLLIq_switch",
|
|
273
|
-
"dialogHeader": "NPLLIq_dialogHeader",
|
|
274
|
-
"logSearch": "NPLLIq_logSearch",
|
|
248
|
+
"noteWinResize": "NPLLIq_noteWinResize",
|
|
275
249
|
"dialogClose": "NPLLIq_dialogClose",
|
|
276
|
-
"
|
|
277
|
-
"
|
|
278
|
-
"logPagerControls": "NPLLIq_logPagerControls",
|
|
279
|
-
"versionNew": "NPLLIq_versionNew",
|
|
280
|
-
"headerActions": "NPLLIq_headerActions",
|
|
281
|
-
"logPager": "NPLLIq_logPager",
|
|
282
|
-
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
283
|
-
"logScroll": "NPLLIq_logScroll",
|
|
284
|
-
"balanceRefreshAll": "NPLLIq_balanceRefreshAll",
|
|
285
|
-
"noteWinTitle": "NPLLIq_noteWinTitle",
|
|
286
|
-
"logDialog": "NPLLIq_logDialog",
|
|
287
|
-
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
288
|
-
"resetRow": "NPLLIq_resetRow",
|
|
289
|
-
"noteWinText": "NPLLIq_noteWinText",
|
|
290
|
-
"save": "NPLLIq_save",
|
|
291
|
-
"balanceBarError": "NPLLIq_balanceBarError",
|
|
292
|
-
"row": "NPLLIq_row",
|
|
293
|
-
"checkBtn": "NPLLIq_checkBtn",
|
|
294
|
-
"balanceValueLow": "NPLLIq_balanceValueLow",
|
|
295
|
-
"notesBar": "NPLLIq_notesBar",
|
|
296
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
297
|
-
"logDayCol": "NPLLIq_logDayCol",
|
|
298
|
-
"bar": "NPLLIq_bar",
|
|
299
|
-
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
300
|
-
"noteNew": "NPLLIq_noteNew",
|
|
301
|
-
"logModelCol": "NPLLIq_logModelCol",
|
|
302
|
-
"logTable": "NPLLIq_logTable",
|
|
250
|
+
"balanceStateHint": "NPLLIq_balanceStateHint",
|
|
251
|
+
"panel": "NPLLIq_panel",
|
|
303
252
|
"noteMenuBackdrop": "NPLLIq_noteMenuBackdrop",
|
|
304
|
-
"
|
|
305
|
-
"
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
253
|
+
"notesBar": "NPLLIq_notesBar",
|
|
254
|
+
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
255
|
+
"balanceWinHeader": "NPLLIq_balanceWinHeader",
|
|
256
|
+
"balanceRowValue": "NPLLIq_balanceRowValue",
|
|
257
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
258
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
259
|
+
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
260
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
309
261
|
"fillWarn": "NPLLIq_fillWarn",
|
|
310
|
-
"
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
"
|
|
314
|
-
"subtitle": "NPLLIq_subtitle",
|
|
315
|
-
"dialog": "NPLLIq_dialog",
|
|
316
|
-
"controls": "NPLLIq_controls",
|
|
317
|
-
"noticeError": "NPLLIq_noticeError",
|
|
318
|
-
"tabLabel": "NPLLIq_tabLabel",
|
|
319
|
-
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
320
|
-
"balanceStateError": "NPLLIq_balanceStateError",
|
|
321
|
-
"logHeader": "NPLLIq_logHeader",
|
|
322
|
-
"logClearDialog": "NPLLIq_logClearDialog",
|
|
323
|
-
"logClearBtn": "NPLLIq_logClearBtn",
|
|
324
|
-
"noteWinGripBar": "NPLLIq_noteWinGripBar",
|
|
325
|
-
"noteWinResize": "NPLLIq_noteWinResize",
|
|
326
|
-
"collapse": "NPLLIq_collapse",
|
|
327
|
-
"monitorHint": "NPLLIq_monitorHint",
|
|
262
|
+
"logDialog": "NPLLIq_logDialog",
|
|
263
|
+
"balanceRowHeader": "NPLLIq_balanceRowHeader",
|
|
264
|
+
"monitorRow": "NPLLIq_monitorRow",
|
|
265
|
+
"logPager": "NPLLIq_logPager",
|
|
328
266
|
"title": "NPLLIq_title",
|
|
329
|
-
"
|
|
267
|
+
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
268
|
+
"balanceRowRefresh": "NPLLIq_balanceRowRefresh",
|
|
269
|
+
"balanceToggle": "NPLLIq_balanceToggle",
|
|
270
|
+
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
271
|
+
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
330
272
|
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
273
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
274
|
+
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
275
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
331
276
|
"noteWinTitleText": "NPLLIq_noteWinTitleText",
|
|
332
|
-
"
|
|
333
|
-
"
|
|
334
|
-
"
|
|
335
|
-
"
|
|
336
|
-
"
|
|
337
|
-
"
|
|
338
|
-
"
|
|
339
|
-
"
|
|
340
|
-
"
|
|
341
|
-
"
|
|
342
|
-
"
|
|
343
|
-
"balanceWin": "NPLLIq_balanceWin",
|
|
344
|
-
"balanceWinTitle": "NPLLIq_balanceWinTitle",
|
|
345
|
-
"balanceBar": "NPLLIq_balanceBar",
|
|
346
|
-
"balanceRowName": "NPLLIq_balanceRowName",
|
|
347
|
-
"dialogTabs": "NPLLIq_dialogTabs",
|
|
348
|
-
"noteMenu": "NPLLIq_noteMenu",
|
|
277
|
+
"balanceBarBadge": "NPLLIq_balanceBarBadge",
|
|
278
|
+
"controls": "NPLLIq_controls",
|
|
279
|
+
"upgradeHint": "NPLLIq_upgradeHint",
|
|
280
|
+
"resetRow": "NPLLIq_resetRow",
|
|
281
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
282
|
+
"rowDrag": "NPLLIq_rowDrag",
|
|
283
|
+
"balanceBarLow": "NPLLIq_balanceBarLow",
|
|
284
|
+
"bar": "NPLLIq_bar",
|
|
285
|
+
"panelDim": "NPLLIq_panelDim",
|
|
286
|
+
"noteMenuItem": "NPLLIq_noteMenuItem",
|
|
287
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
349
288
|
"rowDragging": "NPLLIq_rowDragging",
|
|
289
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
290
|
+
"rowMeta": "NPLLIq_rowMeta",
|
|
350
291
|
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
351
|
-
"
|
|
352
|
-
"
|
|
353
|
-
"
|
|
292
|
+
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
293
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
294
|
+
"balanceBarRefresh": "NPLLIq_balanceBarRefresh",
|
|
295
|
+
"header": "NPLLIq_header",
|
|
296
|
+
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
354
297
|
"logPagerPages": "NPLLIq_logPagerPages",
|
|
355
|
-
"
|
|
356
|
-
"
|
|
298
|
+
"noteNewPlus": "NPLLIq_noteNewPlus",
|
|
299
|
+
"balanceToggleOpen": "NPLLIq_balanceToggleOpen",
|
|
300
|
+
"logTable": "NPLLIq_logTable",
|
|
301
|
+
"version": "NPLLIq_version",
|
|
302
|
+
"settingsBtn": "NPLLIq_settingsBtn",
|
|
357
303
|
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
358
|
-
"
|
|
359
|
-
"
|
|
360
|
-
"
|
|
361
|
-
"
|
|
304
|
+
"balanceValueOk": "NPLLIq_balanceValueOk",
|
|
305
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
306
|
+
"noteWinTitle": "NPLLIq_noteWinTitle",
|
|
307
|
+
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
308
|
+
"noteMenu": "NPLLIq_noteMenu",
|
|
309
|
+
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
310
|
+
"dialogTabs": "NPLLIq_dialogTabs",
|
|
311
|
+
"balanceRow": "NPLLIq_balanceRow",
|
|
312
|
+
"logPagerControls": "NPLLIq_logPagerControls",
|
|
313
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
314
|
+
"noticeError": "NPLLIq_noticeError",
|
|
315
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
316
|
+
"tab": "NPLLIq_tab",
|
|
317
|
+
"dialog": "NPLLIq_dialog",
|
|
318
|
+
"balanceSortBtn": "NPLLIq_balanceSortBtn",
|
|
319
|
+
"fillOver": "NPLLIq_fillOver",
|
|
362
320
|
"dialogBtn": "NPLLIq_dialogBtn",
|
|
363
|
-
"
|
|
364
|
-
"
|
|
365
|
-
"
|
|
321
|
+
"noteWin": "NPLLIq_noteWin",
|
|
322
|
+
"save": "NPLLIq_save",
|
|
323
|
+
"dialogTab": "NPLLIq_dialogTab",
|
|
324
|
+
"noteWinText": "NPLLIq_noteWinText",
|
|
325
|
+
"balanceWin": "NPLLIq_balanceWin",
|
|
326
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
327
|
+
"monitorName": "NPLLIq_monitorName",
|
|
328
|
+
"tabIcon": "NPLLIq_tabIcon",
|
|
329
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
366
330
|
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
367
|
-
"
|
|
368
|
-
"fullNotice": "NPLLIq_fullNotice",
|
|
369
|
-
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
370
|
-
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
371
|
-
"balanceRowValue": "NPLLIq_balanceRowValue",
|
|
372
|
-
"balanceToggle": "NPLLIq_balanceToggle",
|
|
373
|
-
"rowMeta": "NPLLIq_rowMeta",
|
|
374
|
-
"balanceBarRefresh": "NPLLIq_balanceBarRefresh",
|
|
375
|
-
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
331
|
+
"body": "NPLLIq_body",
|
|
376
332
|
"rowName": "NPLLIq_rowName",
|
|
377
|
-
"
|
|
378
|
-
"
|
|
379
|
-
"
|
|
380
|
-
"
|
|
381
|
-
"
|
|
382
|
-
"
|
|
383
|
-
"
|
|
384
|
-
"upgradeClose": "NPLLIq_upgradeClose",
|
|
385
|
-
"tab": "NPLLIq_tab",
|
|
333
|
+
"collapse": "NPLLIq_collapse",
|
|
334
|
+
"dialogHeader": "NPLLIq_dialogHeader",
|
|
335
|
+
"balanceWinBody": "NPLLIq_balanceWinBody",
|
|
336
|
+
"balanceBarDim": "NPLLIq_balanceBarDim",
|
|
337
|
+
"noteWinCollapsed": "NPLLIq_noteWinCollapsed",
|
|
338
|
+
"switch": "NPLLIq_switch",
|
|
339
|
+
"rowDropTarget": "NPLLIq_rowDropTarget",
|
|
386
340
|
"dialogTitle": "NPLLIq_dialogTitle",
|
|
387
|
-
"
|
|
341
|
+
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
388
342
|
"dialogBody": "NPLLIq_dialogBody",
|
|
389
|
-
"
|
|
390
|
-
"
|
|
391
|
-
"
|
|
343
|
+
"balanceBarText": "NPLLIq_balanceBarText",
|
|
344
|
+
"settingsDialog": "NPLLIq_settingsDialog",
|
|
345
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
346
|
+
"logHeader": "NPLLIq_logHeader",
|
|
347
|
+
"balanceBar": "NPLLIq_balanceBar",
|
|
348
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
349
|
+
"balanceBarError": "NPLLIq_balanceBarError",
|
|
350
|
+
"monitorList": "NPLLIq_monitorList",
|
|
351
|
+
"balanceRefreshAll": "NPLLIq_balanceRefreshAll",
|
|
352
|
+
"dialogSection": "NPLLIq_dialogSection",
|
|
353
|
+
"balanceValueError": "NPLLIq_balanceValueError",
|
|
354
|
+
"balanceLastLine": "NPLLIq_balanceLastLine",
|
|
355
|
+
"upgradeClose": "NPLLIq_upgradeClose",
|
|
356
|
+
"notice": "NPLLIq_notice",
|
|
357
|
+
"balanceStateError": "NPLLIq_balanceStateError",
|
|
358
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
359
|
+
"noteChipOpen": "NPLLIq_noteChipOpen",
|
|
360
|
+
"versionNew": "NPLLIq_versionNew",
|
|
361
|
+
"balanceRowName": "NPLLIq_balanceRowName",
|
|
362
|
+
"headerText": "NPLLIq_headerText",
|
|
363
|
+
"row": "NPLLIq_row",
|
|
364
|
+
"input": "NPLLIq_input",
|
|
365
|
+
"balanceWinTitle": "NPLLIq_balanceWinTitle",
|
|
366
|
+
"headerActions": "NPLLIq_headerActions",
|
|
367
|
+
"noteWinBtn": "NPLLIq_noteWinBtn",
|
|
368
|
+
"radioRow": "NPLLIq_radioRow",
|
|
369
|
+
"balanceValueLow": "NPLLIq_balanceValueLow",
|
|
370
|
+
"gearBtn": "NPLLIq_gearBtn",
|
|
371
|
+
"dialogLabel": "NPLLIq_dialogLabel",
|
|
372
|
+
"logScroll": "NPLLIq_logScroll",
|
|
373
|
+
"noteWinGripBar": "NPLLIq_noteWinGripBar",
|
|
374
|
+
"noteWinBar": "NPLLIq_noteWinBar",
|
|
375
|
+
"subtitle": "NPLLIq_subtitle",
|
|
376
|
+
"copyBtn": "NPLLIq_copyBtn",
|
|
377
|
+
"selectBtn": "NPLLIq_selectBtn",
|
|
378
|
+
"logSearch": "NPLLIq_logSearch",
|
|
379
|
+
"logClearDialog": "NPLLIq_logClearDialog",
|
|
380
|
+
"noteNew": "NPLLIq_noteNew",
|
|
381
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
382
|
+
"logToolbar": "NPLLIq_logToolbar",
|
|
383
|
+
"noteChip": "NPLLIq_noteChip"
|
|
392
384
|
};
|
|
393
385
|
//#endregion
|
|
394
386
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -879,7 +871,7 @@ window.__ModuleLoader__.load({
|
|
|
879
871
|
for (const provider of providers) {
|
|
880
872
|
const bal = balances.find((b) => b.provider === provider);
|
|
881
873
|
if (bal !== void 0) map.set(provider, bal);
|
|
882
|
-
else if (
|
|
874
|
+
else if (balances.length === 0) map.set(provider, "loading");
|
|
883
875
|
else map.set(provider, "unsupported");
|
|
884
876
|
}
|
|
885
877
|
return map;
|
|
@@ -1058,13 +1050,13 @@ window.__ModuleLoader__.load({
|
|
|
1058
1050
|
title: t("upgradeAvailableHint"),
|
|
1059
1051
|
children: [
|
|
1060
1052
|
"v",
|
|
1061
|
-
"0.1.
|
|
1053
|
+
"0.1.40",
|
|
1062
1054
|
" → v",
|
|
1063
1055
|
upgrade.latestVersion
|
|
1064
1056
|
]
|
|
1065
1057
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
1066
1058
|
className: TokenQuotaPanel_module_css_default.version,
|
|
1067
|
-
children: ["v", "0.1.
|
|
1059
|
+
children: ["v", "0.1.40"]
|
|
1068
1060
|
})]
|
|
1069
1061
|
})
|
|
1070
1062
|
}),
|
package/lib/index.js
CHANGED
|
@@ -276,23 +276,8 @@ function defaultStoragePath() {
|
|
|
276
276
|
function usageTokens(usage) {
|
|
277
277
|
return usage.inputTokens + (usage.cacheReadTokens ?? 0) + (usage.cacheWriteTokens ?? 0) + usage.outputTokens;
|
|
278
278
|
}
|
|
279
|
-
/**
|
|
280
|
-
|
|
281
|
-
*
|
|
282
|
-
* Mount it beside the other rows (`@jxgame2020/dsh-token-quota`) and write
|
|
283
|
-
* per-model limits through the `token-quota` settings namespace.
|
|
284
|
-
*/
|
|
285
|
-
/**
|
|
286
|
-
* Providers the host can query for account balance, keyed by route key. Each
|
|
287
|
-
* entry names the credential reference (environment-variable name), the
|
|
288
|
-
* balance endpoint base, and the optional `*_BASE_URL` override variable.
|
|
289
|
-
* Directory providers outside this map render as "not integrated for query".
|
|
290
|
-
*/
|
|
291
|
-
const BALANCE_SOURCES = { deepseek: {
|
|
292
|
-
keyEnv: "DEEPSEEK_API_KEY",
|
|
293
|
-
baseURL: "https://api.deepseek.com",
|
|
294
|
-
baseEnv: "DEEPSEEK_BASE_URL"
|
|
295
|
-
} };
|
|
279
|
+
/** DeepSeek's public API host; used to recognise DeepSeek-family providers. */
|
|
280
|
+
const DEEPSEEK_BALANCE_HOST = "api.deepseek.com";
|
|
296
281
|
var TokenQuotaService = class TokenQuotaService extends Service {
|
|
297
282
|
static Config = z.object({ storagePath: z.string().default("") });
|
|
298
283
|
storagePath;
|
|
@@ -525,7 +510,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
525
510
|
if (typeof parsed === "object" && parsed !== null && typeof parsed.provider === "string") provider = parsed.provider;
|
|
526
511
|
}
|
|
527
512
|
} catch {}
|
|
528
|
-
(provider !== void 0
|
|
513
|
+
(provider !== void 0 ? this.refreshProviderBalance(provider) : this.refreshAllBalances()).finally(() => {
|
|
529
514
|
const body = JSON.stringify(this.readSnapshot());
|
|
530
515
|
res.writeHead(200, {
|
|
531
516
|
"content-type": "application/json",
|
|
@@ -619,7 +604,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
619
604
|
return this.upgradeCheck;
|
|
620
605
|
}
|
|
621
606
|
async doRefreshUpgrade() {
|
|
622
|
-
const current = "0.1.
|
|
607
|
+
const current = "0.1.40";
|
|
623
608
|
let latest;
|
|
624
609
|
try {
|
|
625
610
|
const response = await fetch(REGISTRY_LATEST_URL, {
|
|
@@ -692,9 +677,46 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
692
677
|
};
|
|
693
678
|
schedule();
|
|
694
679
|
}
|
|
695
|
-
/** Refresh every provider
|
|
680
|
+
/** Refresh every DeepSeek-family provider found in the model directory. */
|
|
696
681
|
refreshAllBalances() {
|
|
697
|
-
return Promise.all(
|
|
682
|
+
return Promise.all([...this.discoverBalanceSources().values()].map((source) => this.refreshProviderBalance(source.provider, source))).then(() => void 0);
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Discover every provider in the model directory that looks like DeepSeek,
|
|
686
|
+
* together with its own credential reference and endpoint base. This is what
|
|
687
|
+
* decides which providers are queried: a provider qualifies when its base URL
|
|
688
|
+
* points at DeepSeek's API host or its credential reference is named with the
|
|
689
|
+
* `DEEPSEEK` prefix, and it must declare an `apiKeyEnv`.
|
|
690
|
+
*/
|
|
691
|
+
discoverBalanceSources() {
|
|
692
|
+
const found = /* @__PURE__ */ new Map();
|
|
693
|
+
const llm = this.ctx.get("llm");
|
|
694
|
+
const settings = this.ctx.get("settings");
|
|
695
|
+
const fallback = () => ({
|
|
696
|
+
provider: "deepseek",
|
|
697
|
+
keyEnv: "DEEPSEEK_API_KEY",
|
|
698
|
+
baseURL: process.env.DEEPSEEK_BASE_URL ?? `https://${DEEPSEEK_BALANCE_HOST}`
|
|
699
|
+
});
|
|
700
|
+
if (llm?.listConfigurableProviders === void 0) {
|
|
701
|
+
found.set("deepseek", fallback());
|
|
702
|
+
return found;
|
|
703
|
+
}
|
|
704
|
+
for (const entry of llm.listConfigurableProviders()) try {
|
|
705
|
+
let profile = settings?.get(entry.settingsNs);
|
|
706
|
+
for (const segment of entry.settingsPath ?? []) profile = profile !== null && typeof profile === "object" ? profile[segment] : void 0;
|
|
707
|
+
if (profile === null || typeof profile !== "object") continue;
|
|
708
|
+
const record = profile;
|
|
709
|
+
const keyEnv = typeof record.apiKeyEnv === "string" && record.apiKeyEnv !== "" ? record.apiKeyEnv : void 0;
|
|
710
|
+
const baseURL = typeof record.baseURL === "string" && record.baseURL !== "" ? record.baseURL : void 0;
|
|
711
|
+
if (!(baseURL !== void 0 && baseURL.includes(DEEPSEEK_BALANCE_HOST) || keyEnv !== void 0 && keyEnv.startsWith("DEEPSEEK") || entry.provider.startsWith("deepseek")) || keyEnv === void 0) continue;
|
|
712
|
+
found.set(entry.provider, {
|
|
713
|
+
provider: entry.provider,
|
|
714
|
+
keyEnv,
|
|
715
|
+
baseURL: baseURL ?? `https://${DEEPSEEK_BALANCE_HOST}`
|
|
716
|
+
});
|
|
717
|
+
} catch {}
|
|
718
|
+
if (found.size === 0) found.set("deepseek", fallback());
|
|
719
|
+
return found;
|
|
698
720
|
}
|
|
699
721
|
/**
|
|
700
722
|
* Refresh one provider's cached account balance. The API key is resolved
|
|
@@ -702,9 +724,9 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
702
724
|
* environment as a fallback, so the Models page key is used with nothing to
|
|
703
725
|
* type. A failed fetch keeps the previous value and marks it as an error.
|
|
704
726
|
*/
|
|
705
|
-
async refreshProviderBalance(provider) {
|
|
706
|
-
const
|
|
707
|
-
if (
|
|
727
|
+
async refreshProviderBalance(provider, source) {
|
|
728
|
+
const resolved = source ?? this.discoverBalanceSources().get(provider);
|
|
729
|
+
if (resolved === void 0) return;
|
|
708
730
|
const existing = this.balanceFetches.get(provider);
|
|
709
731
|
if (existing !== void 0) return existing;
|
|
710
732
|
const run = async () => {
|
|
@@ -712,9 +734,9 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
712
734
|
const credentials = this.ctx.get("credentials");
|
|
713
735
|
let key;
|
|
714
736
|
if (credentials !== void 0) try {
|
|
715
|
-
key = (await credentials.resolve(
|
|
737
|
+
key = (await credentials.resolve(resolved.keyEnv))?.value;
|
|
716
738
|
} catch {}
|
|
717
|
-
if (key === void 0 || key === "") key = process.env[
|
|
739
|
+
if (key === void 0 || key === "") key = process.env[resolved.keyEnv];
|
|
718
740
|
if (key === void 0 || key === "") {
|
|
719
741
|
this.balances.set(provider, {
|
|
720
742
|
provider,
|
|
@@ -726,7 +748,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
726
748
|
});
|
|
727
749
|
return;
|
|
728
750
|
}
|
|
729
|
-
const base =
|
|
751
|
+
const base = resolved.baseURL;
|
|
730
752
|
try {
|
|
731
753
|
const controller = new AbortController();
|
|
732
754
|
const timer = setTimeout(() => {
|
|
@@ -10,7 +10,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
10
10
|
* callbacks.
|
|
11
11
|
*/
|
|
12
12
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
13
|
-
import {
|
|
13
|
+
import { TOKEN_QUOTA_MAX_NOTES } from '@jxgame2020/dsh-token-quota/types';
|
|
14
14
|
import { mergeModelRows, reorderKeys } from "./store.js";
|
|
15
15
|
import css from './TokenQuotaPanel.module.css';
|
|
16
16
|
/** Compact a token count for display. */
|
|
@@ -543,9 +543,10 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
543
543
|
list.push('deepseek');
|
|
544
544
|
return list;
|
|
545
545
|
}, [groups]);
|
|
546
|
-
// Balance by provider key
|
|
547
|
-
//
|
|
548
|
-
//
|
|
546
|
+
// Balance by provider key. The Host returns a balances entry for every
|
|
547
|
+
// provider it can query (DeepSeek-family), so a directory provider with no
|
|
548
|
+
// entry is "not integrated for query" — except during the very first fetch,
|
|
549
|
+
// when the whole list is still empty and reads as "loading" instead.
|
|
549
550
|
const balanceByProvider = useMemo(() => {
|
|
550
551
|
const map = new Map();
|
|
551
552
|
for (const provider of providers) {
|
|
@@ -553,7 +554,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
553
554
|
if (bal !== undefined) {
|
|
554
555
|
map.set(provider, bal);
|
|
555
556
|
}
|
|
556
|
-
else if (
|
|
557
|
+
else if (balances.length === 0) {
|
|
557
558
|
map.set(provider, 'loading');
|
|
558
559
|
}
|
|
559
560
|
else {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -112,8 +112,16 @@ export declare class TokenQuotaService extends Service {
|
|
|
112
112
|
* the enabled-transition in `onChange` fetch immediately).
|
|
113
113
|
*/
|
|
114
114
|
private syncBalancePolling;
|
|
115
|
-
/** Refresh every provider
|
|
115
|
+
/** Refresh every DeepSeek-family provider found in the model directory. */
|
|
116
116
|
private refreshAllBalances;
|
|
117
|
+
/**
|
|
118
|
+
* Discover every provider in the model directory that looks like DeepSeek,
|
|
119
|
+
* together with its own credential reference and endpoint base. This is what
|
|
120
|
+
* decides which providers are queried: a provider qualifies when its base URL
|
|
121
|
+
* points at DeepSeek's API host or its credential reference is named with the
|
|
122
|
+
* `DEEPSEEK` prefix, and it must declare an `apiKeyEnv`.
|
|
123
|
+
*/
|
|
124
|
+
private discoverBalanceSources;
|
|
117
125
|
/**
|
|
118
126
|
* Refresh one provider's cached account balance. The API key is resolved
|
|
119
127
|
* through the harness credential seam (`credentials.resolve`) with the
|
package/lib/types/index.js
CHANGED
|
@@ -271,21 +271,8 @@ function usageTokens(usage) {
|
|
|
271
271
|
+ (usage.cacheWriteTokens ?? 0)
|
|
272
272
|
+ usage.outputTokens;
|
|
273
273
|
}
|
|
274
|
-
/**
|
|
275
|
-
|
|
276
|
-
*
|
|
277
|
-
* Mount it beside the other rows (`@jxgame2020/dsh-token-quota`) and write
|
|
278
|
-
* per-model limits through the `token-quota` settings namespace.
|
|
279
|
-
*/
|
|
280
|
-
/**
|
|
281
|
-
* Providers the host can query for account balance, keyed by route key. Each
|
|
282
|
-
* entry names the credential reference (environment-variable name), the
|
|
283
|
-
* balance endpoint base, and the optional `*_BASE_URL` override variable.
|
|
284
|
-
* Directory providers outside this map render as "not integrated for query".
|
|
285
|
-
*/
|
|
286
|
-
const BALANCE_SOURCES = {
|
|
287
|
-
deepseek: { keyEnv: 'DEEPSEEK_API_KEY', baseURL: 'https://api.deepseek.com', baseEnv: 'DEEPSEEK_BASE_URL' },
|
|
288
|
-
};
|
|
274
|
+
/** DeepSeek's public API host; used to recognise DeepSeek-family providers. */
|
|
275
|
+
const DEEPSEEK_BALANCE_HOST = 'api.deepseek.com';
|
|
289
276
|
export class TokenQuotaService extends Service {
|
|
290
277
|
static Config = z.object({
|
|
291
278
|
storagePath: z.string().default(''),
|
|
@@ -551,7 +538,7 @@ export class TokenQuotaService extends Service {
|
|
|
551
538
|
catch {
|
|
552
539
|
// Malformed body: fall back to refreshing everything.
|
|
553
540
|
}
|
|
554
|
-
const task = provider !== undefined
|
|
541
|
+
const task = provider !== undefined
|
|
555
542
|
? this.refreshProviderBalance(provider)
|
|
556
543
|
: this.refreshAllBalances();
|
|
557
544
|
void task.finally(() => {
|
|
@@ -745,9 +732,66 @@ export class TokenQuotaService extends Service {
|
|
|
745
732
|
};
|
|
746
733
|
schedule();
|
|
747
734
|
}
|
|
748
|
-
/** Refresh every provider
|
|
735
|
+
/** Refresh every DeepSeek-family provider found in the model directory. */
|
|
749
736
|
refreshAllBalances() {
|
|
750
|
-
return Promise.all(
|
|
737
|
+
return Promise.all([...this.discoverBalanceSources().values()]
|
|
738
|
+
.map(source => this.refreshProviderBalance(source.provider, source))).then(() => undefined);
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Discover every provider in the model directory that looks like DeepSeek,
|
|
742
|
+
* together with its own credential reference and endpoint base. This is what
|
|
743
|
+
* decides which providers are queried: a provider qualifies when its base URL
|
|
744
|
+
* points at DeepSeek's API host or its credential reference is named with the
|
|
745
|
+
* `DEEPSEEK` prefix, and it must declare an `apiKeyEnv`.
|
|
746
|
+
*/
|
|
747
|
+
discoverBalanceSources() {
|
|
748
|
+
const found = new Map();
|
|
749
|
+
const llm = this.ctx.get('llm');
|
|
750
|
+
const settings = this.ctx.get('settings');
|
|
751
|
+
const fallback = () => ({
|
|
752
|
+
provider: 'deepseek',
|
|
753
|
+
keyEnv: 'DEEPSEEK_API_KEY',
|
|
754
|
+
baseURL: process.env.DEEPSEEK_BASE_URL ?? `https://${DEEPSEEK_BALANCE_HOST}`,
|
|
755
|
+
});
|
|
756
|
+
if (llm?.listConfigurableProviders === undefined) {
|
|
757
|
+
found.set('deepseek', fallback());
|
|
758
|
+
return found;
|
|
759
|
+
}
|
|
760
|
+
for (const entry of llm.listConfigurableProviders()) {
|
|
761
|
+
try {
|
|
762
|
+
let profile = settings?.get(entry.settingsNs);
|
|
763
|
+
for (const segment of entry.settingsPath ?? []) {
|
|
764
|
+
profile = profile !== null && typeof profile === 'object'
|
|
765
|
+
? profile[segment]
|
|
766
|
+
: undefined;
|
|
767
|
+
}
|
|
768
|
+
if (profile === null || typeof profile !== 'object')
|
|
769
|
+
continue;
|
|
770
|
+
const record = profile;
|
|
771
|
+
const keyEnv = typeof record.apiKeyEnv === 'string' && record.apiKeyEnv !== ''
|
|
772
|
+
? record.apiKeyEnv
|
|
773
|
+
: undefined;
|
|
774
|
+
const baseURL = typeof record.baseURL === 'string' && record.baseURL !== ''
|
|
775
|
+
? record.baseURL
|
|
776
|
+
: undefined;
|
|
777
|
+
const isDeepSeek = (baseURL !== undefined && baseURL.includes(DEEPSEEK_BALANCE_HOST))
|
|
778
|
+
|| (keyEnv !== undefined && keyEnv.startsWith('DEEPSEEK'))
|
|
779
|
+
|| entry.provider.startsWith('deepseek');
|
|
780
|
+
if (!isDeepSeek || keyEnv === undefined)
|
|
781
|
+
continue;
|
|
782
|
+
found.set(entry.provider, {
|
|
783
|
+
provider: entry.provider,
|
|
784
|
+
keyEnv,
|
|
785
|
+
baseURL: baseURL ?? `https://${DEEPSEEK_BALANCE_HOST}`,
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
catch {
|
|
789
|
+
// Malformed provider entry — skip it and keep the others.
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (found.size === 0)
|
|
793
|
+
found.set('deepseek', fallback());
|
|
794
|
+
return found;
|
|
751
795
|
}
|
|
752
796
|
/**
|
|
753
797
|
* Refresh one provider's cached account balance. The API key is resolved
|
|
@@ -755,9 +799,9 @@ export class TokenQuotaService extends Service {
|
|
|
755
799
|
* environment as a fallback, so the Models page key is used with nothing to
|
|
756
800
|
* type. A failed fetch keeps the previous value and marks it as an error.
|
|
757
801
|
*/
|
|
758
|
-
async refreshProviderBalance(provider) {
|
|
759
|
-
const
|
|
760
|
-
if (
|
|
802
|
+
async refreshProviderBalance(provider, source) {
|
|
803
|
+
const resolved = source ?? this.discoverBalanceSources().get(provider);
|
|
804
|
+
if (resolved === undefined)
|
|
761
805
|
return;
|
|
762
806
|
const existing = this.balanceFetches.get(provider);
|
|
763
807
|
if (existing !== undefined)
|
|
@@ -769,14 +813,14 @@ export class TokenQuotaService extends Service {
|
|
|
769
813
|
let key;
|
|
770
814
|
if (credentials !== undefined) {
|
|
771
815
|
try {
|
|
772
|
-
key = (await credentials.resolve(
|
|
816
|
+
key = (await credentials.resolve(resolved.keyEnv))?.value;
|
|
773
817
|
}
|
|
774
818
|
catch {
|
|
775
819
|
// Seam unreachable: fall through to the environment.
|
|
776
820
|
}
|
|
777
821
|
}
|
|
778
822
|
if (key === undefined || key === '')
|
|
779
|
-
key = process.env[
|
|
823
|
+
key = process.env[resolved.keyEnv];
|
|
780
824
|
if (key === undefined || key === '') {
|
|
781
825
|
this.balances.set(provider, {
|
|
782
826
|
provider,
|
|
@@ -788,9 +832,7 @@ export class TokenQuotaService extends Service {
|
|
|
788
832
|
});
|
|
789
833
|
return;
|
|
790
834
|
}
|
|
791
|
-
const base =
|
|
792
|
-
? (process.env[source.baseEnv] ?? source.baseURL)
|
|
793
|
-
: source.baseURL;
|
|
835
|
+
const base = resolved.baseURL;
|
|
794
836
|
try {
|
|
795
837
|
const controller = new AbortController();
|
|
796
838
|
const timer = setTimeout(() => { controller.abort(); }, 10_000);
|
package/lib/types/types.d.ts
CHANGED
|
@@ -55,12 +55,6 @@ export interface TokenQuotaBalanceSettings {
|
|
|
55
55
|
pollMinutes: number;
|
|
56
56
|
}
|
|
57
57
|
export declare const TOKEN_QUOTA_DEFAULT_BALANCE: TokenQuotaBalanceSettings;
|
|
58
|
-
/**
|
|
59
|
-
* Provider route keys the host knows how to query for account balance. A
|
|
60
|
-
* directory provider outside this list renders as "not integrated for query"
|
|
61
|
-
* in the balance window.
|
|
62
|
-
*/
|
|
63
|
-
export declare const TOKEN_QUOTA_BALANCE_PROVIDERS: readonly string[];
|
|
64
58
|
/** Fetch state of the provider account balance. */
|
|
65
59
|
export type TokenQuotaBalanceStatus = 'ok' | 'unconfigured' | 'error';
|
|
66
60
|
/**
|
package/lib/types/types.js
CHANGED
|
@@ -33,12 +33,6 @@ export const TOKEN_QUOTA_DEFAULT_BALANCE = {
|
|
|
33
33
|
enabled: true,
|
|
34
34
|
pollMinutes: 5,
|
|
35
35
|
};
|
|
36
|
-
/**
|
|
37
|
-
* Provider route keys the host knows how to query for account balance. A
|
|
38
|
-
* directory provider outside this list renders as "not integrated for query"
|
|
39
|
-
* in the balance window.
|
|
40
|
-
*/
|
|
41
|
-
export const TOKEN_QUOTA_BALANCE_PROVIDERS = ['deepseek'];
|
|
42
36
|
/** Default music settings: silent until the user flips the panel switch. */
|
|
43
37
|
export const TOKEN_QUOTA_DEFAULT_MUSIC = {
|
|
44
38
|
enabled: false,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxgame2020/dsh-token-quota",
|
|
3
3
|
"description": "Daily per-model token quota accounting, enforcement, and a floating quota panel for the DeepSeek Harness — a fully self-contained plugin (no core-Harness wiring, no generated RPC contract)",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.40",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|