dsh-account-pool 0.2.1 → 0.2.2

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.
Files changed (3) hide show
  1. package/README.md +14 -1
  2. package/lib/client.js +31 -59
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -117,6 +117,14 @@ dsh plugin --profile web add dsh-account-pool
117
117
 
118
118
  全完成显示绿色 `3/3 已完成`,部分完成显示黄色 `2/3`,没做显示灰色 `0/3`。
119
119
 
120
+ 清单底部还有一行**今日获得积分**:点「全部执行」后,用**执行前后的余额差**
121
+ 算出这次实际到手的积分。
122
+
123
+ 为什么用差值:签到接口只回成功/失败、不回奖励数量,Trae 的任务流也没有
124
+ 计费字段——余额差是唯一可靠的真值。只把**正差值**算作获得(负差值可能是
125
+ 期间用了额度);算不出时显示 `—` 而不是编造数字;部分账号缺数据时会注明
126
+ 「合计可能偏低」。
127
+
120
128
  ### 只读与执行分离
121
129
 
122
130
  **打开页面只做只读查询,不会替你签到或派出。** 点「全部执行」才真正执行。
@@ -176,10 +184,15 @@ dsh plugin --profile web add dsh-account-pool
176
184
  |---|---|
177
185
  | 请求数 / 失败数 | **失败的尝试也计入请求数**,这样「重试放大」才看得出来 |
178
186
  | 输入 / 输出 / 总 tokens | 取自上游 SSE 末尾的 `usage` 帧 |
179
- | 积分消耗 | 上游 `usage.credit` |
187
+ | 积分消耗 | 上游 `usage.credit`。**只有逐次上报消耗的上游才有这一格**(WorkBuddy);Trae 的对话流没有计费字段,该指标整块隐藏,而不是显示恒为 0 |
180
188
  | 平均延迟 | 按样本数加权,不是对每桶均值再取平均 |
181
189
  | 按模型明细 | 每个模型的请求、失败、token、积分 |
182
190
 
191
+ > Trae 为什么没有积分消耗:它的对话流只有 6 种事件
192
+ > (`metadata` / `timing_cost` / `output` / `extra_info` / `token_usage` / `done`),
193
+ > 没有任何计费字段。积分接口虽然能给「账号累计已消耗」,但那是账号总量、
194
+ > 不是本页消耗,混着展示会误导,所以不提供。
195
+
183
196
  保留策略:按小时分桶;当桶数超过上限(20 万)时,把**超过 90 天**的小时桶
184
197
  折叠为日桶(日桶长期保留)。折叠由**桶数上限触发**,不是按时间定时执行——
185
198
  所以在流量不大的情况下,历史小时桶会原样保留,不会自动精简。
package/lib/client.js CHANGED
@@ -453,26 +453,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
453
453
  h("td", { style: Object.assign({}, TD_STYLE, { fontSize: "12px", opacity: 0.7 }) }, note || ""),
454
454
  );
455
455
 
456
- /**
457
- * 「今日获得积分」统计行。
458
- *
459
- * 数据来源是执行前后两次余额的差值(签到接口不回奖励数量,
460
- * Trae 的任务流也没有计费字段)。所以:
461
- * - 没执行过 → 显示「未执行」,不猜
462
- * - 执行过但算式缺数据 → 显示「—」
463
- * - 有数字 → 显示合计,部分账号缺数据时加注
464
- */
465
- const earnedRow = () => h("tr", { key: "earned" },
466
- h("td", { style: Object.assign({}, TD_STYLE, { fontWeight: 600 }) }, "今日获得积分"),
467
- h("td", { style: Object.assign({}, TD_STYLE, NUM_STYLE, { color: "var(--dsw-alias-state-success-primary)" }) },
468
- typeof lastRun?.totalEarned === "number"
469
- ? "+" + formatNumber(lastRun.totalEarned)
470
- : h("span", { style: { opacity: 0.5 } }, lastRun ? "—" : "未执行")),
471
- h("td", { style: Object.assign({}, TD_STYLE, { fontSize: "12px", opacity: 0.7 }) },
472
- typeof lastRun?.totalEarned === "number"
473
- ? (lastRun.earnedPartial ? "部分账号余额未取到,合计可能偏低" : "执行前后余额之差")
474
- : "点「全部执行」后统计"),
475
- );
476
456
 
