dsh-codearts 1.2.8 → 1.2.10
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/CHANGELOG.md +23 -0
- package/lib/bin.mjs +2 -2
- package/lib/client/index.d.cts +6 -0
- package/lib/client/index.js +216 -143
- package/lib/index.mjs +78 -14
- package/lib/{usage-B2LNsUuR.mjs → usage-CjPd0Gok.mjs} +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,29 @@
|
|
|
3
3
|
本文件记录本插件的重要改动。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
4
4
|
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
5
5
|
|
|
6
|
+
## [1.2.10] - 2026-11-06
|
|
7
|
+
|
|
8
|
+
### 新增
|
|
9
|
+
|
|
10
|
+
- **每个账号都能「重新登录」,凭证写回原条目**:以前账号过期时卡片上只有「删除」,
|
|
11
|
+
要先删掉再加回来,账号的展示顺序和备注全丢。现在账号行多了「重新登录」按钮
|
|
12
|
+
(过期的账号显示为主色按钮),走一遍浏览器 OAuth 就把新凭证写回同一条,id、顺序、
|
|
13
|
+
备注都保留。手工粘贴 token 的账号同样适用。
|
|
14
|
+
- 点了 A 账号的重登却登成了 B 账号时,B 会作为新账号添加,A 原样不动,并提示
|
|
15
|
+
「你登录的是另一个账号,已作为新账号添加;原账号保持不变」——不会把 A 的凭证
|
|
16
|
+
悄悄换成别人的。
|
|
17
|
+
|
|
18
|
+
## [1.2.9] - 2026-11-06
|
|
19
|
+
|
|
20
|
+
### 变更
|
|
21
|
+
|
|
22
|
+
- **热力图的悬停提示统一成明细卡**:日历格子和逐小时格子原来只有浏览器原生
|
|
23
|
+
`title`(一个灰底小文字框),下面再挂一行同内容的小字;现在和「按账号 / 按模型」
|
|
24
|
+
的用量条共用同一张悬停卡 —— 标题、分隔线、输入 / 输出 / 思考 / 缓存 / 请求 /
|
|
25
|
+
命中率,数字精确到个位。卡片贴着指针画(格子只有 36px 宽,锚在格子上会横穿整张
|
|
26
|
+
卡片),靠近视口右/下边界时自动翻到另一侧。底部那行改成固定的操作提示,不再复述
|
|
27
|
+
明细。
|
|
28
|
+
|
|
6
29
|
## [1.2.8] - 2026-11-05
|
|
7
30
|
|
|
8
31
|
### 变更
|
package/lib/bin.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { R as isBenefitModel, V as CodeArtsAccountStore, W as codeartsAccountsPath, d as fetchCallerIdentity, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker } from "./usage-
|
|
2
|
+
import { R as isBenefitModel, V as CodeArtsAccountStore, W as codeartsAccountsPath, d as fetchCallerIdentity, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker } from "./usage-CjPd0Gok.mjs";
|
|
3
3
|
import { existsSync, statSync } from "node:fs";
|
|
4
4
|
//#region src/version.ts
|
|
5
|
-
const CODEARTS_VERSION = "1.2.
|
|
5
|
+
const CODEARTS_VERSION = "1.2.10";
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/bin.ts
|
|
8
8
|
/**
|
package/lib/client/index.d.cts
CHANGED
|
@@ -32,6 +32,12 @@ interface CodeArtsSettingsKey {
|
|
|
32
32
|
expiredHint: string;
|
|
33
33
|
accountsTitle: string;
|
|
34
34
|
accountRemove: string;
|
|
35
|
+
/** 重新登录这个账号:新凭证写回原条目,不会多出一条。 */
|
|
36
|
+
accountRelogin: string;
|
|
37
|
+
/** 该账号正在浏览器里授权。 */
|
|
38
|
+
reloginPending: string;
|
|
39
|
+
/** 「重新登录」却登了另一个账号:已作为新账号添加,原账号未动。 */
|
|
40
|
+
reloginOtherAccount: string;
|
|
35
41
|
addAccount: string;
|
|
36
42
|
pasteTokenAdd: string;
|
|
37
43
|
accountsRotateHint: string;
|
package/lib/client/index.js
CHANGED
|
@@ -62,7 +62,7 @@ function subscribeSidebarPanelWanted(listener) {
|
|
|
62
62
|
}
|
|
63
63
|
//#endregion
|
|
64
64
|
//#region \0dsh-css:/home/runner/work/dsh-codearts/dsh-codearts/src/client/CodeArtsPluginCard.module.css.mjs
|
|
65
|
-
const css$1 = ".xoziZG_card{border:.5px solid var(--dsw-alias-settings-card-stroke);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-settings-card-fill);max-width:720px}.xoziZG_header{align-items:flex-start;gap:12px;padding:14px 16px;display:flex}.xoziZG_headText{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.xoziZG_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:22px}.xoziZG_desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}.xoziZG_statusLine{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;font-size:14px;font-weight:500;line-height:22px;display:inline-flex}.xoziZG_meta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:18px}.xoziZG_body{border-top:.5px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 16px}.xoziZG_tabs{margin-top:12px}.xoziZG_tabPanel{padding-top:2px}.xoziZG_accountToolbar{gap:8px;margin-top:12px;display:flex}.xoziZG_accountToolbar>*{flex:1}.xoziZG_manualForm{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);margin-top:12px;padding:12px}.xoziZG_accountCard{flex-direction:column;gap:10px;margin-top:12px;display:flex}.xoziZG_accountEntry{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-2)}.xoziZG_accountRow{align-items:center;gap:10px;padding:12px;display:flex}.xoziZG_claimAllRow{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:flex-end;padding:10px 12px 0;display:flex}.xoziZG_avatar{background:var(--dsw-alias-bg-layer-3);width:32px;height:32px;color:var(--dsw-alias-label-primary);border-radius:50%;flex:none;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:inline-flex}.xoziZG_accountInfo{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.xoziZG_accountNameRow{align-items:center;gap:6px;min-width:0;display:flex}.xoziZG_accountName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:600;line-height:20px;overflow:hidden}.xoziZG_accountRowActions{flex:none;gap:6px;display:flex}.xoziZG_accountHint{color:var(--dsw-alias-label-tertiary);margin:0;padding:0 12px 12px;font-size:12px;line-height:18px}.xoziZG_creditBlock{border-top:.5px solid var(--dsw-alias-border-l2);padding:12px}.xoziZG_balanceRow{flex-wrap:wrap;align-items:baseline;gap:6px;display:flex}.xoziZG_balance{color:var(--dsw-alias-label-primary);letter-spacing:-.02em;font-variant-numeric:tabular-nums;font-size:28px;font-weight:600;line-height:34px}.xoziZG_balanceUnit{color:var(--dsw-alias-label-secondary);font-size:12px}.xoziZG_balanceMeta{color:var(--dsw-alias-label-tertiary);margin-left:2px;font-size:12px}.xoziZG_updated{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;margin-left:auto;font-size:12px}.xoziZG_creditRows{flex-direction:column;gap:4px;margin-top:8px;display:flex}.xoziZG_creditRow{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;justify-content:space-between;align-items:baseline;gap:12px;font-size:12px;line-height:18px;display:flex}.xoziZG_usageBar{background:var(--dsw-alias-border-l2);border-radius:2px;height:4px;margin-top:4px;display:block;overflow:hidden}.xoziZG_usageFill{background:var(--dsw-alias-brand-primary);border-radius:2px;height:100%;transition:width .2s;display:block}.xoziZG_expiryRow{margin-top:2px}.xoziZG_expiryLabel{color:var(--dsw-alias-state-warn-label)}.xoziZG_bar{background:var(--dsw-alias-bg-layer-3);border-radius:2px;height:4px;margin-top:6px;display:block;overflow:hidden}.xoziZG_barFill{background:var(--dsw-alias-state-warn-primary);border-radius:2px;height:100%;display:block}.xoziZG_creditLink{margin-top:8px;display:inline-block}.xoziZG_creditFooter{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:8px;margin-top:12px;padding-top:10px;display:flex}.xoziZG_creditHint{color:var(--dsw-alias-label-tertiary);margin:8px 0 0;font-size:12px;line-height:18px}.xoziZG_section{margin-top:16px}.xoziZG_sectionHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.xoziZG_sectionLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;font-weight:500}.xoziZG_count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:12px}.xoziZG_hint{color:var(--dsw-alias-label-secondary);margin:8px 0 0;font-size:13px;line-height:20px}.xoziZG_error{color:var(--dsw-alias-state-error-primary);margin:10px 0 0;font-size:13px;line-height:20px}.xoziZG_actions{flex-wrap:wrap;align-items:center;gap:8px;margin-top:12px;display:flex}.xoziZG_danger{color:var(--dsw-alias-state-error-primary)}.xoziZG_link{appearance:none;color:var(--dsw-alias-brand-text);font:inherit;text-align:left;word-break:break-all;cursor:pointer;background:0 0;border:none;padding:0;font-size:12px}.xoziZG_link:hover{text-decoration:underline}.xoziZG_choices{flex-direction:column;gap:2px;margin-top:8px;display:flex}.xoziZG_choiceRow{border-radius:var(--dsw-radius-sm);align-items:center;gap:8px;margin:0 -6px;padding:5px 6px;display:flex}.xoziZG_choiceRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.xoziZG_statGrid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:10px 0 14px;display:grid}.xoziZG_statCard{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);flex-direction:column;gap:1px;padding:8px 10px;display:flex}.xoziZG_statLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.xoziZG_statValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:15px;line-height:20px}.xoziZG_statSub{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px;line-height:16px}.xoziZG_modelChart{flex-direction:column;gap:2px;margin-top:8px;display:flex}.xoziZG_modelRow{font-variant-numeric:tabular-nums;border-radius:6px;grid-template-columns:minmax(0,1.2fr) minmax(48px,1fr) 56px 52px 64px;align-items:center;gap:8px;padding:4px 0;display:grid;position:relative}.xoziZG_modelRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.xoziZG_usageTip{z-index:5;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);min-width:180px;max-width:260px;color:var(--dsw-alias-label-secondary);text-align:left;font-variant-numeric:tabular-nums;pointer-events:none;padding:8px 10px;font-size:12px;line-height:1.9;position:absolute;bottom:calc(100% + 6px);right:0;box-shadow:0 10px 28px #00000073}.xoziZG_usageTipName{max-width:240px;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.xoziZG_usageTipSep{background:var(--dsw-alias-border-l2);height:1px;margin:4px 0}.xoziZG_usageTipRow{justify-content:space-between;gap:24px;display:flex}.xoziZG_usageTipRow span:last-child{color:var(--dsw-alias-label-primary);font-weight:600}.xoziZG_modelName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.xoziZG_modelTrack{background:var(--dsw-alias-border-l2);border-radius:4px;height:8px;display:block;overflow:hidden}.xoziZG_modelFill{background:var(--dsw-alias-brand-primary);border-radius:4px;height:100%;transition:width .16s;display:block}.xoziZG_modelTokens,.xoziZG_modelShare,.xoziZG_modelRequests{color:var(--dsw-alias-label-secondary);text-align:right;white-space:nowrap;font-size:11px;line-height:16px}.xoziZG_modelRequests{color:var(--dsw-alias-label-tertiary)}.xoziZG_heatGrid{grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;margin:8px 0 2px;display:grid}.xoziZG_heatWeekday{color:var(--dsw-alias-label-tertiary);text-align:center;font-size:10px;line-height:14px}.xoziZG_heatCell{background:color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);height:36px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;border:0;border-radius:8px;outline:0;justify-content:center;align-items:center;font-size:12px;transition:background .12s ease-out;display:flex}.xoziZG_heatCell[data-tone=empty]{color:var(--dsw-alias-label-tertiary)}.xoziZG_heatCell[data-tone=pad]{background:0 0}.xoziZG_heatCell[data-tone=out]{color:var(--dsw-alias-label-tertiary);opacity:.45;background:0 0}.xoziZG_heatCell[data-tone=lv1]{color:#0f1115;background:#ddf4e7}.xoziZG_heatCell[data-tone=lv2]{color:#0f1115;background:#b3e8cc}.xoziZG_heatCell[data-tone=lv3]{color:#0f1115;background:#7dd8ac}.xoziZG_heatCell[data-tone=lv4]{color:#fff;background:#40c584}.xoziZG_heatCell[data-tone=lv5]{color:#fff;background:#16a34a}.xoziZG_heatCell[data-today=true]{font-weight:700;box-shadow:inset 0 -2px}.xoziZG_heatHours{grid-template-columns:repeat(24,minmax(0,1fr));gap:3px;margin:8px 0 0;display:grid}.xoziZG_heatHourCell{background:color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);border-radius:4px;height:26px;transition:background .12s ease-out}.xoziZG_heatHourCell[data-tone=lv1]{background:#ddf4e7}.xoziZG_heatHourCell[data-tone=lv2]{background:#b3e8cc}.xoziZG_heatHourCell[data-tone=lv3]{background:#7dd8ac}.xoziZG_heatHourCell[data-tone=lv4]{background:#40c584}.xoziZG_heatHourCell[data-tone=lv5]{background:#16a34a}.xoziZG_heatAxis{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;grid-template-columns:repeat(24,minmax(0,1fr));gap:3px;font-size:10px;line-height:14px;display:grid}.xoziZG_heatAxisSlot{text-align:center;white-space:nowrap;overflow:hidden}.xoziZG_heatLegend{color:var(--dsw-alias-label-tertiary);justify-content:flex-start;align-items:center;gap:3px;margin:0 0 6px;font-size:10px;display:flex}.xoziZG_heatLegendChip{border-radius:3px;width:10px;height:10px}.xoziZG_heatLegendChip[data-tone=lv1]{background:#ddf4e7}.xoziZG_heatLegendChip[data-tone=lv2]{background:#b3e8cc}.xoziZG_heatLegendChip[data-tone=lv3]{background:#7dd8ac}.xoziZG_heatLegendChip[data-tone=lv4]{background:#40c584}.xoziZG_heatLegendChip[data-tone=lv5]{background:#16a34a}.xoziZG_trendTip{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;margin:2px 0 0;font-size:11px;line-height:16px}.xoziZG_check{flex:1;min-width:0}.xoziZG_check>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.xoziZG_manual{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);margin-top:12px;padding:0 12px}.xoziZG_manual[open]{padding-bottom:12px}.xoziZG_manualSummary{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;padding:9px 0;font-size:13px;list-style:none;display:flex}.xoziZG_manualSummary::-webkit-details-marker{display:none}.xoziZG_field{flex-direction:column;gap:5px;margin-top:10px;display:flex}.xoziZG_fieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px}.xoziZG_area{box-sizing:border-box;resize:vertical;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:20px}.xoziZG_area::placeholder{color:var(--dsw-alias-label-dimmed)}.xoziZG_area:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.xoziZG_skeleton{flex-direction:column;gap:10px;padding:4px 0;display:flex}.xoziZG_skeletonRow{border-radius:var(--dsw-radius-sm,4px);background:var(--dsw-alias-border-l2);height:12px;animation:1.4s ease-in-out infinite xoziZG_skeletonBreath}.xoziZG_skeletonRow:nth-child(2){width:72%}.xoziZG_skeletonRow:nth-child(3){width:46%}@keyframes xoziZG_skeletonBreath{0%,to{opacity:.45}50%{opacity:.9}}@media (prefers-reduced-motion:reduce){.xoziZG_skeletonRow{animation:none}}";
|
|
65
|
+
const css$1 = ".xoziZG_card{border:.5px solid var(--dsw-alias-settings-card-stroke);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-settings-card-fill);max-width:720px}.xoziZG_header{align-items:flex-start;gap:12px;padding:14px 16px;display:flex}.xoziZG_headText{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.xoziZG_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:22px}.xoziZG_desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}.xoziZG_statusLine{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;font-size:14px;font-weight:500;line-height:22px;display:inline-flex}.xoziZG_meta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:18px}.xoziZG_body{border-top:.5px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 16px}.xoziZG_tabs{margin-top:12px}.xoziZG_tabPanel{padding-top:2px}.xoziZG_accountToolbar{gap:8px;margin-top:12px;display:flex}.xoziZG_accountToolbar>*{flex:1}.xoziZG_manualForm{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);margin-top:12px;padding:12px}.xoziZG_accountCard{flex-direction:column;gap:10px;margin-top:12px;display:flex}.xoziZG_accountEntry{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-2)}.xoziZG_accountRow{align-items:center;gap:10px;padding:12px;display:flex}.xoziZG_claimAllRow{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:flex-end;padding:10px 12px 0;display:flex}.xoziZG_avatar{background:var(--dsw-alias-bg-layer-3);width:32px;height:32px;color:var(--dsw-alias-label-primary);border-radius:50%;flex:none;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:inline-flex}.xoziZG_accountInfo{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.xoziZG_accountNameRow{align-items:center;gap:6px;min-width:0;display:flex}.xoziZG_accountName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:600;line-height:20px;overflow:hidden}.xoziZG_accountRowActions{flex-wrap:wrap;flex:none;justify-content:flex-end;gap:6px;display:flex}.xoziZG_accountHint{color:var(--dsw-alias-label-tertiary);margin:0;padding:0 12px 12px;font-size:12px;line-height:18px}.xoziZG_creditBlock{border-top:.5px solid var(--dsw-alias-border-l2);padding:12px}.xoziZG_balanceRow{flex-wrap:wrap;align-items:baseline;gap:6px;display:flex}.xoziZG_balance{color:var(--dsw-alias-label-primary);letter-spacing:-.02em;font-variant-numeric:tabular-nums;font-size:28px;font-weight:600;line-height:34px}.xoziZG_balanceUnit{color:var(--dsw-alias-label-secondary);font-size:12px}.xoziZG_balanceMeta{color:var(--dsw-alias-label-tertiary);margin-left:2px;font-size:12px}.xoziZG_updated{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;margin-left:auto;font-size:12px}.xoziZG_creditRows{flex-direction:column;gap:4px;margin-top:8px;display:flex}.xoziZG_creditRow{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;justify-content:space-between;align-items:baseline;gap:12px;font-size:12px;line-height:18px;display:flex}.xoziZG_usageBar{background:var(--dsw-alias-border-l2);border-radius:2px;height:4px;margin-top:4px;display:block;overflow:hidden}.xoziZG_usageFill{background:var(--dsw-alias-brand-primary);border-radius:2px;height:100%;transition:width .2s;display:block}.xoziZG_expiryRow{margin-top:2px}.xoziZG_expiryLabel{color:var(--dsw-alias-state-warn-label)}.xoziZG_bar{background:var(--dsw-alias-bg-layer-3);border-radius:2px;height:4px;margin-top:6px;display:block;overflow:hidden}.xoziZG_barFill{background:var(--dsw-alias-state-warn-primary);border-radius:2px;height:100%;display:block}.xoziZG_creditLink{margin-top:8px;display:inline-block}.xoziZG_creditFooter{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:8px;margin-top:12px;padding-top:10px;display:flex}.xoziZG_creditHint{color:var(--dsw-alias-label-tertiary);margin:8px 0 0;font-size:12px;line-height:18px}.xoziZG_section{margin-top:16px}.xoziZG_sectionHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.xoziZG_sectionLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;font-weight:500}.xoziZG_count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:12px}.xoziZG_hint{color:var(--dsw-alias-label-secondary);margin:8px 0 0;font-size:13px;line-height:20px}.xoziZG_error{color:var(--dsw-alias-state-error-primary);margin:10px 0 0;font-size:13px;line-height:20px}.xoziZG_actions{flex-wrap:wrap;align-items:center;gap:8px;margin-top:12px;display:flex}.xoziZG_danger{color:var(--dsw-alias-state-error-primary)}.xoziZG_link{appearance:none;color:var(--dsw-alias-brand-text);font:inherit;text-align:left;word-break:break-all;cursor:pointer;background:0 0;border:none;padding:0;font-size:12px}.xoziZG_link:hover{text-decoration:underline}.xoziZG_choices{flex-direction:column;gap:2px;margin-top:8px;display:flex}.xoziZG_choiceRow{border-radius:var(--dsw-radius-sm);align-items:center;gap:8px;margin:0 -6px;padding:5px 6px;display:flex}.xoziZG_choiceRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.xoziZG_statGrid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:10px 0 14px;display:grid}.xoziZG_statCard{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);flex-direction:column;gap:1px;padding:8px 10px;display:flex}.xoziZG_statLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.xoziZG_statValue{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;font-size:15px;line-height:20px}.xoziZG_statSub{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:11px;line-height:16px}.xoziZG_modelChart{flex-direction:column;gap:2px;margin-top:8px;display:flex}.xoziZG_modelRow{font-variant-numeric:tabular-nums;border-radius:6px;grid-template-columns:minmax(0,1.2fr) minmax(48px,1fr) 56px 52px 64px;align-items:center;gap:8px;padding:4px 0;display:grid;position:relative}.xoziZG_modelRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.xoziZG_usageTip{z-index:5;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);min-width:180px;max-width:260px;color:var(--dsw-alias-label-secondary);text-align:left;font-variant-numeric:tabular-nums;pointer-events:none;padding:8px 10px;font-size:12px;line-height:1.9;position:absolute;bottom:calc(100% + 6px);right:0;box-shadow:0 10px 28px #00000073}.xoziZG_usageTip[data-float=true]{z-index:40;position:fixed;bottom:auto;right:auto}.xoziZG_usageTipName{max-width:240px;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.xoziZG_usageTipSep{background:var(--dsw-alias-border-l2);height:1px;margin:4px 0}.xoziZG_usageTipRow{justify-content:space-between;gap:24px;display:flex}.xoziZG_usageTipRow span:last-child{color:var(--dsw-alias-label-primary);font-weight:600}.xoziZG_modelName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;overflow:hidden}.xoziZG_modelTrack{background:var(--dsw-alias-border-l2);border-radius:4px;height:8px;display:block;overflow:hidden}.xoziZG_modelFill{background:var(--dsw-alias-brand-primary);border-radius:4px;height:100%;transition:width .16s;display:block}.xoziZG_modelTokens,.xoziZG_modelShare,.xoziZG_modelRequests{color:var(--dsw-alias-label-secondary);text-align:right;white-space:nowrap;font-size:11px;line-height:16px}.xoziZG_modelRequests{color:var(--dsw-alias-label-tertiary)}.xoziZG_heatGrid{grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;margin:8px 0 2px;display:grid}.xoziZG_heatWeekday{color:var(--dsw-alias-label-tertiary);text-align:center;font-size:10px;line-height:14px}.xoziZG_heatCell{background:color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);height:36px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;border:0;border-radius:8px;outline:0;justify-content:center;align-items:center;font-size:12px;transition:background .12s ease-out;display:flex}.xoziZG_heatCell[data-tone=empty]{color:var(--dsw-alias-label-tertiary)}.xoziZG_heatCell[data-tone=pad]{background:0 0}.xoziZG_heatCell[data-tone=out]{color:var(--dsw-alias-label-tertiary);opacity:.45;background:0 0}.xoziZG_heatCell[data-tone=lv1]{color:#0f1115;background:#ddf4e7}.xoziZG_heatCell[data-tone=lv2]{color:#0f1115;background:#b3e8cc}.xoziZG_heatCell[data-tone=lv3]{color:#0f1115;background:#7dd8ac}.xoziZG_heatCell[data-tone=lv4]{color:#fff;background:#40c584}.xoziZG_heatCell[data-tone=lv5]{color:#fff;background:#16a34a}.xoziZG_heatCell[data-today=true]{font-weight:700;box-shadow:inset 0 -2px}.xoziZG_heatHours{grid-template-columns:repeat(24,minmax(0,1fr));gap:3px;margin:8px 0 0;display:grid}.xoziZG_heatHourCell{background:color-mix(in srgb, var(--dsw-alias-label-primary) 6%, transparent);border-radius:4px;height:26px;transition:background .12s ease-out}.xoziZG_heatHourCell[data-tone=lv1]{background:#ddf4e7}.xoziZG_heatHourCell[data-tone=lv2]{background:#b3e8cc}.xoziZG_heatHourCell[data-tone=lv3]{background:#7dd8ac}.xoziZG_heatHourCell[data-tone=lv4]{background:#40c584}.xoziZG_heatHourCell[data-tone=lv5]{background:#16a34a}.xoziZG_heatAxis{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;grid-template-columns:repeat(24,minmax(0,1fr));gap:3px;font-size:10px;line-height:14px;display:grid}.xoziZG_heatAxisSlot{text-align:center;white-space:nowrap;overflow:hidden}.xoziZG_heatLegend{color:var(--dsw-alias-label-tertiary);justify-content:flex-start;align-items:center;gap:3px;margin:0 0 6px;font-size:10px;display:flex}.xoziZG_heatLegendChip{border-radius:3px;width:10px;height:10px}.xoziZG_heatLegendChip[data-tone=lv1]{background:#ddf4e7}.xoziZG_heatLegendChip[data-tone=lv2]{background:#b3e8cc}.xoziZG_heatLegendChip[data-tone=lv3]{background:#7dd8ac}.xoziZG_heatLegendChip[data-tone=lv4]{background:#40c584}.xoziZG_heatLegendChip[data-tone=lv5]{background:#16a34a}.xoziZG_trendTip{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;margin:2px 0 0;font-size:11px;line-height:16px}.xoziZG_check{flex:1;min-width:0}.xoziZG_check>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.xoziZG_manual{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);margin-top:12px;padding:0 12px}.xoziZG_manual[open]{padding-bottom:12px}.xoziZG_manualSummary{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;padding:9px 0;font-size:13px;list-style:none;display:flex}.xoziZG_manualSummary::-webkit-details-marker{display:none}.xoziZG_field{flex-direction:column;gap:5px;margin-top:10px;display:flex}.xoziZG_fieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px}.xoziZG_area{box-sizing:border-box;resize:vertical;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:20px}.xoziZG_area::placeholder{color:var(--dsw-alias-label-dimmed)}.xoziZG_area:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.xoziZG_skeleton{flex-direction:column;gap:10px;padding:4px 0;display:flex}.xoziZG_skeletonRow{border-radius:var(--dsw-radius-sm,4px);background:var(--dsw-alias-border-l2);height:12px;animation:1.4s ease-in-out infinite xoziZG_skeletonBreath}.xoziZG_skeletonRow:nth-child(2){width:72%}.xoziZG_skeletonRow:nth-child(3){width:46%}@keyframes xoziZG_skeletonBreath{0%,to{opacity:.45}50%{opacity:.9}}@media (prefers-reduced-motion:reduce){.xoziZG_skeletonRow{animation:none}}";
|
|
66
66
|
const tagId$1 = "dsh-codearts/CodeArtsPluginCard.module.css";
|
|
67
67
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
68
68
|
const tag = document.createElement("style");
|
|
@@ -72,92 +72,92 @@ if (typeof document !== "undefined" && document.querySelector("style[data-plugin
|
|
|
72
72
|
document.head.appendChild(tag);
|
|
73
73
|
}
|
|
74
74
|
var CodeArtsPluginCard_module_css_default = {
|
|
75
|
-
"heatWeekday": "xoziZG_heatWeekday",
|
|
76
|
-
"headText": "xoziZG_headText",
|
|
77
|
-
"sectionLabel": "xoziZG_sectionLabel",
|
|
78
|
-
"avatar": "xoziZG_avatar",
|
|
79
|
-
"usageFill": "xoziZG_usageFill",
|
|
80
|
-
"creditLink": "xoziZG_creditLink",
|
|
81
|
-
"modelRequests": "xoziZG_modelRequests",
|
|
82
|
-
"hint": "xoziZG_hint",
|
|
83
|
-
"usageTipSep": "xoziZG_usageTipSep",
|
|
84
|
-
"usageTipRow": "xoziZG_usageTipRow",
|
|
85
|
-
"expiryLabel": "xoziZG_expiryLabel",
|
|
86
|
-
"area": "xoziZG_area",
|
|
87
|
-
"balanceUnit": "xoziZG_balanceUnit",
|
|
88
|
-
"sectionHead": "xoziZG_sectionHead",
|
|
89
|
-
"danger": "xoziZG_danger",
|
|
90
|
-
"modelFill": "xoziZG_modelFill",
|
|
91
|
-
"creditRow": "xoziZG_creditRow",
|
|
92
|
-
"choices": "xoziZG_choices",
|
|
93
|
-
"modelRow": "xoziZG_modelRow",
|
|
94
|
-
"creditHint": "xoziZG_creditHint",
|
|
95
|
-
"desc": "xoziZG_desc",
|
|
96
|
-
"header": "xoziZG_header",
|
|
97
75
|
"accountHint": "xoziZG_accountHint",
|
|
98
|
-
"heatCell": "xoziZG_heatCell",
|
|
99
76
|
"heatLegendChip": "xoziZG_heatLegendChip",
|
|
100
|
-
"check": "xoziZG_check",
|
|
101
|
-
"fieldLabel": "xoziZG_fieldLabel",
|
|
102
|
-
"statusLine": "xoziZG_statusLine",
|
|
103
|
-
"skeletonRow": "xoziZG_skeletonRow",
|
|
104
|
-
"tabPanel": "xoziZG_tabPanel",
|
|
105
|
-
"accountInfo": "xoziZG_accountInfo",
|
|
106
|
-
"usageBar": "xoziZG_usageBar",
|
|
107
|
-
"heatHourCell": "xoziZG_heatHourCell",
|
|
108
|
-
"creditFooter": "xoziZG_creditFooter",
|
|
109
|
-
"statValue": "xoziZG_statValue",
|
|
110
77
|
"balance": "xoziZG_balance",
|
|
111
|
-
"tabs": "xoziZG_tabs",
|
|
112
|
-
"count": "xoziZG_count",
|
|
113
|
-
"usageTip": "xoziZG_usageTip",
|
|
114
78
|
"claimAllRow": "xoziZG_claimAllRow",
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"skeleton": "xoziZG_skeleton",
|
|
124
|
-
"statSub": "xoziZG_statSub",
|
|
79
|
+
"balanceUnit": "xoziZG_balanceUnit",
|
|
80
|
+
"heatAxisSlot": "xoziZG_heatAxisSlot",
|
|
81
|
+
"creditBlock": "xoziZG_creditBlock",
|
|
82
|
+
"statusLine": "xoziZG_statusLine",
|
|
83
|
+
"modelChart": "xoziZG_modelChart",
|
|
84
|
+
"sectionHead": "xoziZG_sectionHead",
|
|
85
|
+
"usageBar": "xoziZG_usageBar",
|
|
86
|
+
"accountCard": "xoziZG_accountCard",
|
|
125
87
|
"usageTipName": "xoziZG_usageTipName",
|
|
88
|
+
"choiceRow": "xoziZG_choiceRow",
|
|
89
|
+
"fieldLabel": "xoziZG_fieldLabel",
|
|
90
|
+
"modelRow": "xoziZG_modelRow",
|
|
91
|
+
"expiryRow": "xoziZG_expiryRow",
|
|
92
|
+
"headText": "xoziZG_headText",
|
|
93
|
+
"modelTrack": "xoziZG_modelTrack",
|
|
94
|
+
"heatHourCell": "xoziZG_heatHourCell",
|
|
95
|
+
"header": "xoziZG_header",
|
|
96
|
+
"accountToolbar": "xoziZG_accountToolbar",
|
|
97
|
+
"statGrid": "xoziZG_statGrid",
|
|
98
|
+
"skeletonBreath": "xoziZG_skeletonBreath",
|
|
99
|
+
"balanceRow": "xoziZG_balanceRow",
|
|
100
|
+
"modelFill": "xoziZG_modelFill",
|
|
126
101
|
"heatAxis": "xoziZG_heatAxis",
|
|
127
|
-
"
|
|
128
|
-
"
|
|
102
|
+
"accountRow": "xoziZG_accountRow",
|
|
103
|
+
"heatGrid": "xoziZG_heatGrid",
|
|
104
|
+
"field": "xoziZG_field",
|
|
105
|
+
"link": "xoziZG_link",
|
|
106
|
+
"heatHours": "xoziZG_heatHours",
|
|
107
|
+
"tabPanel": "xoziZG_tabPanel",
|
|
108
|
+
"choices": "xoziZG_choices",
|
|
109
|
+
"desc": "xoziZG_desc",
|
|
110
|
+
"creditHint": "xoziZG_creditHint",
|
|
111
|
+
"creditFooter": "xoziZG_creditFooter",
|
|
112
|
+
"accountInfo": "xoziZG_accountInfo",
|
|
129
113
|
"manualForm": "xoziZG_manualForm",
|
|
130
|
-
"
|
|
131
|
-
"statGrid": "xoziZG_statGrid",
|
|
132
|
-
"modelTrack": "xoziZG_modelTrack",
|
|
133
|
-
"accountRowActions": "xoziZG_accountRowActions",
|
|
114
|
+
"card": "xoziZG_card",
|
|
134
115
|
"actions": "xoziZG_actions",
|
|
116
|
+
"usageFill": "xoziZG_usageFill",
|
|
117
|
+
"usageTipRow": "xoziZG_usageTipRow",
|
|
118
|
+
"modelTokens": "xoziZG_modelTokens",
|
|
135
119
|
"trendTip": "xoziZG_trendTip",
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"error": "xoziZG_error",
|
|
139
|
-
"statCard": "xoziZG_statCard",
|
|
140
|
-
"heatLegend": "xoziZG_heatLegend",
|
|
141
|
-
"statLabel": "xoziZG_statLabel",
|
|
142
|
-
"barFill": "xoziZG_barFill",
|
|
120
|
+
"section": "xoziZG_section",
|
|
121
|
+
"tabs": "xoziZG_tabs",
|
|
143
122
|
"meta": "xoziZG_meta",
|
|
144
|
-
"modelChart": "xoziZG_modelChart",
|
|
145
|
-
"balanceRow": "xoziZG_balanceRow",
|
|
146
123
|
"bar": "xoziZG_bar",
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
124
|
+
"barFill": "xoziZG_barFill",
|
|
125
|
+
"modelRequests": "xoziZG_modelRequests",
|
|
126
|
+
"skeleton": "xoziZG_skeleton",
|
|
127
|
+
"modelName": "xoziZG_modelName",
|
|
128
|
+
"updated": "xoziZG_updated",
|
|
151
129
|
"manualSummary": "xoziZG_manualSummary",
|
|
152
|
-
"
|
|
130
|
+
"area": "xoziZG_area",
|
|
131
|
+
"statCard": "xoziZG_statCard",
|
|
132
|
+
"heatWeekday": "xoziZG_heatWeekday",
|
|
133
|
+
"creditRow": "xoziZG_creditRow",
|
|
134
|
+
"check": "xoziZG_check",
|
|
135
|
+
"accountNameRow": "xoziZG_accountNameRow",
|
|
136
|
+
"skeletonRow": "xoziZG_skeletonRow",
|
|
153
137
|
"balanceMeta": "xoziZG_balanceMeta",
|
|
154
|
-
"
|
|
155
|
-
"
|
|
138
|
+
"statSub": "xoziZG_statSub",
|
|
139
|
+
"count": "xoziZG_count",
|
|
140
|
+
"name": "xoziZG_name",
|
|
141
|
+
"accountRowActions": "xoziZG_accountRowActions",
|
|
142
|
+
"danger": "xoziZG_danger",
|
|
143
|
+
"statLabel": "xoziZG_statLabel",
|
|
144
|
+
"usageTipSep": "xoziZG_usageTipSep",
|
|
145
|
+
"modelShare": "xoziZG_modelShare",
|
|
146
|
+
"heatCell": "xoziZG_heatCell",
|
|
147
|
+
"heatLegend": "xoziZG_heatLegend",
|
|
148
|
+
"manual": "xoziZG_manual",
|
|
149
|
+
"avatar": "xoziZG_avatar",
|
|
150
|
+
"error": "xoziZG_error",
|
|
151
|
+
"body": "xoziZG_body",
|
|
152
|
+
"creditLink": "xoziZG_creditLink",
|
|
153
|
+
"accountName": "xoziZG_accountName",
|
|
154
|
+
"statValue": "xoziZG_statValue",
|
|
155
|
+
"expiryLabel": "xoziZG_expiryLabel",
|
|
156
|
+
"hint": "xoziZG_hint",
|
|
157
|
+
"usageTip": "xoziZG_usageTip",
|
|
156
158
|
"accountEntry": "xoziZG_accountEntry",
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"updated": "xoziZG_updated",
|
|
160
|
-
"modelName": "xoziZG_modelName"
|
|
159
|
+
"sectionLabel": "xoziZG_sectionLabel",
|
|
160
|
+
"creditRows": "xoziZG_creditRows"
|
|
161
161
|
};
|
|
162
162
|
//#endregion
|
|
163
163
|
//#region src/client/CodeArtsPluginCard.tsx
|
|
@@ -444,6 +444,62 @@ function hitPercentOf(totals) {
|
|
|
444
444
|
return Math.min(100, Math.round(cached / totals.promptTokens * 100));
|
|
445
445
|
}
|
|
446
446
|
/**
|
|
447
|
+
* 悬停明细卡的正文:标题(账号 / 模型 / 日期 / 钟点)+ 输入 / 输出 / 思考 / 缓存 /
|
|
448
|
+
* 请求 / 命中率。用量条和热力图格子共用这一份,改文案或加字段只需动这里。
|
|
449
|
+
*/
|
|
450
|
+
function UsageTipBody({ label, totals, t }) {
|
|
451
|
+
const cached = totals.cachedTokens;
|
|
452
|
+
const pct = hitPercentOf(totals);
|
|
453
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
454
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
455
|
+
className: CodeArtsPluginCard_module_css_default.usageTipName,
|
|
456
|
+
children: label
|
|
457
|
+
}),
|
|
458
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: CodeArtsPluginCard_module_css_default.usageTipSep }),
|
|
459
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
460
|
+
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
461
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipInput") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: exactCount(totals.promptTokens) })]
|
|
462
|
+
}),
|
|
463
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
464
|
+
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
465
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipOutput") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: exactCount(totals.completionTokens) })]
|
|
466
|
+
}),
|
|
467
|
+
(totals.reasoningTokens ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
468
|
+
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
469
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipReasoning") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: exactCount(totals.reasoningTokens ?? 0) })]
|
|
470
|
+
}),
|
|
471
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
472
|
+
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
473
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipCached") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: cached === void 0 ? t("usageTipNoCache") : exactCount(cached) })]
|
|
474
|
+
}),
|
|
475
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: CodeArtsPluginCard_module_css_default.usageTipSep }),
|
|
476
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
477
|
+
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
478
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipRequests") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageRequestCount", { n: formatCount(totals.requests) }) })]
|
|
479
|
+
}),
|
|
480
|
+
pct !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
481
|
+
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
482
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipHit") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [pct, "%"] })]
|
|
483
|
+
})
|
|
484
|
+
] });
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* 悬停卡贴着指针画:热力图格子只有 36px 宽,卡片锚在格子上会横穿整张卡片,
|
|
488
|
+
* 所以和 agent-acta 一样用 fixed + 指针坐标,靠近右下边界时翻到另一侧。
|
|
489
|
+
*/
|
|
490
|
+
function tipPointStyle(point) {
|
|
491
|
+
const width = 230;
|
|
492
|
+
const height = 190;
|
|
493
|
+
const viewWidth = typeof window === "undefined" ? 0 : window.innerWidth;
|
|
494
|
+
const viewHeight = typeof window === "undefined" ? 0 : window.innerHeight;
|
|
495
|
+
const left = viewWidth > 0 && point.x + 16 + width > viewWidth ? point.x - 16 - width : point.x + 16;
|
|
496
|
+
const top = viewHeight > 0 && point.y + 16 + height > viewHeight ? point.y - 16 - height : point.y + 16;
|
|
497
|
+
return {
|
|
498
|
+
left: Math.max(8, left),
|
|
499
|
+
top: Math.max(8, top)
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
447
503
|
* 横向条形列表:名称 / 条 / token / 占比 / 请求数。
|
|
448
504
|
*
|
|
449
505
|
* 条长按「占组内总量的比例」画(不是按最大值归一化),所以几条加起来就是全部。
|
|
@@ -463,8 +519,6 @@ function UsageBars({ rows, t }) {
|
|
|
463
519
|
const value = valueOf(row);
|
|
464
520
|
const share = sum > 0 ? value / sum * 100 : 0;
|
|
465
521
|
const totals = row.totals;
|
|
466
|
-
const cached = totals.cachedTokens;
|
|
467
|
-
const pct = hitPercentOf(totals);
|
|
468
522
|
const detail = [t("usageRequests", { n: formatCount(totals.requests) }), t("usageTokens", {
|
|
469
523
|
prompt: formatTokens$1(totals.promptTokens),
|
|
470
524
|
completion: formatTokens$1(totals.completionTokens)
|
|
@@ -498,41 +552,14 @@ function UsageBars({ rows, t }) {
|
|
|
498
552
|
className: CodeArtsPluginCard_module_css_default.modelRequests,
|
|
499
553
|
children: t("usageRequestCount", { n: formatCount(totals.requests) })
|
|
500
554
|
}),
|
|
501
|
-
hovered === row.id && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
555
|
+
hovered === row.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
502
556
|
className: CodeArtsPluginCard_module_css_default.usageTip,
|
|
503
557
|
role: "tooltip",
|
|
504
|
-
children:
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: CodeArtsPluginCard_module_css_default.usageTipSep }),
|
|
510
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
511
|
-
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
512
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipInput") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: exactCount(totals.promptTokens) })]
|
|
513
|
-
}),
|
|
514
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
515
|
-
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
516
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipOutput") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: exactCount(totals.completionTokens) })]
|
|
517
|
-
}),
|
|
518
|
-
(totals.reasoningTokens ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
519
|
-
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
520
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipReasoning") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: exactCount(totals.reasoningTokens ?? 0) })]
|
|
521
|
-
}),
|
|
522
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
523
|
-
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
524
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipCached") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: cached === void 0 ? t("usageTipNoCache") : exactCount(cached) })]
|
|
525
|
-
}),
|
|
526
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: CodeArtsPluginCard_module_css_default.usageTipSep }),
|
|
527
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
528
|
-
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
529
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipRequests") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageRequestCount", { n: formatCount(totals.requests) }) })]
|
|
530
|
-
}),
|
|
531
|
-
pct !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
532
|
-
className: CodeArtsPluginCard_module_css_default.usageTipRow,
|
|
533
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("usageTipHit") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [pct, "%"] })]
|
|
534
|
-
})
|
|
535
|
-
]
|
|
558
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageTipBody, {
|
|
559
|
+
label: row.label,
|
|
560
|
+
totals,
|
|
561
|
+
t
|
|
562
|
+
})
|
|
536
563
|
})
|
|
537
564
|
]
|
|
538
565
|
}, row.id);
|
|
@@ -562,6 +589,8 @@ function weekdayOf(date) {
|
|
|
562
589
|
*/
|
|
563
590
|
function UsageHeat({ days, t }) {
|
|
564
591
|
const [hovered, setHovered] = (0, react.useState)(null);
|
|
592
|
+
/** 指针离开格子就清掉,卡片跟着指针停在那一次进入的位置。 */
|
|
593
|
+
const [point, setPoint] = (0, react.useState)(null);
|
|
565
594
|
const last = days.at(-1);
|
|
566
595
|
const month = last?.date.slice(0, 7) ?? "";
|
|
567
596
|
const inMonth = days.filter((day) => day.date.startsWith(month));
|
|
@@ -614,9 +643,12 @@ function UsageHeat({ days, t }) {
|
|
|
614
643
|
className: CodeArtsPluginCard_module_css_default.heatCell,
|
|
615
644
|
"data-tone": tone,
|
|
616
645
|
"data-today": entry.date === last?.date ? "true" : void 0,
|
|
617
|
-
|
|
618
|
-
onMouseEnter: entry.totals === void 0 ? void 0 : () => {
|
|
646
|
+
onMouseEnter: entry.totals === void 0 ? void 0 : (event) => {
|
|
619
647
|
setHovered(entry.date);
|
|
648
|
+
setPoint({
|
|
649
|
+
x: event.clientX,
|
|
650
|
+
y: event.clientY
|
|
651
|
+
});
|
|
620
652
|
},
|
|
621
653
|
onMouseLeave: entry.totals === void 0 ? void 0 : () => {
|
|
622
654
|
setHovered(null);
|
|
@@ -626,9 +658,20 @@ function UsageHeat({ days, t }) {
|
|
|
626
658
|
})
|
|
627
659
|
]
|
|
628
660
|
}),
|
|
661
|
+
shown?.totals !== void 0 && point !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
662
|
+
className: CodeArtsPluginCard_module_css_default.usageTip,
|
|
663
|
+
"data-float": "true",
|
|
664
|
+
role: "tooltip",
|
|
665
|
+
style: tipPointStyle(point),
|
|
666
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageTipBody, {
|
|
667
|
+
label: shown.date,
|
|
668
|
+
totals: shown.totals,
|
|
669
|
+
t
|
|
670
|
+
})
|
|
671
|
+
}),
|
|
629
672
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
630
673
|
className: CodeArtsPluginCard_module_css_default.trendTip,
|
|
631
|
-
children:
|
|
674
|
+
children: t("usageTrendHint")
|
|
632
675
|
})
|
|
633
676
|
] });
|
|
634
677
|
}
|
|
@@ -639,6 +682,7 @@ function UsageHeat({ days, t }) {
|
|
|
639
682
|
*/
|
|
640
683
|
function UsageHours({ hours, t }) {
|
|
641
684
|
const [hovered, setHovered] = (0, react.useState)(null);
|
|
685
|
+
const [point, setPoint] = (0, react.useState)(null);
|
|
642
686
|
const max = hours.reduce((peak, hour) => Math.max(peak, hour.totals.totalTokens), 0);
|
|
643
687
|
const shown = hovered === null ? void 0 : hours.find((entry) => entry.hour === hovered);
|
|
644
688
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
@@ -647,9 +691,12 @@ function UsageHours({ hours, t }) {
|
|
|
647
691
|
children: hours.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
648
692
|
className: CodeArtsPluginCard_module_css_default.heatHourCell,
|
|
649
693
|
"data-tone": toneOf(entry.totals.totalTokens, max),
|
|
650
|
-
|
|
651
|
-
onMouseEnter: () => {
|
|
694
|
+
onMouseEnter: (event) => {
|
|
652
695
|
setHovered(entry.hour);
|
|
696
|
+
setPoint({
|
|
697
|
+
x: event.clientX,
|
|
698
|
+
y: event.clientY
|
|
699
|
+
});
|
|
653
700
|
},
|
|
654
701
|
onMouseLeave: () => {
|
|
655
702
|
setHovered(null);
|
|
@@ -663,22 +710,23 @@ function UsageHours({ hours, t }) {
|
|
|
663
710
|
children: entry.hour % 6 === 0 ? entry.hour : ""
|
|
664
711
|
}, entry.hour))
|
|
665
712
|
}),
|
|
713
|
+
shown !== void 0 && point !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
714
|
+
className: CodeArtsPluginCard_module_css_default.usageTip,
|
|
715
|
+
"data-float": "true",
|
|
716
|
+
role: "tooltip",
|
|
717
|
+
style: tipPointStyle(point),
|
|
718
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageTipBody, {
|
|
719
|
+
label: `${String(shown.hour).padStart(2, "0")}:00`,
|
|
720
|
+
totals: shown.totals,
|
|
721
|
+
t
|
|
722
|
+
})
|
|
723
|
+
}),
|
|
666
724
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
667
725
|
className: CodeArtsPluginCard_module_css_default.trendTip,
|
|
668
|
-
children:
|
|
726
|
+
children: t("usageTrendHint")
|
|
669
727
|
})
|
|
670
728
|
] });
|
|
671
729
|
}
|
|
672
|
-
/** 一格趋势的明细文案:输入 / 缓存 / 命中率 / 请求数(输出与思考在明细卡里看)。 */
|
|
673
|
-
function trendDetail(totals, t) {
|
|
674
|
-
const pct = hitPercentOf(totals);
|
|
675
|
-
return [
|
|
676
|
-
t("usageStatIn", { n: formatTokens$1(totals.promptTokens) }),
|
|
677
|
-
`${t("usageTipCached")} ${formatTokens$1(totals.cachedTokens ?? 0)}`,
|
|
678
|
-
`${t("usageTipHit")} ${pct === void 0 ? "—" : `${pct}%`}`,
|
|
679
|
-
t("usageRequestCount", { n: formatCount(totals.requests) })
|
|
680
|
-
].join(" · ");
|
|
681
|
-
}
|
|
682
730
|
/**
|
|
683
731
|
* 用量区块。
|
|
684
732
|
*
|
|
@@ -839,6 +887,8 @@ function CodeArtsPluginCard({ t }) {
|
|
|
839
887
|
const [msg, setMsg] = (0, react.useState)(null);
|
|
840
888
|
const [loginUrl, setLoginUrl] = (0, react.useState)(null);
|
|
841
889
|
const [loginPending, setLoginPending] = (0, react.useState)(false);
|
|
890
|
+
/** 正在进行的是哪个账号的「重新登录」(无则 null)。用来只让那一行的按钮变「登录中」。 */
|
|
891
|
+
const [reloginId, setReloginId] = (0, react.useState)(null);
|
|
842
892
|
const [selection, setSelection] = (0, react.useState)(null);
|
|
843
893
|
const [draft, setDraft] = (0, react.useState)([]);
|
|
844
894
|
const [savingModels, setSavingModels] = (0, react.useState)(false);
|
|
@@ -1163,16 +1213,29 @@ function CodeArtsPluginCard({ t }) {
|
|
|
1163
1213
|
setRefreshing(false);
|
|
1164
1214
|
}
|
|
1165
1215
|
}
|
|
1166
|
-
|
|
1216
|
+
/**
|
|
1217
|
+
* 开始一次浏览器登录。
|
|
1218
|
+
*
|
|
1219
|
+
* 不带 `targetId` 是「添加账号」;带 `targetId` 是「重新登录这个账号」——
|
|
1220
|
+
* 服务端会把新凭证写回原条目(保留顺序与备注),而不是又长出一条。
|
|
1221
|
+
*/
|
|
1222
|
+
async function startOAuthLogin(targetId) {
|
|
1167
1223
|
setBusy(true);
|
|
1168
1224
|
setMsg(null);
|
|
1169
1225
|
setLoginPending(true);
|
|
1226
|
+
if (targetId !== void 0) setReloginId(targetId);
|
|
1227
|
+
const finish = () => {
|
|
1228
|
+
setLoginUrl(null);
|
|
1229
|
+
setLoginPending(false);
|
|
1230
|
+
setReloginId(null);
|
|
1231
|
+
};
|
|
1170
1232
|
try {
|
|
1171
|
-
const
|
|
1233
|
+
const query = targetId === void 0 ? "" : `?account=${encodeURIComponent(targetId)}`;
|
|
1234
|
+
const res = await fetch(`/api/codearts/login${query}`, { method: "POST" });
|
|
1172
1235
|
const data = await res.json().catch(() => ({}));
|
|
1173
1236
|
if (!res.ok || typeof data.url !== "string") {
|
|
1174
1237
|
setMsg(data.error ?? `HTTP ${res.status}`);
|
|
1175
|
-
|
|
1238
|
+
finish();
|
|
1176
1239
|
return;
|
|
1177
1240
|
}
|
|
1178
1241
|
setLoginUrl(data.url);
|
|
@@ -1180,20 +1243,18 @@ function CodeArtsPluginCard({ t }) {
|
|
|
1180
1243
|
const poll = async () => {
|
|
1181
1244
|
const st = await (await fetch(`/api/codearts/login/status?url=${encodeURIComponent(data.url)}`, { headers: { Accept: "application/json" } })).json().catch(() => ({ status: "pending" }));
|
|
1182
1245
|
if (st.status === "done") {
|
|
1183
|
-
|
|
1184
|
-
|
|
1246
|
+
finish();
|
|
1247
|
+
if (st.conflict === true) setMsg(t("reloginOtherAccount"));
|
|
1185
1248
|
await refresh();
|
|
1186
1249
|
return;
|
|
1187
1250
|
}
|
|
1188
1251
|
if (st.status === "error") {
|
|
1189
|
-
|
|
1190
|
-
setLoginPending(false);
|
|
1252
|
+
finish();
|
|
1191
1253
|
setMsg(t("loginFailed"));
|
|
1192
1254
|
return;
|
|
1193
1255
|
}
|
|
1194
1256
|
if (st.status === "idle") {
|
|
1195
|
-
|
|
1196
|
-
setLoginPending(false);
|
|
1257
|
+
finish();
|
|
1197
1258
|
await refresh();
|
|
1198
1259
|
return;
|
|
1199
1260
|
}
|
|
@@ -1202,7 +1263,7 @@ function CodeArtsPluginCard({ t }) {
|
|
|
1202
1263
|
poll();
|
|
1203
1264
|
} catch (err) {
|
|
1204
1265
|
setMsg(err instanceof Error ? err.message : String(err));
|
|
1205
|
-
|
|
1266
|
+
finish();
|
|
1206
1267
|
} finally {
|
|
1207
1268
|
setBusy(false);
|
|
1208
1269
|
}
|
|
@@ -1452,16 +1513,22 @@ function CodeArtsPluginCard({ t }) {
|
|
|
1452
1513
|
children: accountLine
|
|
1453
1514
|
})]
|
|
1454
1515
|
}),
|
|
1455
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1516
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1456
1517
|
className: CodeArtsPluginCard_module_css_default.accountRowActions,
|
|
1457
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1518
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1519
|
+
variant: account.stale ? "primary" : "outline",
|
|
1520
|
+
size: "sm",
|
|
1521
|
+
disabled: busy || loginPending,
|
|
1522
|
+
onClick: () => void startOAuthLogin(account.id),
|
|
1523
|
+
children: reloginId === account.id && loginPending ? t("reloginPending") : t("accountRelogin")
|
|
1524
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1458
1525
|
variant: "outline",
|
|
1459
1526
|
size: "sm",
|
|
1460
1527
|
className: CodeArtsPluginCard_module_css_default.danger,
|
|
1461
|
-
disabled: busy,
|
|
1528
|
+
disabled: busy || loginPending,
|
|
1462
1529
|
onClick: () => void removeAccount(account.id),
|
|
1463
1530
|
children: t("accountRemove")
|
|
1464
|
-
})
|
|
1531
|
+
})]
|
|
1465
1532
|
})
|
|
1466
1533
|
]
|
|
1467
1534
|
}), credit !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreditBlock, {
|
|
@@ -2363,14 +2430,14 @@ if (typeof document !== "undefined" && document.querySelector("style[data-plugin
|
|
|
2363
2430
|
document.head.appendChild(tag);
|
|
2364
2431
|
}
|
|
2365
2432
|
var CodeArtsPanel_module_css_default = {
|
|
2366
|
-
"
|
|
2367
|
-
"
|
|
2368
|
-
"backCaret": "Z66cgG_backCaret",
|
|
2433
|
+
"head": "Z66cgG_head",
|
|
2434
|
+
"body": "Z66cgG_body",
|
|
2369
2435
|
"title": "Z66cgG_title",
|
|
2370
2436
|
"desc": "Z66cgG_desc",
|
|
2437
|
+
"back": "Z66cgG_back",
|
|
2438
|
+
"icon": "Z66cgG_icon",
|
|
2371
2439
|
"page": "Z66cgG_page",
|
|
2372
|
-
"
|
|
2373
|
-
"head": "Z66cgG_head"
|
|
2440
|
+
"backCaret": "Z66cgG_backCaret"
|
|
2374
2441
|
};
|
|
2375
2442
|
//#endregion
|
|
2376
2443
|
//#region src/client/CodeArtsPanel.tsx
|
|
@@ -2471,6 +2538,9 @@ const zh = {
|
|
|
2471
2538
|
expiredHint: "凭证已过期,请重新登录以继续使用;已勾选的模型设置会保留。",
|
|
2472
2539
|
accountsTitle: "账号",
|
|
2473
2540
|
accountRemove: "删除",
|
|
2541
|
+
accountRelogin: "重新登录",
|
|
2542
|
+
reloginPending: "登录中…",
|
|
2543
|
+
reloginOtherAccount: "你登录的是另一个账号,已作为新账号添加;原账号保持不变。",
|
|
2474
2544
|
addAccount: "添加账号",
|
|
2475
2545
|
pasteTokenAdd: "粘贴 Token 添加",
|
|
2476
2546
|
accountsRotateHint: "已存多个账号:请求会自动轮转,某个账号忙时改用下一个,不用干等。",
|
|
@@ -2621,6 +2691,9 @@ const en = {
|
|
|
2621
2691
|
expiredHint: "Your credential has expired. Sign in again to continue; your model selection is kept.",
|
|
2622
2692
|
accountsTitle: "Accounts",
|
|
2623
2693
|
accountRemove: "Remove",
|
|
2694
|
+
accountRelogin: "Sign in again",
|
|
2695
|
+
reloginPending: "Signing in…",
|
|
2696
|
+
reloginOtherAccount: "That was a different account, so it was added as a new one; the original stayed unchanged.",
|
|
2624
2697
|
addAccount: "Add account",
|
|
2625
2698
|
pasteTokenAdd: "Paste a token",
|
|
2626
2699
|
accountsRotateHint: "Multiple accounts stored: requests rotate automatically, so a busy account hands over to the next one instead of making you wait.",
|
package/lib/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as upstreamErrorMessage, B as modelUnavailableReason, C as isWelfareClaimedStatus, D as prepareChatBody, E as pickDailyWelfareCampaign, F as filterEnabledModels, G as codeartsAuthPath, H as CodeArtsCredentialStore, I as forgetModelUnavailable, K as
|
|
1
|
+
import { A as upstreamErrorMessage, B as modelUnavailableReason, C as isWelfareClaimedStatus, D as prepareChatBody, E as pickDailyWelfareCampaign, F as filterEnabledModels, G as codeartsAuthPath, H as CodeArtsCredentialStore, I as forgetModelUnavailable, K as credentialFromOAuth, L as isBenefitBlocked, M as FALLBACK_CODEARTS_MODELS, N as clearBenefitBlocked, O as rateLimitFrame, P as creditRatioLabel, R as isBenefitModel, S as isTpmLimit, T as modelUnavailableReasonText, U as MANUAL_ACCOUNT_ID, V as CodeArtsAccountStore, W as codeartsAccountsPath, _ as isIamTokenError, a as SNAP_HOST, b as isParamInvalidFrame, c as claimDailyWelfare, d as fetchCallerIdentity, f as fetchModels, g as isConcurrencyCap, h as firstFrameError, i as refreshCatalog, j as CodeArtsCatalog, k as signedGet, l as clearQueueStatus, m as fetchWelfareCampaigns, n as codeartsUsagePath, o as canonicalModel, p as fetchQueueStatus, q as startLogin, r as discoverModels, s as chatStream, t as CodeArtsUsageTracker, u as degradeTokenCeiling, v as isModelNotAccessible, w as maxTokensCeilingFor, x as isQueueableRate, y as isNotMultimodal, z as markModelUnavailable } from "./usage-CjPd0Gok.mjs";
|
|
2
2
|
import { i as lazyApi, r as createProvider } from "./models-CgKCibpk.mjs";
|
|
3
3
|
import z from "@deepseek-ai/schemastery";
|
|
4
4
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
@@ -1609,6 +1609,58 @@ async function probeIdentity(token) {
|
|
|
1609
1609
|
clearTimeout(timer);
|
|
1610
1610
|
}
|
|
1611
1611
|
}
|
|
1612
|
+
/**
|
|
1613
|
+
* 落一次 OAuth 登录的凭证。
|
|
1614
|
+
*
|
|
1615
|
+
* 不带 `targetId` 是「添加账号」:同一账号更新,别的账号新增。
|
|
1616
|
+
*
|
|
1617
|
+
* 带 `targetId` 是「重新登录这个账号」:凭证写回原条目(保留 id、展示顺序和
|
|
1618
|
+
* 备注),而不是又长出一条 —— 以前卡片上只有「删除」,用户遇到凭证过期只能
|
|
1619
|
+
* 先把账号删掉再加回来,顺序和备注都丢。
|
|
1620
|
+
*
|
|
1621
|
+
* 上游只在 `fetchCallerIdentity` 成功时才给稳定 `userId`,拿不到身份就判断不了
|
|
1622
|
+
* 「是不是同一个人」。此时按用户意图替换(他点的就是这个账号的重登),并沿用
|
|
1623
|
+
* 旧条目的身份字段;只有两边 `userId` 都非空且不同,才判为登了另一个账号,
|
|
1624
|
+
* 退回「新增」,原账号原样不动。
|
|
1625
|
+
*/
|
|
1626
|
+
async function settleLogin(deps, token, targetId) {
|
|
1627
|
+
const identity = await probeIdentity(token);
|
|
1628
|
+
const target = targetId === void 0 ? void 0 : await deps.store.credential(targetId);
|
|
1629
|
+
if (targetId !== void 0 && target !== void 0) {
|
|
1630
|
+
const known = typeof target.userId === "string" && target.userId !== "";
|
|
1631
|
+
if (!(identity !== null && known && target.userId !== identity.userId)) {
|
|
1632
|
+
const cred = credentialFromOAuth(token, target.label);
|
|
1633
|
+
cred.userId = cred.userId || target.userId;
|
|
1634
|
+
cred.userName = cred.userName || target.userName;
|
|
1635
|
+
cred.domainId = cred.domainId || target.domainId;
|
|
1636
|
+
const id = await deps.store.upsert(cred, targetId);
|
|
1637
|
+
deps.reviveAccount?.(id);
|
|
1638
|
+
if (identity !== null && identity.userId !== "") {
|
|
1639
|
+
if (identity.userId !== id) await deps.store.adoptIdentity(id, identity);
|
|
1640
|
+
deps.reviveAccount?.(identity.userId);
|
|
1641
|
+
return {
|
|
1642
|
+
id: identity.userId,
|
|
1643
|
+
replaced: true,
|
|
1644
|
+
conflict: false
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
return {
|
|
1648
|
+
id,
|
|
1649
|
+
replaced: true,
|
|
1650
|
+
conflict: false
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
const id = await deps.store.upsertFromOAuth(token, void 0, identity ?? void 0);
|
|
1655
|
+
if (identity !== null && id !== identity.userId) await deps.store.adoptIdentity(id, identity);
|
|
1656
|
+
deps.reviveAccount?.(id);
|
|
1657
|
+
if (identity !== null && identity.userId !== id) deps.reviveAccount?.(identity.userId);
|
|
1658
|
+
return {
|
|
1659
|
+
id: identity?.userId ?? id,
|
|
1660
|
+
replaced: false,
|
|
1661
|
+
conflict: target !== void 0
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1612
1664
|
/** 账号还能用吗(没被标 stale、也没过期)。 */
|
|
1613
1665
|
function accountUsable(summary) {
|
|
1614
1666
|
if (summary.stale) return false;
|
|
@@ -2169,6 +2221,8 @@ function registerCodeArtsStatusRoute(ctx, deps) {
|
|
|
2169
2221
|
const activeLogins = /* @__PURE__ */ new Map();
|
|
2170
2222
|
/** 已结束登录的终态,供迟到的轮询读取。被读一次即删。 */
|
|
2171
2223
|
const recentLogins = /* @__PURE__ */ new Map();
|
|
2224
|
+
/** 本次登录是「重新登录」时,授权 URL → 目标账号 id。终态落库后即删。 */
|
|
2225
|
+
const reloginTargets = /* @__PURE__ */ new Map();
|
|
2172
2226
|
const disposeStatus = ctx.webServer.register({
|
|
2173
2227
|
kind: "exact",
|
|
2174
2228
|
path: CODEARTS_STATUS_PATH,
|
|
@@ -2192,7 +2246,7 @@ function registerCodeArtsStatusRoute(ctx, deps) {
|
|
|
2192
2246
|
const disposeLoginStart = ctx.webServer.register({
|
|
2193
2247
|
kind: "exact",
|
|
2194
2248
|
path: CODEARTS_LOGIN_PATH,
|
|
2195
|
-
handler: loginStartHandler(deps, activeLogins, recentLogins)
|
|
2249
|
+
handler: loginStartHandler(deps, activeLogins, recentLogins, reloginTargets)
|
|
2196
2250
|
});
|
|
2197
2251
|
const disposeLoginStatus = ctx.webServer.register({
|
|
2198
2252
|
kind: "exact",
|
|
@@ -2250,6 +2304,7 @@ function registerCodeArtsStatusRoute(ctx, deps) {
|
|
|
2250
2304
|
disposeDebug();
|
|
2251
2305
|
for (const s of activeLogins.values()) s.close();
|
|
2252
2306
|
activeLogins.clear();
|
|
2307
|
+
reloginTargets.clear();
|
|
2253
2308
|
};
|
|
2254
2309
|
}, "dsh-codearts: Web status route");
|
|
2255
2310
|
}
|
|
@@ -2267,8 +2322,12 @@ function recordLoginOutcome(recent, url, outcome) {
|
|
|
2267
2322
|
}
|
|
2268
2323
|
recent.set(url, outcome);
|
|
2269
2324
|
}
|
|
2270
|
-
/**
|
|
2271
|
-
|
|
2325
|
+
/**
|
|
2326
|
+
* POST /api/codearts/login — 启动本地 OAuth 回调,返回授权 URL。
|
|
2327
|
+
*
|
|
2328
|
+
* `?account=<id>` 表示「重新登录这个账号」(见 settleLogin);省略就是添加账号。
|
|
2329
|
+
*/
|
|
2330
|
+
function loginStartHandler(deps, active, recent, targets) {
|
|
2272
2331
|
return async (req, res) => {
|
|
2273
2332
|
if (req.method !== "POST") {
|
|
2274
2333
|
json(res, 405, { error: "method not allowed" });
|
|
@@ -2278,28 +2337,33 @@ function loginStartHandler(deps, active, recent) {
|
|
|
2278
2337
|
json(res, 403, { error: "request-not-trusted" });
|
|
2279
2338
|
return;
|
|
2280
2339
|
}
|
|
2340
|
+
const targetId = (new URL(req.url ?? "", "http://localhost").searchParams.get("account") ?? "").trim();
|
|
2281
2341
|
try {
|
|
2282
2342
|
const session = await startLogin();
|
|
2283
2343
|
active.set(session.url, session);
|
|
2344
|
+
if (targetId !== "") targets.set(session.url, targetId);
|
|
2284
2345
|
session.promise.then(async (token) => {
|
|
2285
2346
|
active.delete(session.url);
|
|
2347
|
+
const reloginId = targets.get(session.url);
|
|
2348
|
+
targets.delete(session.url);
|
|
2286
2349
|
try {
|
|
2287
|
-
const
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
recordLoginOutcome(recent, session.url, "done");
|
|
2350
|
+
const result = await settleLogin(deps, token, reloginId);
|
|
2351
|
+
recordLoginOutcome(recent, session.url, {
|
|
2352
|
+
status: "done",
|
|
2353
|
+
...result
|
|
2354
|
+
});
|
|
2293
2355
|
} catch {
|
|
2294
|
-
recordLoginOutcome(recent, session.url, "error");
|
|
2356
|
+
recordLoginOutcome(recent, session.url, { status: "error" });
|
|
2295
2357
|
}
|
|
2296
2358
|
}, () => {
|
|
2297
2359
|
active.delete(session.url);
|
|
2298
|
-
|
|
2360
|
+
targets.delete(session.url);
|
|
2361
|
+
recordLoginOutcome(recent, session.url, { status: "error" });
|
|
2299
2362
|
});
|
|
2300
2363
|
const timer = setTimeout(() => {
|
|
2301
2364
|
session.close();
|
|
2302
|
-
|
|
2365
|
+
targets.delete(session.url);
|
|
2366
|
+
if (active.delete(session.url)) recordLoginOutcome(recent, session.url, { status: "error" });
|
|
2303
2367
|
}, 3e5);
|
|
2304
2368
|
session.promise.finally(() => clearTimeout(timer)).catch(() => {});
|
|
2305
2369
|
json(res, 200, {
|
|
@@ -2330,7 +2394,7 @@ function loginPollHandler(_deps, active, recent) {
|
|
|
2330
2394
|
const outcome = recent.get(key);
|
|
2331
2395
|
if (outcome !== void 0) {
|
|
2332
2396
|
recent.delete(key);
|
|
2333
|
-
json(res, 200, {
|
|
2397
|
+
json(res, 200, { ...outcome });
|
|
2334
2398
|
return;
|
|
2335
2399
|
}
|
|
2336
2400
|
json(res, 200, { status: "idle" });
|
|
@@ -3052,4 +3052,4 @@ function sumOf(store) {
|
|
|
3052
3052
|
return out;
|
|
3053
3053
|
}
|
|
3054
3054
|
//#endregion
|
|
3055
|
-
export { upstreamErrorMessage as A, modelUnavailableReason as B, isWelfareClaimedStatus as C, prepareChatBody as D, pickDailyWelfareCampaign as E, filterEnabledModels as F, codeartsAuthPath as G, CodeArtsCredentialStore as H, forgetModelUnavailable as I,
|
|
3055
|
+
export { upstreamErrorMessage as A, modelUnavailableReason as B, isWelfareClaimedStatus as C, prepareChatBody as D, pickDailyWelfareCampaign as E, filterEnabledModels as F, codeartsAuthPath as G, CodeArtsCredentialStore as H, forgetModelUnavailable as I, credentialFromOAuth as K, isBenefitBlocked as L, FALLBACK_CODEARTS_MODELS as M, clearBenefitBlocked as N, rateLimitFrame as O, creditRatioLabel as P, isBenefitModel as R, isTpmLimit as S, modelUnavailableReasonText as T, MANUAL_ACCOUNT_ID as U, CodeArtsAccountStore as V, codeartsAccountsPath as W, isIamTokenError as _, SNAP_HOST as a, isParamInvalidFrame as b, claimDailyWelfare as c, fetchCallerIdentity as d, fetchModels as f, isConcurrencyCap as g, firstFrameError as h, refreshCatalog as i, CodeArtsCatalog as j, signedGet as k, clearQueueStatus as l, fetchWelfareCampaigns as m, codeartsUsagePath as n, canonicalModel as o, fetchQueueStatus as p, startLogin as q, discoverModels as r, chatStream as s, CodeArtsUsageTracker as t, degradeTokenCeiling as u, isModelNotAccessible as v, maxTokensCeilingFor as w, isQueueableRate as x, isNotMultimodal as y, markModelUnavailable as z };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-codearts",
|
|
3
3
|
"displayName": "DSH CodeArts Connect",
|
|
4
4
|
"description": "把华为云 CodeArts 接入 DeepSeek Harness —— 内置 OAuth2 登录(PKCE + DPoP),登录后即可在 DSH 对话窗口使用 CodeArts 的模型。",
|
|
5
|
-
"version": "1.2.
|
|
5
|
+
"version": "1.2.10",
|
|
6
6
|
"packageManager": "pnpm@11.24.0",
|
|
7
7
|
"author": "elegant01",
|
|
8
8
|
"keywords": [
|