@jxgame2020/dsh-token-quota 0.1.41 → 0.1.43
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 +161 -136
- package/lib/index.js +1 -1
- package/lib/types/client/index.js +38 -7
- package/lib/types/client/mic.d.ts +11 -7
- package/lib/types/client/mic.js +11 -12
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -132,7 +132,7 @@ window.__ModuleLoader__.load({
|
|
|
132
132
|
d.transcribe = settings;
|
|
133
133
|
},
|
|
134
134
|
setUpgrade: (d, upgrade) => {
|
|
135
|
-
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.
|
|
135
|
+
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.43" ? upgrade : null;
|
|
136
136
|
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
|
|
137
137
|
d.upgrade = normalized;
|
|
138
138
|
},
|
|
@@ -262,142 +262,142 @@ window.__ModuleLoader__.load({
|
|
|
262
262
|
document.head.appendChild(tag);
|
|
263
263
|
}
|
|
264
264
|
var TokenQuotaPanel_module_css_default = {
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
"
|
|
269
|
-
"dialogBtn": "NPLLIq_dialogBtn",
|
|
270
|
-
"logScroll": "NPLLIq_logScroll",
|
|
271
|
-
"logPager": "NPLLIq_logPager",
|
|
272
|
-
"logPagerControls": "NPLLIq_logPagerControls",
|
|
273
|
-
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
274
|
-
"balanceWinHeader": "NPLLIq_balanceWinHeader",
|
|
275
|
-
"balanceBarRefresh": "NPLLIq_balanceBarRefresh",
|
|
276
|
-
"gearBtn": "NPLLIq_gearBtn",
|
|
277
|
-
"logDayCol": "NPLLIq_logDayCol",
|
|
278
|
-
"noteChip": "NPLLIq_noteChip",
|
|
279
|
-
"dialogClose": "NPLLIq_dialogClose",
|
|
280
|
-
"radioRow": "NPLLIq_radioRow",
|
|
281
|
-
"noteMenuBackdrop": "NPLLIq_noteMenuBackdrop",
|
|
282
|
-
"rowMeta": "NPLLIq_rowMeta",
|
|
283
|
-
"balanceRowValue": "NPLLIq_balanceRowValue",
|
|
284
|
-
"collapse": "NPLLIq_collapse",
|
|
285
|
-
"tab": "NPLLIq_tab",
|
|
286
|
-
"balanceRowRefresh": "NPLLIq_balanceRowRefresh",
|
|
287
|
-
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
288
|
-
"tabIcon": "NPLLIq_tabIcon",
|
|
289
|
-
"header": "NPLLIq_header",
|
|
290
|
-
"balanceRefreshAll": "NPLLIq_balanceRefreshAll",
|
|
291
|
-
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
292
|
-
"noteWinBtn": "NPLLIq_noteWinBtn",
|
|
293
|
-
"subtitle": "NPLLIq_subtitle",
|
|
294
|
-
"rowHeader": "NPLLIq_rowHeader",
|
|
295
|
-
"monitorName": "NPLLIq_monitorName",
|
|
296
|
-
"logClearDate": "NPLLIq_logClearDate",
|
|
297
|
-
"balanceStateError": "NPLLIq_balanceStateError",
|
|
265
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
266
|
+
"balanceValueOk": "NPLLIq_balanceValueOk",
|
|
267
|
+
"logTable": "NPLLIq_logTable",
|
|
268
|
+
"noteWinBar": "NPLLIq_noteWinBar",
|
|
298
269
|
"row": "NPLLIq_row",
|
|
299
|
-
"
|
|
300
|
-
"
|
|
301
|
-
"
|
|
270
|
+
"noteMenu": "NPLLIq_noteMenu",
|
|
271
|
+
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
272
|
+
"header": "NPLLIq_header",
|
|
273
|
+
"noteMenuBackdrop": "NPLLIq_noteMenuBackdrop",
|
|
274
|
+
"noteWin": "NPLLIq_noteWin",
|
|
275
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
276
|
+
"body": "NPLLIq_body",
|
|
277
|
+
"balanceWin": "NPLLIq_balanceWin",
|
|
278
|
+
"noteWinResize": "NPLLIq_noteWinResize",
|
|
302
279
|
"settingsDialog": "NPLLIq_settingsDialog",
|
|
280
|
+
"settingsBtn": "NPLLIq_settingsBtn",
|
|
281
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
282
|
+
"balanceToggle": "NPLLIq_balanceToggle",
|
|
283
|
+
"balanceRow": "NPLLIq_balanceRow",
|
|
284
|
+
"balanceStateError": "NPLLIq_balanceStateError",
|
|
285
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
286
|
+
"balanceSortBtn": "NPLLIq_balanceSortBtn",
|
|
287
|
+
"monitorList": "NPLLIq_monitorList",
|
|
288
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
289
|
+
"noticeError": "NPLLIq_noticeError",
|
|
303
290
|
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
304
|
-
"balanceValueOk": "NPLLIq_balanceValueOk",
|
|
305
|
-
"noteChipOpen": "NPLLIq_noteChipOpen",
|
|
306
|
-
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
307
|
-
"title": "NPLLIq_title",
|
|
308
291
|
"dialogLabel": "NPLLIq_dialogLabel",
|
|
309
|
-
"
|
|
310
|
-
"balanceWinBody": "NPLLIq_balanceWinBody",
|
|
311
|
-
"noteWinResize": "NPLLIq_noteWinResize",
|
|
312
|
-
"noteNewPlus": "NPLLIq_noteNewPlus",
|
|
313
|
-
"selectBtn": "NPLLIq_selectBtn",
|
|
314
|
-
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
315
|
-
"balanceBarError": "NPLLIq_balanceBarError",
|
|
316
|
-
"upgradeClose": "NPLLIq_upgradeClose",
|
|
317
|
-
"logToolbar": "NPLLIq_logToolbar",
|
|
318
|
-
"balanceValueError": "NPLLIq_balanceValueError",
|
|
319
|
-
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
320
|
-
"input": "NPLLIq_input",
|
|
321
|
-
"monitorList": "NPLLIq_monitorList",
|
|
322
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
323
|
-
"noteWinTitleText": "NPLLIq_noteWinTitleText",
|
|
324
|
-
"rowDragging": "NPLLIq_rowDragging",
|
|
325
|
-
"balanceRow": "NPLLIq_balanceRow",
|
|
292
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
326
293
|
"noteWinCollapsed": "NPLLIq_noteWinCollapsed",
|
|
327
|
-
"fillIdle": "NPLLIq_fillIdle",
|
|
328
|
-
"balanceRowName": "NPLLIq_balanceRowName",
|
|
329
|
-
"noteMenu": "NPLLIq_noteMenu",
|
|
330
|
-
"fillWarn": "NPLLIq_fillWarn",
|
|
331
294
|
"noteWinGripBar": "NPLLIq_noteWinGripBar",
|
|
332
|
-
"
|
|
295
|
+
"controls": "NPLLIq_controls",
|
|
296
|
+
"noteWinText": "NPLLIq_noteWinText",
|
|
297
|
+
"dialogTab": "NPLLIq_dialogTab",
|
|
298
|
+
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
299
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
300
|
+
"balanceBarBadge": "NPLLIq_balanceBarBadge",
|
|
301
|
+
"rowMeta": "NPLLIq_rowMeta",
|
|
302
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
333
303
|
"noteMenuItem": "NPLLIq_noteMenuItem",
|
|
334
|
-
"rowName": "NPLLIq_rowName",
|
|
335
|
-
"version": "NPLLIq_version",
|
|
336
304
|
"dialogTabs": "NPLLIq_dialogTabs",
|
|
337
|
-
"
|
|
338
|
-
"
|
|
339
|
-
"
|
|
305
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
306
|
+
"noteNew": "NPLLIq_noteNew",
|
|
307
|
+
"balanceLastLine": "NPLLIq_balanceLastLine",
|
|
308
|
+
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
309
|
+
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
310
|
+
"panelDim": "NPLLIq_panelDim",
|
|
311
|
+
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
312
|
+
"tab": "NPLLIq_tab",
|
|
313
|
+
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
314
|
+
"balanceBarDim": "NPLLIq_balanceBarDim",
|
|
315
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
316
|
+
"dialogBody": "NPLLIq_dialogBody",
|
|
317
|
+
"headerActions": "NPLLIq_headerActions",
|
|
318
|
+
"balanceBarLow": "NPLLIq_balanceBarLow",
|
|
319
|
+
"balanceRowValue": "NPLLIq_balanceRowValue",
|
|
320
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
321
|
+
"tabIcon": "NPLLIq_tabIcon",
|
|
322
|
+
"selectBtn": "NPLLIq_selectBtn",
|
|
323
|
+
"switch": "NPLLIq_switch",
|
|
324
|
+
"panel": "NPLLIq_panel",
|
|
325
|
+
"fillOver": "NPLLIq_fillOver",
|
|
326
|
+
"subtitle": "NPLLIq_subtitle",
|
|
340
327
|
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
328
|
+
"balanceValueLow": "NPLLIq_balanceValueLow",
|
|
329
|
+
"notice": "NPLLIq_notice",
|
|
330
|
+
"balanceBar": "NPLLIq_balanceBar",
|
|
341
331
|
"dialogHeader": "NPLLIq_dialogHeader",
|
|
332
|
+
"balanceWinHeader": "NPLLIq_balanceWinHeader",
|
|
342
333
|
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
334
|
+
"upgradeClose": "NPLLIq_upgradeClose",
|
|
335
|
+
"rowName": "NPLLIq_rowName",
|
|
336
|
+
"noteWinTitleText": "NPLLIq_noteWinTitleText",
|
|
337
|
+
"copyBtn": "NPLLIq_copyBtn",
|
|
338
|
+
"rowDragging": "NPLLIq_rowDragging",
|
|
339
|
+
"noteChipOpen": "NPLLIq_noteChipOpen",
|
|
340
|
+
"balanceWinTitle": "NPLLIq_balanceWinTitle",
|
|
341
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
342
|
+
"balanceStateHint": "NPLLIq_balanceStateHint",
|
|
343
343
|
"upgradeHint": "NPLLIq_upgradeHint",
|
|
344
|
-
"
|
|
345
|
-
"
|
|
346
|
-
"
|
|
347
|
-
"
|
|
348
|
-
"
|
|
349
|
-
"
|
|
350
|
-
"
|
|
351
|
-
"
|
|
344
|
+
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
345
|
+
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
346
|
+
"balanceToggleOpen": "NPLLIq_balanceToggleOpen",
|
|
347
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
348
|
+
"noteChip": "NPLLIq_noteChip",
|
|
349
|
+
"balanceValueError": "NPLLIq_balanceValueError",
|
|
350
|
+
"monitorName": "NPLLIq_monitorName",
|
|
351
|
+
"noteWinBtn": "NPLLIq_noteWinBtn",
|
|
352
|
+
"balanceRowRefresh": "NPLLIq_balanceRowRefresh",
|
|
353
|
+
"resetRow": "NPLLIq_resetRow",
|
|
352
354
|
"logSearch": "NPLLIq_logSearch",
|
|
353
|
-
"
|
|
354
|
-
"
|
|
355
|
-
"resetSelect": "NPLLIq_resetSelect",
|
|
356
|
-
"logModelCol": "NPLLIq_logModelCol",
|
|
357
|
-
"bar": "NPLLIq_bar",
|
|
358
|
-
"logClearBtn": "NPLLIq_logClearBtn",
|
|
359
|
-
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
360
|
-
"balanceToggle": "NPLLIq_balanceToggle",
|
|
361
|
-
"balanceBarLow": "NPLLIq_balanceBarLow",
|
|
355
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
356
|
+
"logPagerControls": "NPLLIq_logPagerControls",
|
|
362
357
|
"save": "NPLLIq_save",
|
|
363
|
-
"noteWinText": "NPLLIq_noteWinText",
|
|
364
358
|
"logClearDialog": "NPLLIq_logClearDialog",
|
|
365
|
-
"
|
|
366
|
-
"
|
|
367
|
-
"
|
|
368
|
-
"
|
|
359
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
360
|
+
"balanceRefreshAll": "NPLLIq_balanceRefreshAll",
|
|
361
|
+
"noteNewPlus": "NPLLIq_noteNewPlus",
|
|
362
|
+
"balanceWinBody": "NPLLIq_balanceWinBody",
|
|
363
|
+
"collapse": "NPLLIq_collapse",
|
|
364
|
+
"dialogSection": "NPLLIq_dialogSection",
|
|
365
|
+
"dialogClose": "NPLLIq_dialogClose",
|
|
366
|
+
"balanceRowName": "NPLLIq_balanceRowName",
|
|
367
|
+
"dialog": "NPLLIq_dialog",
|
|
368
|
+
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
369
|
+
"logPager": "NPLLIq_logPager",
|
|
370
|
+
"fillWarn": "NPLLIq_fillWarn",
|
|
371
|
+
"rowDropTarget": "NPLLIq_rowDropTarget",
|
|
372
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
373
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
374
|
+
"notesBar": "NPLLIq_notesBar",
|
|
375
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
376
|
+
"radioRow": "NPLLIq_radioRow",
|
|
369
377
|
"balanceBarText": "NPLLIq_balanceBarText",
|
|
378
|
+
"monitorRow": "NPLLIq_monitorRow",
|
|
379
|
+
"balanceRowHeader": "NPLLIq_balanceRowHeader",
|
|
380
|
+
"noteWinTitle": "NPLLIq_noteWinTitle",
|
|
370
381
|
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
371
|
-
"
|
|
372
|
-
"
|
|
373
|
-
"
|
|
374
|
-
"
|
|
382
|
+
"balanceBarRefresh": "NPLLIq_balanceBarRefresh",
|
|
383
|
+
"logToolbar": "NPLLIq_logToolbar",
|
|
384
|
+
"balanceBarError": "NPLLIq_balanceBarError",
|
|
385
|
+
"version": "NPLLIq_version",
|
|
386
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
375
387
|
"logHeader": "NPLLIq_logHeader",
|
|
376
|
-
"
|
|
377
|
-
"
|
|
378
|
-
"
|
|
379
|
-
"
|
|
380
|
-
"
|
|
381
|
-
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
382
|
-
"panel": "NPLLIq_panel",
|
|
383
|
-
"dialogBody": "NPLLIq_dialogBody",
|
|
384
|
-
"balanceRowHeader": "NPLLIq_balanceRowHeader",
|
|
385
|
-
"logUsedCol": "NPLLIq_logUsedCol",
|
|
386
|
-
"body": "NPLLIq_body",
|
|
388
|
+
"logScroll": "NPLLIq_logScroll",
|
|
389
|
+
"bar": "NPLLIq_bar",
|
|
390
|
+
"gearBtn": "NPLLIq_gearBtn",
|
|
391
|
+
"headerText": "NPLLIq_headerText",
|
|
392
|
+
"input": "NPLLIq_input",
|
|
387
393
|
"logDialog": "NPLLIq_logDialog",
|
|
388
|
-
"
|
|
394
|
+
"versionNew": "NPLLIq_versionNew",
|
|
389
395
|
"logPagerPages": "NPLLIq_logPagerPages",
|
|
390
|
-
"
|
|
391
|
-
"
|
|
392
|
-
"
|
|
393
|
-
"
|
|
394
|
-
"
|
|
395
|
-
"notesBar": "NPLLIq_notesBar",
|
|
396
|
-
"balanceLastLine": "NPLLIq_balanceLastLine",
|
|
397
|
-
"balanceWinTitle": "NPLLIq_balanceWinTitle",
|
|
398
|
-
"balanceBar": "NPLLIq_balanceBar",
|
|
399
|
-
"monitorHint": "NPLLIq_monitorHint",
|
|
400
|
-
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash"
|
|
396
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
397
|
+
"dialogTitle": "NPLLIq_dialogTitle",
|
|
398
|
+
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
399
|
+
"title": "NPLLIq_title",
|
|
400
|
+
"rowDrag": "NPLLIq_rowDrag"
|
|
401
401
|
};
|
|
402
402
|
//#endregion
|
|
403
403
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -1068,13 +1068,13 @@ window.__ModuleLoader__.load({
|
|
|
1068
1068
|
title: t("upgradeAvailableHint"),
|
|
1069
1069
|
children: [
|
|
1070
1070
|
"v",
|
|
1071
|
-
"0.1.
|
|
1071
|
+
"0.1.43",
|
|
1072
1072
|
" → v",
|
|
1073
1073
|
upgrade.latestVersion
|
|
1074
1074
|
]
|
|
1075
1075
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
1076
1076
|
className: TokenQuotaPanel_module_css_default.version,
|
|
1077
|
-
children: ["v", "0.1.
|
|
1077
|
+
children: ["v", "0.1.43"]
|
|
1078
1078
|
})]
|
|
1079
1079
|
})
|
|
1080
1080
|
}),
|
|
@@ -2890,13 +2890,13 @@ window.__ModuleLoader__.load({
|
|
|
2890
2890
|
document.head.appendChild(tag);
|
|
2891
2891
|
}
|
|
2892
2892
|
var mic_module_css_default = {
|
|
2893
|
-
"
|
|
2893
|
+
"micPulse": "KCoVpa_micPulse",
|
|
2894
2894
|
"micErr": "KCoVpa_micErr",
|
|
2895
2895
|
"micErrTip": "KCoVpa_micErrTip",
|
|
2896
|
+
"micRec": "KCoVpa_micRec",
|
|
2896
2897
|
"micBusy": "KCoVpa_micBusy",
|
|
2897
|
-
"micWrap": "KCoVpa_micWrap",
|
|
2898
2898
|
"micBtn": "KCoVpa_micBtn",
|
|
2899
|
-
"
|
|
2899
|
+
"micWrap": "KCoVpa_micWrap"
|
|
2900
2900
|
};
|
|
2901
2901
|
//#endregion
|
|
2902
2902
|
//#region lib/types/client/mic.js
|
|
@@ -2907,11 +2907,17 @@ window.__ModuleLoader__.load({
|
|
|
2907
2907
|
* Host, which forwards it to the configured OpenAI-compatible transcription
|
|
2908
2908
|
* endpoint. The returned text is appended to the composer. The button only
|
|
2909
2909
|
* renders while transcription is enabled in the token-quota settings.
|
|
2910
|
+
*
|
|
2911
|
+
* This entry is mounted in a session-scoped slot, so it cannot share the
|
|
2912
|
+
* panel's root-scoped store handle (which would fork a per-session instance
|
|
2913
|
+
* with stale state). Instead it subscribes to a tiny transcribe-only
|
|
2914
|
+
* observable passed through injection and reads the locale-bound `t` from
|
|
2915
|
+
* injection as well.
|
|
2910
2916
|
*/
|
|
2911
2917
|
/**
|
|
2912
2918
|
* Append recognised text to the contentEditable composer. Focuses the editor,
|
|
2913
2919
|
* moves the caret to the end, and uses `insertText` so the host editor's own
|
|
2914
|
-
* input handling (undo,
|
|
2920
|
+
* input handling (undo, lexical binding) sees it as a typed insertion.
|
|
2915
2921
|
*/
|
|
2916
2922
|
function appendToComposer(text) {
|
|
2917
2923
|
const editor = document.querySelector("[data-composer-input]");
|
|
@@ -2938,8 +2944,8 @@ window.__ModuleLoader__.load({
|
|
|
2938
2944
|
* Mic button rendered inside the composer card. Manages its own MediaRecorder
|
|
2939
2945
|
* lifecycle; only the button is shown — no floating panel UI.
|
|
2940
2946
|
*/
|
|
2941
|
-
function TokenQuotaMic({ t,
|
|
2942
|
-
const
|
|
2947
|
+
function TokenQuotaMic({ t, transcribe, subscribeTranscribe, getTranscribe }) {
|
|
2948
|
+
const settings = (0, react.useSyncExternalStore)(subscribeTranscribe, getTranscribe, getTranscribe);
|
|
2943
2949
|
const [recording, setRecording] = (0, react.useState)(false);
|
|
2944
2950
|
const [transcribing, setTranscribing] = (0, react.useState)(false);
|
|
2945
2951
|
const [error, setError] = (0, react.useState)(null);
|
|
@@ -3016,7 +3022,7 @@ window.__ModuleLoader__.load({
|
|
|
3016
3022
|
if (recording) stopAndTranscribe();
|
|
3017
3023
|
else startRecording();
|
|
3018
3024
|
};
|
|
3019
|
-
if (!enabled) return null;
|
|
3025
|
+
if (!settings.enabled) return null;
|
|
3020
3026
|
const state = transcribing ? "busy" : recording ? "rec" : "idle";
|
|
3021
3027
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
3022
3028
|
className: mic_module_css_default.micWrap,
|
|
@@ -3422,6 +3428,23 @@ window.__ModuleLoader__.load({
|
|
|
3422
3428
|
apiKeyEnv: typeof raw?.apiKeyEnv === "string" && raw.apiKeyEnv !== "" ? raw.apiKeyEnv : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.apiKeyEnv,
|
|
3423
3429
|
model: typeof raw?.model === "string" && raw.model !== "" ? raw.model : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.model
|
|
3424
3430
|
});
|
|
3431
|
+
let currentTranscribe = TOKEN_QUOTA_DEFAULT_TRANSCRIBE;
|
|
3432
|
+
const transcribeSubscribers = /* @__PURE__ */ new Set();
|
|
3433
|
+
const emitTranscribe = () => {
|
|
3434
|
+
for (const fn of transcribeSubscribers) fn();
|
|
3435
|
+
};
|
|
3436
|
+
const subscribeTranscribe = (cb) => {
|
|
3437
|
+
transcribeSubscribers.add(cb);
|
|
3438
|
+
return () => {
|
|
3439
|
+
transcribeSubscribers.delete(cb);
|
|
3440
|
+
};
|
|
3441
|
+
};
|
|
3442
|
+
const getTranscribe = () => currentTranscribe;
|
|
3443
|
+
const applyTranscribe = (settings) => {
|
|
3444
|
+
if (settings.enabled === currentTranscribe.enabled && settings.baseURL === currentTranscribe.baseURL && settings.apiKeyEnv === currentTranscribe.apiKeyEnv && settings.model === currentTranscribe.model) return;
|
|
3445
|
+
currentTranscribe = settings;
|
|
3446
|
+
emitTranscribe();
|
|
3447
|
+
};
|
|
3425
3448
|
const keyOf = (selection) => {
|
|
3426
3449
|
if (selection === null) return void 0;
|
|
3427
3450
|
return `${selection.provider}/${selection.model}`;
|
|
@@ -3544,7 +3567,10 @@ window.__ModuleLoader__.load({
|
|
|
3544
3567
|
bound?.setMusicVolume(musicSettings.volume);
|
|
3545
3568
|
bound?.setMusicStyle(musicSettings.style);
|
|
3546
3569
|
bound?.setMusicOnlyCurrentSession(musicSettings.onlyCurrentSession);
|
|
3547
|
-
|
|
3570
|
+
const transcribeRaw = doc?.transcribe;
|
|
3571
|
+
const resolvedTranscribe = transcribeDefaults(transcribeRaw);
|
|
3572
|
+
applyTranscribe(resolvedTranscribe);
|
|
3573
|
+
bound?.setTranscribeSettings(resolvedTranscribe);
|
|
3548
3574
|
fetch("/token-quota", { headers: { accept: "application/json" } }).then((response) => {
|
|
3549
3575
|
if (!response.ok) {
|
|
3550
3576
|
bound?.setError(`quota route: ${String(response.status)}`);
|
|
@@ -3635,6 +3661,7 @@ window.__ModuleLoader__.load({
|
|
|
3635
3661
|
};
|
|
3636
3662
|
/** Persist the voice transcription settings and mirror them into the store. */
|
|
3637
3663
|
const setTranscribeSettings = (settings) => {
|
|
3664
|
+
applyTranscribe(settings);
|
|
3638
3665
|
bound?.setTranscribeSettings(settings);
|
|
3639
3666
|
scope.set("transcribe", settings);
|
|
3640
3667
|
};
|
|
@@ -3809,15 +3836,13 @@ window.__ModuleLoader__.load({
|
|
|
3809
3836
|
id: "token-quota-mic",
|
|
3810
3837
|
order: 100,
|
|
3811
3838
|
label: () => t("transcribeTitle"),
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
};
|
|
3820
|
-
}
|
|
3839
|
+
inject: (_sessionId) => ({
|
|
3840
|
+
transcribe,
|
|
3841
|
+
setTranscribeSettings,
|
|
3842
|
+
subscribeTranscribe,
|
|
3843
|
+
getTranscribe,
|
|
3844
|
+
t
|
|
3845
|
+
})
|
|
3821
3846
|
}, TokenQuotaMic));
|
|
3822
3847
|
}
|
|
3823
3848
|
//#endregion
|
package/lib/index.js
CHANGED
|
@@ -651,7 +651,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
651
651
|
return this.upgradeCheck;
|
|
652
652
|
}
|
|
653
653
|
async doRefreshUpgrade() {
|
|
654
|
-
const current = "0.1.
|
|
654
|
+
const current = "0.1.43";
|
|
655
655
|
let latest;
|
|
656
656
|
try {
|
|
657
657
|
const response = await fetch(REGISTRY_LATEST_URL, {
|
|
@@ -129,6 +129,28 @@ export function apply(ctx) {
|
|
|
129
129
|
apiKeyEnv: typeof raw?.apiKeyEnv === 'string' && raw.apiKeyEnv !== '' ? raw.apiKeyEnv : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.apiKeyEnv,
|
|
130
130
|
model: typeof raw?.model === 'string' && raw.model !== '' ? raw.model : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.model,
|
|
131
131
|
});
|
|
132
|
+
// --- Transcription settings source (independent of the panel store, so the
|
|
133
|
+
// mic entry — mounted in the session-scoped conversation.input.overlay
|
|
134
|
+
// slot — can subscribe without sharing the panel's root-scoped store
|
|
135
|
+
// instance (which would fork state across scopes). ---
|
|
136
|
+
let currentTranscribe = TOKEN_QUOTA_DEFAULT_TRANSCRIBE;
|
|
137
|
+
const transcribeSubscribers = new Set();
|
|
138
|
+
const emitTranscribe = () => { for (const fn of transcribeSubscribers)
|
|
139
|
+
fn(); };
|
|
140
|
+
const subscribeTranscribe = (cb) => {
|
|
141
|
+
transcribeSubscribers.add(cb);
|
|
142
|
+
return () => { transcribeSubscribers.delete(cb); };
|
|
143
|
+
};
|
|
144
|
+
const getTranscribe = () => currentTranscribe;
|
|
145
|
+
const applyTranscribe = (settings) => {
|
|
146
|
+
if (settings.enabled === currentTranscribe.enabled
|
|
147
|
+
&& settings.baseURL === currentTranscribe.baseURL
|
|
148
|
+
&& settings.apiKeyEnv === currentTranscribe.apiKeyEnv
|
|
149
|
+
&& settings.model === currentTranscribe.model)
|
|
150
|
+
return;
|
|
151
|
+
currentTranscribe = settings;
|
|
152
|
+
emitTranscribe();
|
|
153
|
+
};
|
|
132
154
|
const keyOf = (selection) => {
|
|
133
155
|
if (selection === null)
|
|
134
156
|
return undefined;
|
|
@@ -299,7 +321,10 @@ export function apply(ctx) {
|
|
|
299
321
|
bound?.setMusicVolume(musicSettings.volume);
|
|
300
322
|
bound?.setMusicStyle(musicSettings.style);
|
|
301
323
|
bound?.setMusicOnlyCurrentSession(musicSettings.onlyCurrentSession);
|
|
302
|
-
|
|
324
|
+
const transcribeRaw = doc?.transcribe;
|
|
325
|
+
const resolvedTranscribe = transcribeDefaults(transcribeRaw);
|
|
326
|
+
applyTranscribe(resolvedTranscribe);
|
|
327
|
+
bound?.setTranscribeSettings(resolvedTranscribe);
|
|
303
328
|
void fetch('/token-quota', { headers: { accept: 'application/json' } }).then((response) => {
|
|
304
329
|
if (!response.ok) {
|
|
305
330
|
bound?.setError(`quota route: ${String(response.status)}`);
|
|
@@ -389,6 +414,7 @@ export function apply(ctx) {
|
|
|
389
414
|
};
|
|
390
415
|
/** Persist the voice transcription settings and mirror them into the store. */
|
|
391
416
|
const setTranscribeSettings = (settings) => {
|
|
417
|
+
applyTranscribe(settings);
|
|
392
418
|
bound?.setTranscribeSettings(settings);
|
|
393
419
|
void scope.set('transcribe', settings);
|
|
394
420
|
};
|
|
@@ -562,17 +588,22 @@ export function apply(ctx) {
|
|
|
562
588
|
// transcription is enabled in settings; a press starts recording, a second
|
|
563
589
|
// press stops and sends the audio to the Host for transcription, then the
|
|
564
590
|
// recognised text is appended to the composer.
|
|
591
|
+
// NOTE: This entry is scoped to a session (not root), so it cannot share the
|
|
592
|
+
// panel's root-scoped store handle without forking a separate per-session
|
|
593
|
+
// instance. Instead it subscribes to a tiny transcribe-only observable and
|
|
594
|
+
// receives the locale-bound `t` function through injection.
|
|
565
595
|
ctx.slots.inject('conversation.input.overlay', () => ctx.slots.register({
|
|
566
596
|
name: 'conversation.input.overlay',
|
|
567
597
|
id: 'token-quota-mic',
|
|
568
598
|
order: 100,
|
|
569
599
|
label: () => t('transcribeTitle'),
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
600
|
+
inject: (_sessionId) => ({
|
|
601
|
+
transcribe,
|
|
602
|
+
setTranscribeSettings,
|
|
603
|
+
subscribeTranscribe,
|
|
604
|
+
getTranscribe,
|
|
605
|
+
t: t,
|
|
606
|
+
}),
|
|
576
607
|
}, TokenQuotaMic));
|
|
577
608
|
}
|
|
578
609
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { TOKEN_QUOTA_NAMESPACE } from '@jxgame2020/dsh-token-quota/types';
|
|
1
|
+
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
2
|
import type { TokenQuotaTranscribeSettings } from '@jxgame2020/dsh-token-quota/types';
|
|
4
|
-
|
|
5
|
-
/** Injected business face: transcription send + settings persistence. */
|
|
3
|
+
/** Injected business face: transcription send + settings subscription. */
|
|
6
4
|
export interface TokenQuotaMicInjected {
|
|
7
5
|
/** Send a recorded audio blob to the Host for transcription. */
|
|
8
6
|
transcribe: (blob: Blob) => Promise<string>;
|
|
9
7
|
/** Persist the transcription settings (the panel owns the settings UI). */
|
|
10
8
|
setTranscribeSettings: (settings: TokenQuotaTranscribeSettings) => void;
|
|
9
|
+
/** Subscribe to transcribe settings changes (returns an unsubscribe). */
|
|
10
|
+
subscribeTranscribe: (cb: () => void) => () => void;
|
|
11
|
+
/** Read the current transcribe settings snapshot. */
|
|
12
|
+
getTranscribe: () => TokenQuotaTranscribeSettings;
|
|
13
|
+
/** Locale-bound translate function. */
|
|
14
|
+
t: (key: string) => string;
|
|
11
15
|
}
|
|
12
|
-
/** Full mic component props: runtime +
|
|
13
|
-
export type TokenQuotaMicComponentProps = PropsRuntime<'conversation.input.overlay'> &
|
|
16
|
+
/** Full mic component props: runtime + injected face (no store/locale shares). */
|
|
17
|
+
export type TokenQuotaMicComponentProps = PropsRuntime<'conversation.input.overlay'> & TokenQuotaMicInjected;
|
|
14
18
|
/**
|
|
15
19
|
* Mic button rendered inside the composer card. Manages its own MediaRecorder
|
|
16
20
|
* lifecycle; only the button is shown — no floating panel UI.
|
|
17
21
|
*/
|
|
18
|
-
export declare function TokenQuotaMic({ t,
|
|
22
|
+
export declare function TokenQuotaMic({ t, transcribe, subscribeTranscribe, getTranscribe, }: TokenQuotaMicComponentProps): JSX.Element | null;
|
|
19
23
|
//# sourceMappingURL=mic.d.ts.map
|
package/lib/types/client/mic.js
CHANGED
|
@@ -6,23 +6,27 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
* Host, which forwards it to the configured OpenAI-compatible transcription
|
|
7
7
|
* endpoint. The returned text is appended to the composer. The button only
|
|
8
8
|
* renders while transcription is enabled in the token-quota settings.
|
|
9
|
+
*
|
|
10
|
+
* This entry is mounted in a session-scoped slot, so it cannot share the
|
|
11
|
+
* panel's root-scoped store handle (which would fork a per-session instance
|
|
12
|
+
* with stale state). Instead it subscribes to a tiny transcribe-only
|
|
13
|
+
* observable passed through injection and reads the locale-bound `t` from
|
|
14
|
+
* injection as well.
|
|
9
15
|
*/
|
|
10
|
-
import { useEffect, useRef, useState } from 'react';
|
|
16
|
+
import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
11
17
|
import css from './mic.module.css';
|
|
12
18
|
/**
|
|
13
19
|
* Append recognised text to the contentEditable composer. Focuses the editor,
|
|
14
20
|
* moves the caret to the end, and uses `insertText` so the host editor's own
|
|
15
|
-
* input handling (undo,
|
|
21
|
+
* input handling (undo, lexical binding) sees it as a typed insertion.
|
|
16
22
|
*/
|
|
17
23
|
function appendToComposer(text) {
|
|
18
24
|
const editor = document.querySelector('[data-composer-input]');
|
|
19
25
|
if (editor === null) {
|
|
20
|
-
// No composer on this page — copy to the clipboard as a fallback.
|
|
21
26
|
void navigator.clipboard?.writeText(text).catch(() => { });
|
|
22
27
|
return;
|
|
23
28
|
}
|
|
24
29
|
editor.focus();
|
|
25
|
-
// Move the caret to the end of the editor's text content.
|
|
26
30
|
const selection = window.getSelection();
|
|
27
31
|
if (selection !== null) {
|
|
28
32
|
const range = document.createRange();
|
|
@@ -31,9 +35,6 @@ function appendToComposer(text) {
|
|
|
31
35
|
selection.removeAllRanges();
|
|
32
36
|
selection.addRange(range);
|
|
33
37
|
}
|
|
34
|
-
// execCommand is deprecated but remains the only cross-browser way to trigger
|
|
35
|
-
// a contentEditable editor's own "typed text" handling (undo stack, lexical
|
|
36
|
-
// binding). The host composer listens to it.
|
|
37
38
|
let inserted = false;
|
|
38
39
|
try {
|
|
39
40
|
inserted = document.execCommand('insertText', false, text);
|
|
@@ -49,8 +50,8 @@ function appendToComposer(text) {
|
|
|
49
50
|
* Mic button rendered inside the composer card. Manages its own MediaRecorder
|
|
50
51
|
* lifecycle; only the button is shown — no floating panel UI.
|
|
51
52
|
*/
|
|
52
|
-
export function TokenQuotaMic({ t,
|
|
53
|
-
const
|
|
53
|
+
export function TokenQuotaMic({ t, transcribe, subscribeTranscribe, getTranscribe, }) {
|
|
54
|
+
const settings = useSyncExternalStore(subscribeTranscribe, getTranscribe, getTranscribe);
|
|
54
55
|
const [recording, setRecording] = useState(false);
|
|
55
56
|
const [transcribing, setTranscribing] = useState(false);
|
|
56
57
|
const [error, setError] = useState(null);
|
|
@@ -58,8 +59,6 @@ export function TokenQuotaMic({ t, useStore, transcribe, }) {
|
|
|
58
59
|
const chunksRef = useRef([]);
|
|
59
60
|
const streamRef = useRef(null);
|
|
60
61
|
const errorTimerRef = useRef(undefined);
|
|
61
|
-
// Clean up the recorder / stream on unmount so a navigation while recording
|
|
62
|
-
// stops the mic tracks rather than leaving them open.
|
|
63
62
|
useEffect(() => {
|
|
64
63
|
return () => {
|
|
65
64
|
if (errorTimerRef.current !== undefined)
|
|
@@ -150,7 +149,7 @@ export function TokenQuotaMic({ t, useStore, transcribe, }) {
|
|
|
150
149
|
void startRecording();
|
|
151
150
|
}
|
|
152
151
|
};
|
|
153
|
-
if (!enabled)
|
|
152
|
+
if (!settings.enabled)
|
|
154
153
|
return null;
|
|
155
154
|
const state = transcribing ? 'busy' : recording ? 'rec' : 'idle';
|
|
156
155
|
return (_jsxs("div", { className: css.micWrap, title: error ?? t('transcribeHint'), children: [_jsx("button", { type: "button", className: `${css.micBtn}${state === 'rec' ? ` ${css.micRec}` : ''}${state === 'busy' ? ` ${css.micBusy}` : ''}${error !== null ? ` ${css.micErr}` : ''}`, disabled: transcribing, onClick: (event) => { event.stopPropagation(); onToggle(); }, onPointerDown: (event) => { event.stopPropagation(); }, "aria-pressed": recording, "aria-label": error ?? t('transcribeTitle'), children: transcribing ? '…' : '🎤' }), error !== null && _jsx("span", { className: css.micErrTip, children: error })] }));
|
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.43",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|