477
457
  return h("div", null,
478
458
  h("div", { style: CARD_STYLE },
@@ -501,7 +481,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
501
481
  const map = {};
502
482
  for (const r of out.results || []) map[r.accountId] = r;
503
483
  // 把「本次获得的总积分」也带进 lastRun,供统计行显示
504
- onRunDone(map, { totalEarned: out.totalEarned, earnedPartial: out.earnedPartial });
484
+ onRunDone(map);
505
485
  // 提示里带上实际到手的积分,比干巴巴一句"已完成"有用
506
486
  setNotice(region, "ok", grantedText(out.totalEarned, "每日任务"));
507
487
  // 重新拉只读状态,让旅行/抽奖/连登的完成数同步更新
@@ -535,7 +515,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
535
515
  taskRow("猫猫旅行", travelDone, "到站领奖 · 空闲派出", "今日已派或在途都算完成"),
536
516
  taskRow("连登兑换", redeemDone, "满 7/14/28 天可兑换", redeemPending > 0 ? redeemPending + " 个账号有可兑换档位" : "没有待兑换的档位"),
537
517
  taskRow("抽奖", lotteryDone, "次数来自连登兑换", lotteryPending > 0 ? lotteryPending + " 个账号有抽奖次数" : "暂无抽奖次数"),
538
- earnedRow(),
539
518
  ),
540
519
  ),
541
520
 
@@ -555,6 +534,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
555
534
  h("th", { style: TH_STYLE }, "猫"),
556
535
  h("th", { style: TH_STYLE }, "旅行"),
557
536
  h("th", { style: TH_STYLE }, "抽奖次数"),
537
+ h("th", { style: TH_STYLE }, "今日获得"),
558
538
  )),
559
539
  h("tbody", null, accounts.map(a => h("tr", { key: a.accountId },
560
540
  h("td", { style: TD_STYLE }, a.nickname || a.accountId?.slice(0, 8) || "—"),
@@ -580,6 +560,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
580
560
  : h("span", { style: { opacity: 0.5 } }, "—")),
581
561
  h("td", { style: TD_STYLE },
582
562
  a.lottery !== undefined ? String(a.lottery.chances) : h("span", { style: { opacity: 0.5 } }, "—")),
563
+ h("td", { style: TD_STYLE }, earnedCell(a, lastRun)),
583
564
  ))),
584
565
  ),
585
566
  ),
@@ -633,6 +614,27 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
633
614
  return what + "完成,获得 " + formatNumber(totalEarned) + " 积分";
634
615
  }
635
616
 
617
+ /**
618
+ * 账号明细里的「今日获得」单元格。
619
+ *
620
+ * 数值来自本次执行的**余额前后差**(后端在 tasks/daily 里算好,
621
+ * 挂在每账号结果的 earnedCredits 上)。
622
+ *
623
+ * 三态刻意区分开:
624
+ * 没执行过 → 未执行(灰)
625
+ * 算出来了 → +N(绿);0 也显示 +0,因为「确实没加」与「不知道」不同
626
+ * 算不出 → —(灰),不编造
627
+ */
628
+ function earnedCell(account, lastRun) {
629
+ const run = lastRun?.[account.accountId];
630
+ if (!run) return h("span", { style: { opacity: 0.5 } }, "未执行");
631
+ const earned = run.earnedCredits;
632
+ if (typeof earned !== "number") return h("span", { style: { opacity: 0.5 } }, "—");
633
+ return h("span", {
634
+ style: { color: earned > 0 ? "var(--dsw-alias-state-success-primary)" : "inherit" },
635
+ }, "+" + formatNumber(earned));
636
+ }
637
+
636
638
  function checkinCell(account) {
637
639
  if (account.checkinError) {
638
640
  return h("span", { style: { color: "var(--dsw-alias-state-error-primary)", fontSize: "12px" } }, "查询失败");
@@ -665,23 +667,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
665
667
 
666
668
  const sumCredits = accounts.reduce((sum, a) => sum + (typeof a.credits === "number" ? a.credits : 0), 0);
667
669
 
668
- /**
669
- * 「今日获得积分」统计行。
670
- *
671
- * 与 WorkBuddy 同源:执行前后两次余额的差值。Trae 的签到接口
672
- * 只回成功/失败,任务流也没有计费字段,差值是真值。
673
- */
674
- const earnedRow = () => h("tr", { key: "earned" },
675
- h("td", { style: Object.assign({}, TD_STYLE, { fontWeight: 600 }) }, "今日获得积分"),
676
- h("td", { style: Object.assign({}, TD_STYLE, NUM_STYLE, { color: "var(--dsw-alias-state-success-primary)" }) },
677
- typeof lastRun?.totalEarned === "number"
678
- ? "+" + formatNumber(lastRun.totalEarned)
679
- : h("span", { style: { opacity: 0.5 } }, lastRun ? "—" : "未执行")),
680
- h("td", { style: Object.assign({}, TD_STYLE, { fontSize: "12px", opacity: 0.7 }) },
681
- typeof lastRun?.totalEarned === "number"
682
- ? (lastRun.earnedPartial ? "部分账号余额未取到,合计可能偏低" : "执行前后余额之差")
683
- : "点「全部执行」后统计"),
684
- );
685
670
 
686
671
  const taskRow = (name, done, note) => h("tr", { key: name },
687
672
  h("td", { style: TD_STYLE }, name),
@@ -715,7 +700,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
715
700
  if (!out.ok) throw new Error(out.error || "执行失败");
716
701
  const map = {};
717
702
  for (const r of out.results || []) map[r.accountId] = r;
718
- onRunDone(map, { totalEarned: out.totalEarned, earnedPartial: out.earnedPartial });
703
+ onRunDone(map);
719
704
  setNotice(region, "ok", grantedText(out.totalEarned, "签到"));
720
705
  await reload();
721
706
  } catch (error) {
@@ -745,7 +730,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
745
730
  h("tbody", null,
746
731
  taskRow("每日签到", checkedIn, "每天一次,先查状态再领取,不会重复领"),
747
732
  taskRow("积分查询", withCredits, total > 0 ? "当前合计 " + formatNumber(sumCredits) + " 积分" : "只读查询,不消耗额度"),
748
- earnedRow(),
749
733
  ),
750
734
  ),
751
735
  ),
@@ -759,6 +743,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
759
743
  h("th", { style: TH_STYLE }, "账号"),
760
744
  h("th", { style: TH_STYLE }, "今日签到"),
761
745
  h("th", { style: TH_STYLE }, "积分"),
746
+ h("th", { style: TH_STYLE }, "今日获得"),
762
747
  )),
