@wannanbigpig/dsh-usage-stats 0.1.1 → 0.1.3
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/README.md
CHANGED
|
@@ -24,6 +24,16 @@ DeepSeek official balance, token usage, a contribution heatmap, and per-hour sta
|
|
|
24
24
|
|
|
25
25
|
界面支持中文和英文。Token 数据来自会话事件中的 provider-reported `usage`(`assistant/chunk` 或 `assistant/message`),不是本地估算;「消费金额」是根据模型单价 × Token 数计算的**估算值**,请以 DeepSeek 官方账单为准。统计、限额判定与「今日」口径均按**北京时间**(服务端下发 `today` 字段,客户端优先使用),机器或浏览器时区不是 UTC+8 也保持一致。
|
|
26
26
|
|
|
27
|
+
## 界面预览 / Screenshots
|
|
28
|
+
|
|
29
|
+
「用量/余额」查询中心(概览标签):DeepSeek 官方余额卡、用量预警、Token 汇总、年度贡献热图与按小时统计。
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
「设置 → 用量与计费」:按 API Key(或全局)配置每日消费限额、余额提醒线与预警比例,硬停止默认关闭。
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
27
37
|
## 快速安装 / Quick start
|
|
28
38
|
|
|
29
39
|
需要 DeepSeek Harness `web` profile(`@deepseek-ai/dsh >= 0.1.0-rc.7`,`dsh plugin` 子命令自该版本引入)与 [pnpm](https://pnpm.io/installation)(`dsh plugin` 会把参数转发给 profile 目录里的 pnpm,因此所有 pnpm 子命令都可用)。
|
|
@@ -123,7 +133,7 @@ DEEPSEEK_API_KEY: sk-your-key-here
|
|
|
123
133
|
|
|
124
134
|
### 用量提醒与限额(设置 → 用量与计费)
|
|
125
135
|
|
|
126
|
-
「设置 → 用量与计费」页面承载限额配置(已从查询弹窗迁出,弹窗保持只读)。可**按 Key
|
|
136
|
+
「设置 → 用量与计费」页面承载限额配置(已从查询弹窗迁出,弹窗保持只读)。可**按 Key(或全局)**配置;**仅配置一个 API Key 时,「目标 API Key」选择器自动隐藏**,直接配置全局规则即可(单 Key 下全局规则就是生效规则):
|
|
127
137
|
|
|
128
138
|
- **启用限额**:开关。
|
|
129
139
|
- **每日消费限额**(CNY):今日估算消费达到限额 × `alertPercent`(默认 80%)→ 黄色预警;达到限额 × `criticalPercent`(默认 90%)→ 红色已超限(仅提醒与告警,不拦截);两个比例都可在设置页调整。
|
|
Binary file
|
|
Binary file
|
package/lib/client.js
CHANGED
|
@@ -1095,7 +1095,9 @@ window.__ModuleLoader__.load({
|
|
|
1095
1095
|
const [limits, setLimits] = react.useState(null);
|
|
1096
1096
|
const limitsRef = react.useRef(null);
|
|
1097
1097
|
const [statusMap, setStatusMap] = react.useState({});
|
|
1098
|
+
const isSingleKey = (keys || []).length <= 1;
|
|
1098
1099
|
const [activeKey, setActiveKey] = react.useState(() => {
|
|
1100
|
+
if (isSingleKey) return "__global__";
|
|
1099
1101
|
const stored = safeGetStorage("dsh_usage_limits_active_key");
|
|
1100
1102
|
if (stored !== null && stored !== "") return stored;
|
|
1101
1103
|
return selectedKey ?? "__global__";
|
|
@@ -1134,6 +1136,10 @@ window.__ModuleLoader__.load({
|
|
|
1134
1136
|
|
|
1135
1137
|
// Sync activeKey when selectedKey becomes available (if not explicitly chosen in storage)
|
|
1136
1138
|
react.useEffect(() => {
|
|
1139
|
+
if (isSingleKey) {
|
|
1140
|
+
setActiveKey("__global__");
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1137
1143
|
if (selectedKey !== null && selectedKey !== undefined && selectedKey !== "") {
|
|
1138
1144
|
const stored = safeGetStorage("dsh_usage_limits_active_key");
|
|
1139
1145
|
if (stored) {
|
|
@@ -1142,7 +1148,7 @@ window.__ModuleLoader__.load({
|
|
|
1142
1148
|
}
|
|
1143
1149
|
setActiveKey(selectedKey);
|
|
1144
1150
|
}
|
|
1145
|
-
}, [selectedKey]);
|
|
1151
|
+
}, [selectedKey, isSingleKey]);
|
|
1146
1152
|
|
|
1147
1153
|
// Update form fields when activeKey or limits payload change
|
|
1148
1154
|
react.useEffect(() => {
|
|
@@ -1160,6 +1166,7 @@ window.__ModuleLoader__.load({
|
|
|
1160
1166
|
}, [activeKey, limits]);
|
|
1161
1167
|
|
|
1162
1168
|
const handleKeySelect = (newKey) => {
|
|
1169
|
+
if (isSingleKey) return;
|
|
1163
1170
|
// Do not strand an unsaved batch on the previous key's form.
|
|
1164
1171
|
if (pendingRef.current !== null && !savingRef.current) flushSave();
|
|
1165
1172
|
setActiveKey(newKey);
|
|
@@ -1306,8 +1313,8 @@ window.__ModuleLoader__.load({
|
|
|
1306
1313
|
}),
|
|
1307
1314
|
react_jsx_runtime.jsx("p", { className: S.note, children: translate("limits.desc") }),
|
|
1308
1315
|
error && react_jsx_runtime.jsx("div", { className: S.error, children: error }),
|
|
1309
|
-
// Key selection
|
|
1310
|
-
react_jsx_runtime.jsxs("label", {
|
|
1316
|
+
// Key selection — hidden when only one key is configured (the global rule IS the key rule).
|
|
1317
|
+
keys.length > 1 && react_jsx_runtime.jsxs("label", {
|
|
1311
1318
|
className: S.pickerRow,
|
|
1312
1319
|
children: [
|
|
1313
1320
|
react_jsx_runtime.jsxs("span", {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wannanbigpig/dsh-usage-stats",
|
|
3
3
|
"description": "DeepSeek 官方余额、Token 用量、月历热图与离线 tokenizer,内置在 Harness 侧栏",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/wannanbigpig/dsh-usage-stats.git"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"files": [
|
|
19
19
|
"lib/",
|
|
20
|
+
"assets/",
|
|
20
21
|
"cordis.patch.yml",
|
|
21
22
|
"README.md",
|
|
22
23
|
"LICENSE"
|