@jxgame2020/dsh-token-quota 0.1.6 → 0.1.8
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 +53 -59
- package/lib/index.js +5 -13
- package/lib/types/client/TokenQuotaPanel.js +0 -1
- package/lib/types/client/index.js +16 -12
- package/lib/types/client/locales.d.ts +0 -2
- package/lib/types/client/locales.js +2 -4
- package/lib/types/index.js +17 -22
- package/lib/types/types.d.ts +5 -4
- package/lib/types/types.js +2 -2
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -129,59 +129,59 @@ window.__ModuleLoader__.load({
|
|
|
129
129
|
document.head.appendChild(tag);
|
|
130
130
|
}
|
|
131
131
|
var TokenQuotaPanel_module_css_default = {
|
|
132
|
-
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
133
|
-
"tabLabel": "NPLLIq_tabLabel",
|
|
134
|
-
"monitorHint": "NPLLIq_monitorHint",
|
|
135
|
-
"monitorRow": "NPLLIq_monitorRow",
|
|
136
132
|
"fillOver": "NPLLIq_fillOver",
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"header": "NPLLIq_header",
|
|
140
|
-
"controls": "NPLLIq_controls",
|
|
133
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
134
|
+
"monitorList": "NPLLIq_monitorList",
|
|
141
135
|
"switch": "NPLLIq_switch",
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
136
|
+
"subtitle": "NPLLIq_subtitle",
|
|
137
|
+
"monitorName": "NPLLIq_monitorName",
|
|
138
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
139
|
+
"collapse": "NPLLIq_collapse",
|
|
147
140
|
"row": "NPLLIq_row",
|
|
148
141
|
"fillWarn": "NPLLIq_fillWarn",
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
"
|
|
142
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
143
|
+
"input": "NPLLIq_input",
|
|
144
|
+
"radioRow": "NPLLIq_radioRow",
|
|
145
|
+
"logHeader": "NPLLIq_logHeader",
|
|
146
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
147
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
148
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
149
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
153
150
|
"logDialog": "NPLLIq_logDialog",
|
|
154
|
-
"
|
|
151
|
+
"notice": "NPLLIq_notice",
|
|
152
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
153
|
+
"dialog": "NPLLIq_dialog",
|
|
155
154
|
"logScroll": "NPLLIq_logScroll",
|
|
156
|
-
"fillIdle": "NPLLIq_fillIdle",
|
|
157
|
-
"logTable": "NPLLIq_logTable",
|
|
158
|
-
"body": "NPLLIq_body",
|
|
159
|
-
"logUsedCol": "NPLLIq_logUsedCol",
|
|
160
155
|
"resetRow": "NPLLIq_resetRow",
|
|
161
|
-
"headerText": "NPLLIq_headerText",
|
|
162
|
-
"notice": "NPLLIq_notice",
|
|
163
|
-
"headerActions": "NPLLIq_headerActions",
|
|
164
|
-
"monitorName": "NPLLIq_monitorName",
|
|
165
|
-
"rowName": "NPLLIq_rowName",
|
|
166
156
|
"rowMeta": "NPLLIq_rowMeta",
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"dialogBtn": "NPLLIq_dialogBtn",
|
|
171
|
-
"logDayCol": "NPLLIq_logDayCol",
|
|
172
|
-
"dialogHeader": "NPLLIq_dialogHeader",
|
|
173
|
-
"dialogLabel": "NPLLIq_dialogLabel",
|
|
174
|
-
"gearBtn": "NPLLIq_gearBtn",
|
|
175
|
-
"logModelCol": "NPLLIq_logModelCol",
|
|
157
|
+
"tab": "NPLLIq_tab",
|
|
158
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
159
|
+
"title": "NPLLIq_title",
|
|
176
160
|
"noticeError": "NPLLIq_noticeError",
|
|
161
|
+
"monitorRow": "NPLLIq_monitorRow",
|
|
162
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
177
163
|
"tabIcon": "NPLLIq_tabIcon",
|
|
178
|
-
"
|
|
164
|
+
"rowName": "NPLLIq_rowName",
|
|
165
|
+
"save": "NPLLIq_save",
|
|
179
166
|
"fullNotice": "NPLLIq_fullNotice",
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
167
|
+
"dialogClose": "NPLLIq_dialogClose",
|
|
168
|
+
"header": "NPLLIq_header",
|
|
169
|
+
"bar": "NPLLIq_bar",
|
|
170
|
+
"dialogHeader": "NPLLIq_dialogHeader",
|
|
171
|
+
"headerText": "NPLLIq_headerText",
|
|
172
|
+
"selectBtn": "NPLLIq_selectBtn",
|
|
173
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
174
|
+
"logTable": "NPLLIq_logTable",
|
|
175
|
+
"panel": "NPLLIq_panel",
|
|
176
|
+
"controls": "NPLLIq_controls",
|
|
177
|
+
"headerActions": "NPLLIq_headerActions",
|
|
178
|
+
"body": "NPLLIq_body",
|
|
179
|
+
"settingsBtn": "NPLLIq_settingsBtn",
|
|
180
|
+
"gearBtn": "NPLLIq_gearBtn",
|
|
181
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
182
|
+
"dialogTitle": "NPLLIq_dialogTitle",
|
|
183
|
+
"dialogSection": "NPLLIq_dialogSection",
|
|
184
|
+
"dialogLabel": "NPLLIq_dialogLabel"
|
|
185
185
|
};
|
|
186
186
|
//#endregion
|
|
187
187
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -220,10 +220,6 @@ window.__ModuleLoader__.load({
|
|
|
220
220
|
{
|
|
221
221
|
value: "switchAll",
|
|
222
222
|
labelKey: "fullSwitchAll"
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
value: "switchPriority",
|
|
226
|
-
labelKey: "fullSwitchPriority"
|
|
227
223
|
}
|
|
228
224
|
];
|
|
229
225
|
/**
|
|
@@ -765,8 +761,7 @@ window.__ModuleLoader__.load({
|
|
|
765
761
|
fullActionLabel: "满额后处理",
|
|
766
762
|
fullStop: "停止请求并提示",
|
|
767
763
|
fullSwitchQuota: "自动切换到其它限额模型",
|
|
768
|
-
fullSwitchAll: "
|
|
769
|
-
fullSwitchPriority: "自动切换(优先非限额,其次未监控)",
|
|
764
|
+
fullSwitchAll: "自动切换(优先限额模型,其次非限额)",
|
|
770
765
|
fullNotice: "当前模型今日额度已用尽,请求已停止。请选择其它模型或调整限额。",
|
|
771
766
|
fullSwitchFailed: "没有可切换的模型,请手动选择其它模型或调整限额",
|
|
772
767
|
fullSwitchTo: "已自动切换到 {model}",
|
|
@@ -811,8 +806,7 @@ window.__ModuleLoader__.load({
|
|
|
811
806
|
fullActionLabel: "When a model is full",
|
|
812
807
|
fullStop: "Stop and prompt",
|
|
813
808
|
fullSwitchQuota: "Switch to another quota model",
|
|
814
|
-
fullSwitchAll: "Switch
|
|
815
|
-
fullSwitchPriority: "Prefer uncapped, then unmonitored",
|
|
809
|
+
fullSwitchAll: "Switch models (quota models first, then uncapped)",
|
|
816
810
|
fullNotice: "Today’s quota for the current model is exhausted; the request was stopped. Pick another model or raise its limit.",
|
|
817
811
|
fullSwitchFailed: "No switchable model — pick one manually or raise a limit",
|
|
818
812
|
fullSwitchTo: "Auto-switched to {model}",
|
|
@@ -899,14 +893,13 @@ window.__ModuleLoader__.load({
|
|
|
899
893
|
used: entry?.used ?? 0
|
|
900
894
|
});
|
|
901
895
|
}
|
|
902
|
-
const
|
|
903
|
-
if (lastOnFull === "switchQuota") return candidates.filter(
|
|
904
|
-
if (lastOnFull === "switchAll")
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
return candidates.find(available);
|
|
896
|
+
const cappedFree = (candidate) => isMonitoredKey(candidate.key) && candidate.limit > 0 && candidate.used < candidate.limit;
|
|
897
|
+
if (lastOnFull === "switchQuota") return candidates.filter(cappedFree).sort((a, b) => a.used / a.limit - b.used / b.limit)[0];
|
|
898
|
+
if (lastOnFull === "switchAll") {
|
|
899
|
+
const withQuota = candidates.filter(cappedFree).sort((a, b) => a.used / a.limit - b.used / b.limit);
|
|
900
|
+
if (withQuota.length > 0) return withQuota[0];
|
|
901
|
+
return candidates.find((candidate) => isMonitoredKey(candidate.key) && candidate.limit <= 0);
|
|
902
|
+
}
|
|
910
903
|
};
|
|
911
904
|
/** Run the configured full-quota strategy once per exhausted model. */
|
|
912
905
|
const actOnFull = (snapshot) => {
|
|
@@ -960,7 +953,8 @@ window.__ModuleLoader__.load({
|
|
|
960
953
|
pullCount += 1;
|
|
961
954
|
const doc = scope.getSnapshot().value;
|
|
962
955
|
lastMonitored = doc?.monitored !== void 0 && doc.monitored.length > 0 ? doc.monitored : null;
|
|
963
|
-
|
|
956
|
+
const rawOnFull = doc?.onFull ?? "stop";
|
|
957
|
+
lastOnFull = rawOnFull === "switchPriority" ? "switchAll" : rawOnFull;
|
|
964
958
|
lastReset = doc?.reset !== void 0 && doc.reset !== null && typeof doc.reset === "object" && typeof doc.reset.offsetHours === "number" ? doc.reset : null;
|
|
965
959
|
bound?.setSettings(lastMonitored, lastOnFull);
|
|
966
960
|
bound?.setReset(lastReset);
|
package/lib/index.js
CHANGED
|
@@ -157,7 +157,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
157
157
|
return {
|
|
158
158
|
limits: doc.limits ?? {},
|
|
159
159
|
monitored: doc.monitored ?? [],
|
|
160
|
-
onFull: doc.onFull ?? "stop",
|
|
160
|
+
onFull: doc.onFull === "switchPriority" ? "switchAll" : doc.onFull ?? "stop",
|
|
161
161
|
reset: doc.reset ?? void 0
|
|
162
162
|
};
|
|
163
163
|
};
|
|
@@ -358,11 +358,6 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
358
358
|
};
|
|
359
359
|
};
|
|
360
360
|
const isMonitored = (key) => this.isMonitored(key);
|
|
361
|
-
const isAvailable = (key) => {
|
|
362
|
-
if (!isMonitored(key)) return false;
|
|
363
|
-
const { limit, used } = availability(key);
|
|
364
|
-
return limit <= 0 || used < limit;
|
|
365
|
-
};
|
|
366
361
|
const candidates = this.cachedModels.filter(({ provider, model }) => tokenQuotaKey(provider, model) !== currentKey).map(({ provider, model }) => {
|
|
367
362
|
const key = tokenQuotaKey(provider, model);
|
|
368
363
|
const { limit, used } = availability(key);
|
|
@@ -377,13 +372,10 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
377
372
|
});
|
|
378
373
|
switch (onFull) {
|
|
379
374
|
case "switchQuota": return candidates.filter((c) => c.monitored && c.limit > 0 && c.used < c.limit).sort((a, b) => a.used / a.limit - b.used / b.limit)[0];
|
|
380
|
-
case "switchAll":
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const unmonitored = candidates.find((c) => !c.monitored);
|
|
385
|
-
if (unmonitored !== void 0) return unmonitored;
|
|
386
|
-
return candidates.find((c) => isAvailable(c.key));
|
|
375
|
+
case "switchAll": {
|
|
376
|
+
const cappedFree = candidates.filter((c) => c.monitored && c.limit > 0 && c.used < c.limit).sort((a, b) => a.used / a.limit - b.used / b.limit);
|
|
377
|
+
if (cappedFree.length > 0) return cappedFree[0];
|
|
378
|
+
return candidates.find((c) => c.monitored && c.limit <= 0);
|
|
387
379
|
}
|
|
388
380
|
default: return;
|
|
389
381
|
}
|
|
@@ -34,7 +34,6 @@ const FULL_ACTIONS = [
|
|
|
34
34
|
{ value: 'stop', labelKey: 'fullStop' },
|
|
35
35
|
{ value: 'switchQuota', labelKey: 'fullSwitchQuota' },
|
|
36
36
|
{ value: 'switchAll', labelKey: 'fullSwitchAll' },
|
|
37
|
-
{ value: 'switchPriority', labelKey: 'fullSwitchPriority' },
|
|
38
37
|
];
|
|
39
38
|
/**
|
|
40
39
|
* Pointer-driven drag of a fixed-positioned element. Deltas are applied
|
|
@@ -70,23 +70,23 @@ export function apply(ctx) {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
const
|
|
73
|
+
const cappedFree = (candidate) => isMonitoredKey(candidate.key) && candidate.limit > 0 && candidate.used < candidate.limit;
|
|
74
74
|
if (lastOnFull === 'switchQuota') {
|
|
75
75
|
return candidates
|
|
76
|
-
.filter(
|
|
76
|
+
.filter(cappedFree)
|
|
77
77
|
.sort((a, b) => (a.used / a.limit) - (b.used / b.limit))[0];
|
|
78
78
|
}
|
|
79
79
|
if (lastOnFull === 'switchAll') {
|
|
80
|
-
|
|
80
|
+
// Monitored only: capped models with headroom first (lowest fill ratio),
|
|
81
|
+
// then uncapped monitored models as fallback.
|
|
82
|
+
const withQuota = candidates
|
|
83
|
+
.filter(cappedFree)
|
|
84
|
+
.sort((a, b) => (a.used / a.limit) - (b.used / b.limit));
|
|
85
|
+
if (withQuota.length > 0)
|
|
86
|
+
return withQuota[0];
|
|
87
|
+
return candidates.find(candidate => isMonitoredKey(candidate.key) && candidate.limit <= 0);
|
|
81
88
|
}
|
|
82
|
-
|
|
83
|
-
const uncapped = candidates.find(candidate => isMonitoredKey(candidate.key) && candidate.limit <= 0);
|
|
84
|
-
if (uncapped !== undefined)
|
|
85
|
-
return uncapped;
|
|
86
|
-
const unmonitored = candidates.find(candidate => !isMonitoredKey(candidate.key));
|
|
87
|
-
if (unmonitored !== undefined)
|
|
88
|
-
return unmonitored;
|
|
89
|
-
return candidates.find(available);
|
|
89
|
+
return undefined;
|
|
90
90
|
};
|
|
91
91
|
/** Run the configured full-quota strategy once per exhausted model. */
|
|
92
92
|
const actOnFull = (snapshot) => {
|
|
@@ -159,7 +159,11 @@ export function apply(ctx) {
|
|
|
159
159
|
pullCount += 1;
|
|
160
160
|
const doc = scope.getSnapshot().value;
|
|
161
161
|
lastMonitored = doc?.monitored !== undefined && doc.monitored.length > 0 ? doc.monitored : null;
|
|
162
|
-
|
|
162
|
+
// Legacy `switchPriority` (removed in 0.1.7) maps to `switchAll`.
|
|
163
|
+
// The runtime document may still hold the old value until the user
|
|
164
|
+
// re-saves the settings dialog.
|
|
165
|
+
const rawOnFull = (doc?.onFull ?? 'stop');
|
|
166
|
+
lastOnFull = rawOnFull === 'switchPriority' ? 'switchAll' : rawOnFull;
|
|
163
167
|
lastReset = doc?.reset !== undefined && doc.reset !== null
|
|
164
168
|
&& typeof doc.reset === 'object'
|
|
165
169
|
&& typeof doc.reset.offsetHours === 'number'
|
|
@@ -34,7 +34,6 @@ export declare const zh: {
|
|
|
34
34
|
fullStop: string;
|
|
35
35
|
fullSwitchQuota: string;
|
|
36
36
|
fullSwitchAll: string;
|
|
37
|
-
fullSwitchPriority: string;
|
|
38
37
|
fullNotice: string;
|
|
39
38
|
fullSwitchFailed: string;
|
|
40
39
|
fullSwitchTo: string;
|
|
@@ -82,7 +81,6 @@ export declare const en: {
|
|
|
82
81
|
fullStop: string;
|
|
83
82
|
fullSwitchQuota: string;
|
|
84
83
|
fullSwitchAll: string;
|
|
85
|
-
fullSwitchPriority: string;
|
|
86
84
|
fullNotice: string;
|
|
87
85
|
fullSwitchFailed: string;
|
|
88
86
|
fullSwitchTo: string;
|
|
@@ -33,8 +33,7 @@ export const zh = {
|
|
|
33
33
|
fullActionLabel: '满额后处理',
|
|
34
34
|
fullStop: '停止请求并提示',
|
|
35
35
|
fullSwitchQuota: '自动切换到其它限额模型',
|
|
36
|
-
fullSwitchAll: '
|
|
37
|
-
fullSwitchPriority: '自动切换(优先非限额,其次未监控)',
|
|
36
|
+
fullSwitchAll: '自动切换(优先限额模型,其次非限额)',
|
|
38
37
|
fullNotice: '当前模型今日额度已用尽,请求已停止。请选择其它模型或调整限额。',
|
|
39
38
|
fullSwitchFailed: '没有可切换的模型,请手动选择其它模型或调整限额',
|
|
40
39
|
fullSwitchTo: '已自动切换到 {model}',
|
|
@@ -79,8 +78,7 @@ export const en = {
|
|
|
79
78
|
fullActionLabel: 'When a model is full',
|
|
80
79
|
fullStop: 'Stop and prompt',
|
|
81
80
|
fullSwitchQuota: 'Switch to another quota model',
|
|
82
|
-
fullSwitchAll: 'Switch
|
|
83
|
-
fullSwitchPriority: 'Prefer uncapped, then unmonitored',
|
|
81
|
+
fullSwitchAll: 'Switch models (quota models first, then uncapped)',
|
|
84
82
|
fullNotice: 'Today\u2019s quota for the current model is exhausted; the request was stopped. Pick another model or raise its limit.',
|
|
85
83
|
fullSwitchFailed: 'No switchable model \u2014 pick one manually or raise a limit',
|
|
86
84
|
fullSwitchTo: 'Auto-switched to {model}',
|
package/lib/types/index.js
CHANGED
|
@@ -45,6 +45,10 @@ import { assertTokenQuotaLimit, splitTokenQuotaKey } from "./invariant.js";
|
|
|
45
45
|
const TOKEN_QUOTA_SETTINGS_SCHEMA = z.object({
|
|
46
46
|
limits: z.dict(z.number().step(1).min(0)).default({}),
|
|
47
47
|
monitored: z.array(z.string()).default([]),
|
|
48
|
+
// `switchPriority` is a legacy value accepted for documents saved by older
|
|
49
|
+
// plugin versions; the runtime normalizes it to `switchAll` (see
|
|
50
|
+
// settingsSource below) so existing users keep auto-switching behavior
|
|
51
|
+
// without reconfiguring.
|
|
48
52
|
onFull: z.union(['stop', 'switchQuota', 'switchAll', 'switchPriority']).default('stop'),
|
|
49
53
|
// `reset` is a user-facing preference outside the validated surface: the
|
|
50
54
|
// panel writes it and the host validates the shape at runtime. `z.any` with
|
|
@@ -147,7 +151,9 @@ export class TokenQuotaService extends Service {
|
|
|
147
151
|
return {
|
|
148
152
|
limits: doc.limits ?? {},
|
|
149
153
|
monitored: doc.monitored ?? [],
|
|
150
|
-
|
|
154
|
+
// Legacy `switchPriority` (removed in 0.1.7) maps to `switchAll`:
|
|
155
|
+
// capped models first, then uncapped — both monitored-only.
|
|
156
|
+
onFull: doc.onFull === 'switchPriority' ? 'switchAll' : (doc.onFull ?? 'stop'),
|
|
151
157
|
reset: doc.reset ?? undefined,
|
|
152
158
|
};
|
|
153
159
|
};
|
|
@@ -362,12 +368,6 @@ export class TokenQuotaService extends Service {
|
|
|
362
368
|
return { limit, used };
|
|
363
369
|
};
|
|
364
370
|
const isMonitored = (key) => this.isMonitored(key);
|
|
365
|
-
const isAvailable = (key) => {
|
|
366
|
-
if (!isMonitored(key))
|
|
367
|
-
return false;
|
|
368
|
-
const { limit, used } = availability(key);
|
|
369
|
-
return limit <= 0 || used < limit;
|
|
370
|
-
};
|
|
371
371
|
// Build candidate list excluding the currently exhausted model.
|
|
372
372
|
const candidates = this.cachedModels
|
|
373
373
|
.filter(({ provider, model }) => tokenQuotaKey(provider, model) !== currentKey)
|
|
@@ -386,21 +386,16 @@ export class TokenQuotaService extends Service {
|
|
|
386
386
|
return eligible[0];
|
|
387
387
|
}
|
|
388
388
|
case 'switchAll': {
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const unmonitored = candidates.find(c => !c.monitored);
|
|
400
|
-
if (unmonitored !== undefined)
|
|
401
|
-
return unmonitored;
|
|
402
|
-
const free = candidates.find(c => isAvailable(c.key));
|
|
403
|
-
return free;
|
|
389
|
+
// Monitored models only. Capped models with headroom first (lowest
|
|
390
|
+
// fill ratio wins, spreading load), then uncapped monitored models as
|
|
391
|
+
// fallback — quotas are preferred, uncapped only when every capped
|
|
392
|
+
// monitored model is exhausted.
|
|
393
|
+
const cappedFree = candidates
|
|
394
|
+
.filter(c => c.monitored && c.limit > 0 && c.used < c.limit)
|
|
395
|
+
.sort((a, b) => (a.used / a.limit) - (b.used / b.limit));
|
|
396
|
+
if (cappedFree.length > 0)
|
|
397
|
+
return cappedFree[0];
|
|
398
|
+
return candidates.find(c => c.monitored && c.limit <= 0);
|
|
404
399
|
}
|
|
405
400
|
default:
|
|
406
401
|
return undefined;
|
package/lib/types/types.d.ts
CHANGED
|
@@ -16,10 +16,10 @@ export declare const TOKEN_QUOTA_NAMESPACE = "token-quota";
|
|
|
16
16
|
export declare const TOKEN_QUOTA_EXCEEDED_CODE = "TOKEN_QUOTA_EXCEEDED";
|
|
17
17
|
/**
|
|
18
18
|
* What to do once a monitored, quota-capped model reaches its daily cap.
|
|
19
|
-
* Selected in the panel's settings dialog; the panel acts on it (b/c
|
|
19
|
+
* Selected in the panel's settings dialog; the panel acts on it (b/c auto
|
|
20
20
|
* switch, a stops and prompts).
|
|
21
21
|
*/
|
|
22
|
-
export declare const TOKEN_QUOTA_FULL_ACTIONS: readonly ["stop", "switchQuota", "switchAll"
|
|
22
|
+
export declare const TOKEN_QUOTA_FULL_ACTIONS: readonly ["stop", "switchQuota", "switchAll"];
|
|
23
23
|
/** One of the {@link TOKEN_QUOTA_FULL_ACTIONS} values. */
|
|
24
24
|
export type TokenQuotaFullAction = typeof TOKEN_QUOTA_FULL_ACTIONS[number];
|
|
25
25
|
/**
|
|
@@ -58,8 +58,9 @@ export interface TokenQuotaSettings {
|
|
|
58
58
|
/**
|
|
59
59
|
* Behavior when a monitored, capped model hits its daily cap:
|
|
60
60
|
* `'stop'` stops and prompts, `'switchQuota'` auto-switches to another
|
|
61
|
-
* capped-but-available model, `'switchAll'` switches to
|
|
62
|
-
* model
|
|
61
|
+
* monitored capped-but-available model, `'switchAll'` auto-switches to
|
|
62
|
+
* another monitored available model — capped models first, uncapped ones
|
|
63
|
+
* as fallback. Only monitored models ever participate in a switch.
|
|
63
64
|
*/
|
|
64
65
|
onFull: TokenQuotaFullAction;
|
|
65
66
|
/**
|
package/lib/types/types.js
CHANGED
|
@@ -16,10 +16,10 @@ export const TOKEN_QUOTA_NAMESPACE = 'token-quota';
|
|
|
16
16
|
export const TOKEN_QUOTA_EXCEEDED_CODE = 'TOKEN_QUOTA_EXCEEDED';
|
|
17
17
|
/**
|
|
18
18
|
* What to do once a monitored, quota-capped model reaches its daily cap.
|
|
19
|
-
* Selected in the panel's settings dialog; the panel acts on it (b/c
|
|
19
|
+
* Selected in the panel's settings dialog; the panel acts on it (b/c auto
|
|
20
20
|
* switch, a stops and prompts).
|
|
21
21
|
*/
|
|
22
|
-
export const TOKEN_QUOTA_FULL_ACTIONS = ['stop', 'switchQuota', 'switchAll'
|
|
22
|
+
export const TOKEN_QUOTA_FULL_ACTIONS = ['stop', 'switchQuota', 'switchAll'];
|
|
23
23
|
/** Default reset: machine-local midnight (offset = host timezone, 00:00). */
|
|
24
24
|
export const TOKEN_QUOTA_DEFAULT_RESET = { offsetHours: 0, hour: 0, minute: 0 };
|
|
25
25
|
/** Build the stable per-model key shared by the counter, settings, and snapshot. */
|
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.8",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@deepseek-ai/dsh-user-approval": "*",
|
|
78
78
|
"@deepseek-ai/dsh-user-questions": "*",
|
|
79
79
|
"@deepseek-ai/dsh-workspace": "*",
|
|
80
|
-
"@deepseek-ai/schemastery": "
|
|
80
|
+
"@deepseek-ai/schemastery": "*"
|
|
81
81
|
},
|
|
82
82
|
"peerDependenciesMeta": {
|
|
83
83
|
"@deepseek-ai/cordis": {
|