763
748
  h("tbody", null, accounts.map(a => h("tr", { key: a.accountId },
764
749
  h("td", { style: TD_STYLE }, a.nickname || String(a.accountId).slice(0, 8)),
@@ -767,6 +752,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
767
752
  a.creditsError
768
753
  ? "—"
769
754
  : typeof a.credits === "number" ? formatNumber(a.credits) : "—"),
755
+ h("td", { style: TD_STYLE }, earnedCell(a, lastRun)),
770
756
  ))),
771
757
  ),
772
758
  )
@@ -1750,24 +1736,10 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
1750
1736
  const timer = setInterval(() => setTick(t => t + 1), 1000);
1751
1737
  return () => clearInterval(timer);
1752
1738
  }, []);
1753
- // 上次每日任务的执行结果:签到没有只读接口,靠它显示完成情况。
1754
- // 除了每账号结果(key 是 accountId),还带两个汇总结算字段:
1755
- // totalEarned 本次获得的总积分(执行前后余额之差)
1756
- // earnedPartial 是否有账号算不出差值(合计可能偏低)
1757
- const [lastRun, setLastRunState] = useState(null);
1758
- /**
1759
- * 保存执行结果。
1760
- *
1761
- * 按 accountId 建立索引,同时把汇总字段挂在同一个对象上——
1762
- * 这样「按账号取结果」和「读合计」共用一份状态,不用两个 state
1763
- * 引起额外的重渲染。
1764
- */
1765
- const setLastRun = useCallback((results, summary) => {
1766
- setLastRunState(Object.assign({}, results, {
1767
- totalEarned: summary?.totalEarned,
1768
- earnedPartial: summary?.earnedPartial === true,
1769
- }));
1770
- }, []);
1739
+ // 上次每日任务的执行结果,按 accountId 索引。
1740
+ // 清单里的「完成数」和明细里的「今日获得」都从它取
1741
+ //(签到没有只读接口,这些只能靠执行结果)。
1742
+ const [lastRun, setLastRun] = useState(null);
1771
1743
  const pollTimer = useRef(null);
1772
1744
 
1773
1745
  /** 给某个区域设一条提示信息。 */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-account-pool",
3
3
  "displayName": "Account Pool",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "description": "把多个 WorkBuddy / Trae 账号汇成账号池接入 DeepSeek Harness:自动切换、限流熔断退避、凭证安全落盘",
6
6
  "type": "module",
7
7
  "license": "MIT",