@ponydev/dsh-model-usage 1.0.4 → 1.0.6

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.6 — 2026-10-20
4
+
5
+ ### 新增
6
+ - **供应商覆盖对齐 DSH provider 目录(43 个)**:
7
+ - 新增适配器:OpenCode Go(`zen/go/v1/usage`,5h/周/月)、Moonshot/Kimi 平台余额、MiniMax Token Plan(5h/周)、Xiaomi MiMo 余额、GitHub Copilot 配额(Premium/Chat/补全)
8
+ - `deepseek` 路由也映射到 DeepSeek 余额适配器
9
+ - 新增「每月限额」窗口标签
10
+ - `docs/providers.md`:完整覆盖矩阵(真实额度 / 订阅待确认 / 无公开接口 / customQuota 接入方式)
11
+
12
+ ### 变更
13
+ - 无公开额度接口的 provider(Anthropic/OpenAI/Google/Bedrock/Azure/Groq 等)保持隐藏,不产生错误卡片
14
+
15
+ ## 1.0.5 — 2026-10-20
16
+
17
+ ### 新增
18
+ - **GLM 每月 MCP 工具调用限额**:解析 `TIME_LIMIT`(unit=5,月)窗口,展示「每月 MCP 工具 · 剩余 N/M 次」与重置倒计时(额度接口 `usageDetails`: search-prime / web-reader / zread)
19
+ - 窗口行支持「次数型」额度(无百分比时按剩余次数展示,进度条仍按剩余比例)
20
+ - **官方 Logo**:GLM / Z.ai(官方 SVG)、Kimi / Moonshot、OpenRouter、MiniMax、xAI;路由映射扩展(zai/glm/bigmodel/zhipu/chatglm、kimi/moonshot、openrouter、minimax、xai),无官方资源时回退字母圆标
21
+
22
+ ### 变更
23
+ - 侧边栏迷你卡片最多展示 3 个窗口(5 小时 / 每周 / 每月 MCP)
24
+
3
25
  ## 1.0.4 — 2026-10-20
4
26
 
5
27
  ### 修复
package/README.md CHANGED
@@ -37,15 +37,20 @@ dsh plugin --profile web add @ponydev/dsh-model-usage
37
37
  dsh plugin --profile web add link:/path/to/dsh-model-usage
38
38
  ```
39
39
 
40
- ## 供应商支持
40
+ ## 供应商支持(完整矩阵见 [docs/providers.md](docs/providers.md))
41
41
 
42
42
  | 供应商 | 数据接口 | 凭据引用 |
43
43
  |---|---|---|
44
44
  | DeepSeek API | `api.deepseek.com/user/balance` | `DEEPSEEK_API_KEY` |
45
45
  | DeepSeek 账号 | Host `deepseekAccount` 服务(登录态) | — |
46
- | GLM Coding Plan(国内 / 国际) | `open.bigmodel.cn` / `api.z.ai` 额度接口 | `ZAI_CODING_CN_API_KEY` / `ZAI_API_KEY` |
46
+ | GLM Coding Plan(国内 / 国际) | `open.bigmodel.cn` / `api.z.ai` 额度接口(5 小时 / 每周 / **每月 MCP 工具次数**) | `ZAI_CODING_CN_API_KEY` / `ZAI_API_KEY` |
47
47
  | OpenRouter | `openrouter.ai/api/v1/credits`(兜底 `/api/v1/key`) | `OPENROUTER_API_KEY` |
48
48
  | Kimi Coding Plan | `api.kimi.com/coding/v1/usages` | `KIMI_CODING_API_KEY` / `KIMI_API_KEY` / `MOONSHOT_API_KEY` |
49
+ | Moonshot / Kimi 平台 | `api.moonshot.{ai,cn}/v1/users/me/balance` | `MOONSHOT_API_KEY` / `MOONSHOT_CN_API_KEY` |
50
+ | MiniMax Token Plan | `api.minimax.io` / `api.minimaxi.com` `/v1/token_plan/remains` | `MINIMAX_API_KEY` / `MINIMAX_CN_API_KEY` |
51
+ | OpenCode Go | `opencode.ai/zen/go/v1/usage` | `OPENCODE_API_KEY` |
52
+ | Xiaomi MiMo | `platform.xiaomimimo.com/api/v1/balance` | `XIAOMI_API_KEY` |
53
+ | GitHub Copilot | `api.github.com/copilot_internal/user` | `GITHUB_TOKEN` |
49
54
  | 其他任意供应商 | `customQuota` 配置(URL + JSON 路径映射) | 自定义 `keyRef` |
50
55
 
51
56
  `customQuota` 示例(余额式):
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><image width="64" height="64" href="data:image/png;base64,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"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><image width="64" height="64" href="data:image/png;base64,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"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><image width="64" height="64" href="data:image/png;base64,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jz3yCOf9qyAajWr02DE6+PDDdfkVV2jht4uskzxly5ZCPfzPR9SmfXuNvOoqdjUDVdC9WzfrBM9iAIixW266SQfsv791RtIY+/Y4HXTYYTrznHO19LvvrHM8rby8XP9+9lm1P+gg3Xr77SosLLJOAjyvW7du/EC2C+wBiKFDDj5E0z6domAwaJ3ieXPmztEf/+9P+s/UqdYpSatJ48a647bbdO7ZZysQYJYHdqXDwQdrydKl1hmew78aMeI4jh5+8H4O/nuwadNmXXH11erWqzcH/xpas3atLh0xQj2O6KP/fvVf6xzAszq072Cd4EkMADFy+tCh6taVc0278/4HH+iwrl309DPPKBKJWOekjK++/ko9+xypkVddpaIiTgsAO2rfvp11gicxAMRAdna27r7zTusMz1qfn6/TzzxLg4YO1Q8//midk5Ki0aj+/eyzOrxbN99fPQHsqFNHVgB2hgEgBv74h6u5e9suTJg4UYd37apx77xtneILy5Yv14ATT9RNt9yScndLBKqr7YFtrRM8iU2ANdR0v/0057//VXZ2tnWKp5SWlurPt9yix598Uq7LXzELBx90sF587jm1ad3KOgUwVVZWprp77aVoNGqd4imsANTQ7bfeysF/BytXrVLffv312BNPcPA39PU3X6tnn96svsD3MjIytM/ee1tneA4DQA20btVKZ5x2mnWGp0z9bKp69WFXulcUFhbpjLPO1nV/+hP3Q4evNWuWZ53gOQwANXDbLTfzsJbtPPbEEzr2hBO1dt066xRsx3Vd/fOxxzTw1FO1ZUuhdQ5gIq9ZU+sEz2EAqKZ27dpp8MBB1hme4Lqu7rrnHl17/fVc3udhEz/+WH2OOVorV62yTgESrmHDhtYJnsMAUE133HoLd1+TVFxcrKHDhunue+6xTkElLFiwQEcefbTmzJ1jnQIkVL169awTPIcjWDUccvAhOumEE60zzG3dulWDTztN49991zoFVfDjTz/pmAEDNHPWTOsUIGEaNmhgneA5DADVcNMNf/L9wyU2bdqsASeepE+mTLFOQTVs3rxFJ5wykJsGwTfq12cFYEcMAFXUulUrnXD88dYZpjZs3Kj+xx+vz7/43DoFNVBUVKRThgzRxI8/tk4B4i4rM8s6wXMYAKroqiuu8PW5/y1bCnXSwEH6Zs431imIgZKSEg0dNowHMyHlpaen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"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><image width="64" height="64" href="data:image/png;base64,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"/></svg>
@@ -0,0 +1,219 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 25.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{opacity:0.3;fill:#E2E4E7;}
7
+ .st1{opacity:0.8;fill:#E2E4E7;stroke:#FFFFFF;stroke-width:5;stroke-miterlimit:10;}
8
+ .st2{fill:url(#SVGID_1_);}
9
+ .st3{fill:none;stroke:#E0E4E9;stroke-width:0.25;stroke-miterlimit:10;}
10
+ .st4{fill:none;}
11
+ .st5{fill:#9DA1A5;}
12
+ .st6{fill-rule:evenodd;clip-rule:evenodd;fill:none;}
13
+ .st7{fill-rule:evenodd;clip-rule:evenodd;fill:#DFE2E7;}
14
+ .st8{fill-rule:evenodd;clip-rule:evenodd;fill:#CDD4DA;}
15
+ .st9{fill-rule:evenodd;clip-rule:evenodd;fill:#B3BCC7;}
16
+ .st10{fill-rule:evenodd;clip-rule:evenodd;fill:#9DAAB7;}
17
+ .st11{fill-rule:evenodd;clip-rule:evenodd;fill:#8698A8;}
18
+ .st12{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_2_);}
19
+ .st13{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_3_);}
20
+ .st14{fill:#1F63EC;}
21
+ .st15{fill:#2D2D2D;}
22
+ .st16{fill:none;stroke:#E0E4E9;stroke-width:0.5;stroke-miterlimit:10;}
23
+ .st17{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_4_);}
24
+ .st18{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_5_);}
25
+ .st19{fill:none;stroke:#677380;stroke-width:0.5;stroke-miterlimit:10;}
26
+ .st20{fill:none;stroke:url(#SVGID_6_);stroke-width:2;stroke-miterlimit:10;}
27
+ .st21{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_7_);}
28
+ .st22{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_8_);}
29
+ .st23{fill:#FFFFFF;}
30
+ .st24{fill-rule:evenodd;clip-rule:evenodd;fill:#2D2D2D;}
31
+ .st25{clip-path:url(#SVGID_10_);}
32
+ .st26{clip-path:url(#SVGID_12_);}
33
+ .st27{fill:url(#SVGID_13_);}
34
+ .st28{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_14_);}
35
+ .st29{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_15_);}
36
+ .st30{clip-path:url(#SVGID_17_);}
37
+ .st31{clip-path:url(#SVGID_19_);}
38
+ .st32{fill:url(#SVGID_20_);}
39
+ .st33{fill:none;stroke:url(#SVGID_21_);stroke-width:2;stroke-miterlimit:10;}
40
+ .st34{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_22_);}
41
+ .st35{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_23_);}
42
+ .st36{clip-path:url(#SVGID_25_);}
43
+ .st37{clip-path:url(#SVGID_27_);}
44
+ .st38{fill:url(#SVGID_28_);}
45
+ .st39{clip-path:url(#SVGID_30_);}
46
+ .st40{clip-path:url(#SVGID_32_);}
47
+ .st41{fill:url(#SVGID_33_);}
48
+ .st42{fill-rule:evenodd;clip-rule:evenodd;fill:#126EF6;}
49
+ .st43{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
50
+ .st44{clip-path:url(#SVGID_35_);}
51
+ .st45{clip-path:url(#SVGID_37_);}
52
+ .st46{fill:url(#SVGID_38_);}
53
+ .st47{fill-rule:evenodd;clip-rule:evenodd;fill:#9DA1A5;}
54
+ .st48{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_39_);}
55
+ .st49{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_40_);}
56
+ .st50{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_41_);}
57
+ .st51{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_42_);}
58
+ .st52{fill:none;stroke:url(#SVGID_43_);stroke-width:2;stroke-miterlimit:10;}
59
+ .st53{fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:#E0E4E9;stroke-width:0.5;stroke-miterlimit:10;}
60
+ .st54{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_44_);}
61
+ .st55{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_45_);}
62
+ .st56{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_46_);}
63
+ .st57{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_47_);}
64
+ .st58{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_48_);}
65
+ .st59{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_49_);}
66
+ .st60{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_50_);}
67
+ .st61{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_51_);}
68
+ .st62{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_52_);}
69
+ .st63{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_53_);}
70
+ .st64{clip-path:url(#SVGID_55_);}
71
+ .st65{clip-path:url(#SVGID_57_);}
72
+ .st66{fill:url(#SVGID_58_);}
73
+ .st67{clip-path:url(#SVGID_60_);}
74
+ .st68{clip-path:url(#SVGID_62_);}
75
+ .st69{fill:url(#SVGID_63_);}
76
+ .st70{fill:none;stroke:url(#SVGID_64_);stroke-width:2;stroke-miterlimit:10;}
77
+ .st71{clip-path:url(#SVGID_66_);}
78
+ .st72{clip-path:url(#SVGID_68_);}
79
+ .st73{fill:url(#SVGID_69_);}
80
+ .st74{clip-path:url(#SVGID_71_);}
81
+ .st75{clip-path:url(#SVGID_73_);}
82
+ .st76{fill:url(#SVGID_74_);}
83
+ .st77{clip-path:url(#SVGID_76_);}
84
+ .st78{clip-path:url(#SVGID_78_);}
85
+ .st79{fill:url(#SVGID_79_);}
86
+ .st80{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_80_);}
87
+ .st81{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_81_);}
88
+ .st82{clip-path:url(#SVGID_83_);}
89
+ .st83{clip-path:url(#SVGID_85_);}
90
+ .st84{fill:url(#SVGID_86_);}
91
+ .st85{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_87_);}
92
+ .st86{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_88_);}
93
+ .st87{clip-path:url(#SVGID_90_);}
94
+ .st88{clip-path:url(#SVGID_92_);}
95
+ .st89{fill:url(#SVGID_93_);}
96
+ .st90{fill:none;stroke:url(#SVGID_94_);stroke-width:2;stroke-miterlimit:10;}
97
+ .st91{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_95_);}
98
+ .st92{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_96_);}
99
+ .st93{clip-path:url(#SVGID_98_);}
100
+ .st94{clip-path:url(#SVGID_100_);}
101
+ .st95{fill:url(#SVGID_101_);}
102
+ .st96{clip-path:url(#SVGID_103_);}
103
+ .st97{clip-path:url(#SVGID_105_);}
104
+ .st98{fill:url(#SVGID_106_);}
105
+ .st99{clip-path:url(#SVGID_108_);}
106
+ .st100{clip-path:url(#SVGID_110_);}
107
+ .st101{fill:url(#SVGID_111_);}
108
+ .st102{fill:#FFFFFF;stroke:#B3BCC7;stroke-width:0.275;stroke-miterlimit:10;}
109
+ .st103{clip-path:url(#SVGID_113_);}
110
+ .st104{fill:#FDD138;}
111
+ .st105{fill:#FCA62F;}
112
+ .st106{fill:#FB7927;}
113
+ .st107{fill:#F44B22;}
114
+ .st108{fill:#D81915;}
115
+ .st109{fill:#2D2D2D;stroke:#FFFFFF;stroke-width:0.3354;stroke-miterlimit:10;}
116
+ .st110{fill:none;stroke:#65727F;stroke-width:2;stroke-miterlimit:10;}
117
+ .st111{fill:none;stroke:#65727F;stroke-width:0.75;stroke-miterlimit:10;}
118
+ .st112{fill:url(#SVGID_114_);}
119
+ .st113{fill:#D06C50;}
120
+ .st114{fill:#2D2D2D;stroke:#B3BCC7;stroke-width:0.275;stroke-miterlimit:10;}
121
+ .st115{opacity:0.2;}
122
+ .st116{fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;}
123
+ .st117{fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;stroke-dasharray:1.0212,1.0212;}
124
+ .st118{fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;stroke-dasharray:1.0205,1.0205;}
125
+ .st119{opacity:0.2;fill:none;}
126
+ .st120{fill:none;stroke:#677380;stroke-width:0.3689;stroke-miterlimit:10;}
127
+ .st121{fill:none;stroke:#677380;stroke-width:0.3689;stroke-miterlimit:10;stroke-dasharray:1.0509,1.0509;}
128
+ .st122{opacity:0.3;fill:#1F63EC;}
129
+ .st123{fill:#2D2D2D;stroke:#FFFFFF;stroke-width:0.3162;stroke-miterlimit:10;}
130
+ .st124{fill:#FFFFFF;stroke:#B3BCC7;stroke-width:0.3162;stroke-miterlimit:10;}
131
+ .st125{clip-path:url(#SVGID_118_);}
132
+ .st126{fill:url(#SVGID_119_);}
133
+ .st127{fill:none;stroke:#DFE2E7;stroke-width:0.75;stroke-miterlimit:10;}
134
+ .st128{fill:#9DA1A5;stroke:#FFFFFF;stroke-miterlimit:10;}
135
+ .st129{fill:url(#SVGID_120_);}
136
+ .st130{fill:none;stroke:#677380;stroke-width:0.75;stroke-miterlimit:10;}
137
+ .st131{opacity:0.4;}
138
+ .st132{clip-path:url(#SVGID_122_);}
139
+ .st133{clip-path:url(#SVGID_124_);}
140
+ .st134{fill:url(#SVGID_125_);}
141
+ .st135{fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;}
142
+ .st136{fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;stroke-dasharray:0.9951,0.9951;}
143
+ .st137{fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;stroke-dasharray:1.004,1.004;}
144
+ .st138{fill:none;stroke:url(#SVGID_126_);stroke-width:1.5;stroke-miterlimit:10;}
145
+ .st139{fill:url(#SVGID_127_);}
146
+ .st140{fill:none;stroke:#DDE0E4;stroke-width:0.35;stroke-miterlimit:10;}
147
+ .st141{fill:#2D2D2D;stroke:#A9B3BE;stroke-width:0.275;stroke-miterlimit:10;}
148
+ .st142{fill-rule:evenodd;clip-rule:evenodd;fill:#126EF4;}
149
+ .st143{fill:#FFFFFF;stroke:#B1BAC4;stroke-width:0.275;stroke-miterlimit:10;}
150
+ .st144{fill:#CE6C50;}
151
+ .st145{fill:#5B5B5B;}
152
+ .st146{fill:#8392A3;}
153
+ .st147{fill:none;stroke:url(#SVGID_128_);stroke-width:1.5;stroke-miterlimit:10;}
154
+ .st148{fill:url(#SVGID_129_);}
155
+ .st149{fill:none;stroke:#B5BDC4;stroke-width:0.7;stroke-miterlimit:10;}
156
+ .st150{opacity:0.6;fill:none;stroke:#78838E;stroke-width:0.35;stroke-miterlimit:10;}
157
+ .st151{opacity:0.2;fill:none;stroke:#8392A3;stroke-width:0.35;stroke-miterlimit:10;stroke-dasharray:1,1;}
158
+ .st152{fill:none;stroke:#DDE0E4;stroke-width:0.75;stroke-miterlimit:10;}
159
+ .st153{fill:none;stroke:#8392A3;stroke-width:0.5;stroke-miterlimit:10;}
160
+ .st154{opacity:0.2;fill:none;stroke:#677380;stroke-width:0.3564;stroke-miterlimit:10;stroke-dasharray:1.0182,1.0182;}
161
+ .st155{fill:none;stroke:#DDE0E4;stroke-width:0.765;stroke-miterlimit:10;}
162
+ .st156{fill:url(#SVGID_130_);}
163
+ .st157{fill:url(#SVGID_131_);}
164
+ .st158{fill:#B1BAC4;}
165
+ .st159{fill:#CBD1D8;}
166
+ .st160{fill:#0B1B2B;}
167
+ .st161{fill:#91D119;}
168
+ .st162{opacity:0.7;}
169
+ .st163{fill:#FFFFFF;stroke:#000000;stroke-width:0.4418;stroke-miterlimit:10;}
170
+ .st164{fill:none;stroke:#939CAA;stroke-width:0.2209;stroke-miterlimit:10;}
171
+ .st165{fill:none;stroke:#FFFFFF;stroke-width:3.0924;stroke-miterlimit:10;}
172
+ .st166{fill:url(#SVGID_132_);}
173
+ .st167{fill:none;stroke:url(#SVGID_133_);stroke-width:1.714;stroke-miterlimit:10;}
174
+ .st168{fill:url(#SVGID_134_);}
175
+ .st169{fill:url(#SVGID_135_);}
176
+ .st170{fill:url(#SVGID_136_);}
177
+ .st171{fill:url(#SVGID_137_);}
178
+ .st172{fill:url(#SVGID_138_);}
179
+ .st173{fill:url(#SVGID_139_);}
180
+ .st174{fill:url(#SVGID_140_);}
181
+ .st175{fill:url(#SVGID_141_);}
182
+ .st176{fill:url(#SVGID_142_);}
183
+ .st177{fill:url(#SVGID_143_);}
184
+ .st178{fill:url(#SVGID_144_);}
185
+ .st179{fill:none;stroke:#1F63EC;stroke-width:4;stroke-miterlimit:10;}
186
+ .st180{fill:none;stroke:#0B1B2B;stroke-width:4;stroke-miterlimit:10;}
187
+ .st181{fill:none;stroke:#677380;stroke-width:0.3989;stroke-miterlimit:10;}
188
+ .st182{fill:none;stroke:#677380;stroke-width:0.3989;stroke-miterlimit:10;stroke-dasharray:1.14,1.14;}
189
+ .st183{fill:#257AF1;}
190
+ .st184{opacity:0.3;fill:#FFFFFF;}
191
+ .st185{fill:none;stroke:#98A5B2;stroke-width:4;stroke-miterlimit:10;}
192
+ .st186{fill:none;stroke:#65727F;stroke-width:0.3989;stroke-miterlimit:10;}
193
+ .st187{fill:none;stroke:#65727F;stroke-width:0.3989;stroke-miterlimit:10;stroke-dasharray:1.14,1.14;}
194
+ .st188{fill:none;stroke:#DDDFE4;stroke-width:0.75;stroke-miterlimit:10;}
195
+ .st189{fill:#9A9EA2;}
196
+ .st190{fill-rule:evenodd;clip-rule:evenodd;fill:#3267AC;}
197
+ .st191{fill:#FFFFFF;stroke:#AFB8C3;stroke-width:0.275;stroke-miterlimit:10;}
198
+ .st192{fill:#C5694E;}
199
+ .st193{fill:#8192A2;}
200
+ .st194{fill:#2D2D2D;stroke:#FFFFFF;stroke-width:0.6317;stroke-miterlimit:10;}
201
+ </style>
202
+ <g id="图层_2">
203
+ </g>
204
+ <g id="图层_1">
205
+ <path class="st194" d="M24.51,28.51H5.49c-2.21,0-4-1.79-4-4V5.49c0-2.21,1.79-4,4-4h19.03c2.21,0,4,1.79,4,4v19.03
206
+ C28.51,26.72,26.72,28.51,24.51,28.51z"/>
207
+ <g>
208
+ <g>
209
+ <g>
210
+ <g>
211
+ <path class="st23" d="M15.47,7.1l-1.3,1.85c-0.2,0.29-0.54,0.47-0.9,0.47h-7.1V7.09C6.16,7.1,15.47,7.1,15.47,7.1z"/>
212
+ <polygon class="st23" points="24.3,7.1 13.14,22.91 5.7,22.91 16.86,7.1 "/>
213
+ <path class="st23" d="M14.53,22.91l1.31-1.86c0.2-0.29,0.54-0.47,0.9-0.47h7.09v2.33H14.53z"/>
214
+ </g>
215
+ </g>
216
+ </g>
217
+ </g>
218
+ </g>
219
+ </svg>
@@ -0,0 +1,67 @@
1
+ # 供应商覆盖矩阵
2
+
3
+ DSH(`@deepseek-ai/dsh` 0.2.0-rc.2)的 pi-ai provider 目录共 43 个 provider。本插件按「**有真实额度接口才显示,没有就隐藏**」的原则覆盖。
4
+
5
+ 图例:
6
+ - ✅ **真实额度**:调用服务商官方接口,显示余额或窗口剩余
7
+ - 🟡 **订阅/接口待确认**:接口存在但需要特定 Key 类型,失败时优雅隐藏
8
+ - ⬜ **无公开接口**:服务商未提供可用 API Key 查询的余额接口 → 不显示卡片(不会报错)
9
+ - 🔧 **customQuota**:可用配置接入(URL + JSON 路径映射)
10
+
11
+ ## 已支持(真实额度)
12
+
13
+ | Provider id | 数据接口 | 凭据引用 | 展示 |
14
+ |---|---|---|---|
15
+ | `deepseek-official` / `deepseek` | `api.deepseek.com/user/balance` | `DEEPSEEK_API_KEY` | 余额(总/充值/赠金) |
16
+ | `deepseek-account` | DSH `deepseekAccount` 服务 | 登录态 | 账号钱包 |
17
+ | `zai` / `zai-coding-cn` | `open.bigmodel.cn` / `api.z.ai` 额度接口 | `ZAI_CODING_CN_API_KEY` / `ZAI_API_KEY` | 5 小时 / 每周 / **每月 MCP 工具次数** |
18
+ | `openrouter` | `openrouter.ai/api/v1/credits`(兜底 `/api/v1/key`) | `OPENROUTER_API_KEY` | credits 余额 |
19
+ | `kimi-coding` / `kimi-coding-cn` | `api.kimi.com/coding/v1/usages` | `KIMI_CODING_API_KEY` / `KIMI_API_KEY` | 周 + 滚动窗口 |
20
+ | `moonshotai` / `moonshotai-cn` | `api.moonshot.{ai,cn}/v1/users/me/balance` | `MOONSHOT_API_KEY` / `MOONSHOT_CN_API_KEY` | 平台余额 |
21
+ | `minimax` / `minimax-cn` | `api.minimax.io` / `api.minimaxi.com` `/v1/token_plan/remains` | `MINIMAX_API_KEY` / `MINIMAX_CN_API_KEY` | 5h + 周(订阅 Key) |
22
+ | `opencode-go` | `opencode.ai/zen/go/v1/usage` | `OPENCODE_API_KEY` | 5h / 周 / 月 |
23
+ | `xiaomi*`(含 token-plan) | `platform.xiaomimimo.com/api/v1/balance` | `XIAOMI_API_KEY` | 余额 |
24
+ | `github-copilot` | `api.github.com/copilot_internal/user` | `GITHUB_TOKEN` / `GH_TOKEN` | Premium / Chat / 补全 配额 |
25
+
26
+ ## 无公开余额接口(隐藏,不报错)
27
+
28
+ | Provider id | 说明 |
29
+ |---|---|
30
+ | `anthropic` | 无用户 Key 余额接口(组织用量需 Admin Key + 控制台) |
31
+ | `openai`、`openai-codex` | 用量接口需组织 Admin Key / ChatGPT OAuth,DSH 的普通 Key 不可用 |
32
+ | `google`、`google-vertex` | 需 GCP 项目计费 API,非 Key 级 |
33
+ | `amazon-bedrock` | 需 AWS IAM/CloudWatch 计费 |
34
+ | `azure-openai-responses` | 需 Azure 订阅计费 API |
35
+ | `groq`、`cerebras`、`fireworks`、`together`、`baseten`、`nvidia`、`huggingface`、`mistral`、`meta`、`cloudflare-ai-gateway`、`cloudflare-workers-ai`、`vercel-ai-gateway`、`radius`、`ant-ling`、`opencode` | 无 Key 级余额/配额查询接口 |
36
+ | `qwen-token-plan` / `-cn` / `-individual` | 阿里云百炼暂未提供 Token Plan 用量 OpenAPI(控制台可见) |
37
+
38
+ > 这些 provider 的卡片**直接隐藏**,不影响插件运行;需要展示时用 `customQuota` 配置接入,或提 issue 附接口文档。
39
+
40
+ ## 用 customQuota 接入任意供应商
41
+
42
+ ```yaml
43
+ config:
44
+ customQuota:
45
+ my-provider:
46
+ url: https://api.example.com/quota
47
+ auth: bearer # bearer | raw | x-api-key | none
48
+ keyRef: MY_PROVIDER_API_KEY
49
+ balance: { path: data.balance, currency: CNY }
50
+ # 或窗口式
51
+ windows:
52
+ - key: rolling
53
+ label: 5h
54
+ usedPath: data.used
55
+ limitPath: data.limit
56
+ resetAtPath: data.resetAt
57
+ resetAtUnit: ms # ms | s | iso
58
+ ```
59
+
60
+ ## 新增适配器
61
+
62
+ 1. 在 `lib/adapters.js` 新增 `{ id, refs, read(env) }`
63
+ 2. `adapterFor()` 加路由匹配(注意顺序:更具体的路由在前,如 `kimi-coding` 先于 `kimi`)
64
+ 3. 返回 `{ status:'ok', balance }` 或 `{ status:'ok', windows:[{key,label,usedPct,resetAt,countBased?,remaining?,limit?}] }`
65
+ 4. 失败一律:`needs-credential` / `unauthorized` / `unsupported`(不抛未捕获异常)
66
+ 5. 只允许写死白名单域名,错误信息必须脱敏
67
+ 6. 更新本文档矩阵 + `package.json` version(patch/minor)+ `CHANGELOG.md`
Binary file
Binary file
Binary file
Binary file
package/lib/adapters.js CHANGED
@@ -251,6 +251,28 @@ const glmCoding = {
251
251
  resetAt: Number(it.nextResetTime) || null,
252
252
  })
253
253
  }
254
+ // 每月 MCP/工具调用次数限额:type=TIME_LIMIT, unit=5(月),usage=总量,remaining=剩余次数
255
+ const timeLimit = limits.find((it) => it && String(it.type) === 'TIME_LIMIT' && Number(it.unit) === 5)
256
+ if (timeLimit) {
257
+ const limit = Number(timeLimit.usage)
258
+ const remaining = Number(timeLimit.remaining)
259
+ const pctRaw = Number(timeLimit.percentage)
260
+ const usedPct = Number.isFinite(pctRaw) && timeLimit.percentage != null
261
+ ? pctRaw
262
+ : (Number.isFinite(limit) && limit > 0 && Number.isFinite(remaining) ? (1 - remaining / limit) * 100 : 0)
263
+ windows.push({
264
+ key: 'mcp',
265
+ label: 'MCP',
266
+ usedPct: clampPct(usedPct),
267
+ resetAt: Number(timeLimit.nextResetTime) || null,
268
+ countBased: true,
269
+ limit: Number.isFinite(limit) ? limit : null,
270
+ remaining: Number.isFinite(remaining) ? remaining : null,
271
+ details: Array.isArray(timeLimit.usageDetails)
272
+ ? timeLimit.usageDetails.map((it) => ({ code: String(it && it.modelCode || ''), usage: Number(it && it.usage) || 0 }))
273
+ : null,
274
+ })
275
+ }
254
276
  if (!windows.length) {
255
277
  const types = limits.map((l) => (l && l.type) + '/' + (l && l.unit)).join(', ')
256
278
  return {
@@ -397,6 +419,201 @@ const openrouter = {
397
419
  },
398
420
  }
399
421
 
422
+ // OpenCode Go(订阅):GET https://opencode.ai/zen/go/v1/usage Bearer
423
+ // 响应 { usage: { rolling: { percent, resetsAt }, weekly: {...}, monthly: {...} } }
424
+ const opencodeGo = {
425
+ id: 'opencode-go',
426
+ refs: (cfg, route) => [cfg.credentials[route] || 'OPENCODE_API_KEY'],
427
+ async read(env) {
428
+ const key = await resolveKey(env)
429
+ if (!key) return { status: 'needs-credential', credential: { refs: env.refs, configured: false } }
430
+ const res = await fetchT('https://opencode.ai/zen/go/v1/usage', { headers: { authorization: 'Bearer ' + key, accept: 'application/json' } }, 10000)
431
+ if (res.status === 401 || res.status === 403) throw err('model-usage/unauthorized', 'HTTP ' + res.status + '(OpenCode Key 无效)')
432
+ if (!res.ok) throw err('model-usage/http', 'HTTP ' + res.status)
433
+ const data = await res.json()
434
+ const u = (data && data.usage) || {}
435
+ const windows = []
436
+ for (const [key2, label] of [['rolling', '5h'], ['weekly', '周'], ['monthly', '月']]) {
437
+ const it = u[key2]
438
+ if (!it || typeof it !== 'object') continue
439
+ const pct = Number(it.percent)
440
+ if (!Number.isFinite(pct)) continue
441
+ const resetRaw = it.resetsAt
442
+ const resetAt = typeof resetRaw === 'string' ? Date.parse(resetRaw) || null : (Number(resetRaw) || null)
443
+ windows.push({ key: key2 === 'rolling' ? 'rolling' : key2 === 'weekly' ? 'weekly' : 'monthly', label, usedPct: clampPct(pct), resetAt })
444
+ }
445
+ if (!windows.length) return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'OpenCode Go 未返回 usage 窗口' } }
446
+ return { status: 'ok', fetchedAt: Date.now(), credential: { refs: env.refs, configured: true }, windows }
447
+ },
448
+ }
449
+
450
+ // Moonshot / Kimi 平台余额:GET https://api.moonshot.{cn,ai}/v1/users/me/balance Bearer
451
+ // 响应 { data: { available_balance, voucher_balance, cash_balance } }
452
+ const moonshotBalance = {
453
+ id: 'moonshot-balance',
454
+ refs: (cfg, route) => [cfg.credentials[route] || (/cn$/.test(route) ? 'MOONSHOT_CN_API_KEY' : 'MOONSHOT_API_KEY'), 'MOONSHOT_API_KEY', 'KIMI_API_KEY', 'MOONSHOT_CN_API_KEY'],
455
+ async read(env) {
456
+ const key = await resolveKey(env)
457
+ if (!key) return { status: 'needs-credential', credential: { refs: env.refs, configured: false } }
458
+ const cn = /cn$/.test(env.route || '')
459
+ const host = cn ? 'https://api.moonshot.cn' : 'https://api.moonshot.ai'
460
+ const res = await fetchT(host + '/v1/users/me/balance', { headers: { authorization: 'Bearer ' + key, accept: 'application/json' } }, 10000)
461
+ if (res.status === 401 || res.status === 403) throw err('model-usage/unauthorized', 'HTTP ' + res.status + '(Moonshot Key 无效)')
462
+ if (!res.ok) throw err('model-usage/http', 'HTTP ' + res.status)
463
+ const body = await res.json()
464
+ const d = (body && body.data) || body || {}
465
+ const pick = (k) => { const v = Number(d[k]); return Number.isFinite(v) ? v : null }
466
+ const available = pick('available_balance')
467
+ if (available == null) return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'Moonshot 未返回 available_balance' } }
468
+ const cash = pick('cash_balance')
469
+ const voucher = pick('voucher_balance')
470
+ const cur = cn ? 'CNY' : 'USD'
471
+ return {
472
+ status: 'ok',
473
+ fetchedAt: Date.now(),
474
+ credential: { refs: env.refs, configured: true },
475
+ balance: {
476
+ currency: cur,
477
+ total: available.toFixed(2),
478
+ toppedUp: cash != null ? cash.toFixed(2) : '',
479
+ granted: voucher != null ? voucher.toFixed(2) : '',
480
+ available: available > 0,
481
+ },
482
+ }
483
+ },
484
+ }
485
+
486
+ // MiniMax Token Plan:GET {api.minimax.io|api.minimaxi.com}/v1/token_plan/remains Bearer
487
+ // 响应 model_remains[] / models[]:current_interval_remaining_percent、current_weekly_remaining_percent、
488
+ // remains_time(毫秒)、weekly_remains_time、end_time / weekly_end_time
489
+ const minimaxPlan = {
490
+ id: 'minimax-plan',
491
+ refs: (cfg, route) => [cfg.credentials[route] || (/cn$/.test(route) ? 'MINIMAX_CN_API_KEY' : 'MINIMAX_API_KEY')],
492
+ async read(env) {
493
+ const key = await resolveKey(env)
494
+ if (!key) return { status: 'needs-credential', credential: { refs: env.refs, configured: false } }
495
+ const cn = /cn$/.test(env.route || '')
496
+ const url = cn ? 'https://api.minimaxi.com/v1/token_plan/remains' : 'https://api.minimax.io/v1/token_plan/remains'
497
+ const res = await fetchT(url, { headers: { authorization: 'Bearer ' + key, accept: 'application/json' } }, 10000)
498
+ if (res.status === 401 || res.status === 403) throw err('model-usage/unauthorized', 'HTTP ' + res.status + '(需要 MiniMax 订阅 Key,不是按量付费 Key)')
499
+ if (!res.ok) throw err('model-usage/http', 'HTTP ' + res.status)
500
+ const body = await res.json()
501
+ const base = (body && body.base_resp) || {}
502
+ if (Number(base.status_code) && Number(base.status_code) !== 0) {
503
+ return { status: 'unsupported', error: { code: 'model-usage/biz', message: String(base.status_msg || base.status_code) } }
504
+ }
505
+ const rows = [body.model_remains, body.models, body.data, body.data && body.data.model_remains].find((x) => Array.isArray(x) && x.length)
506
+ if (!rows) return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'MiniMax 未返回 model_remains' } }
507
+ const n = (row, keys) => {
508
+ for (const k of keys) { const v = Number(row[k]); if (Number.isFinite(v)) return v }
509
+ return null
510
+ }
511
+ // 取第一条有配额的行(多模型时展示主模型)
512
+ let picked = null
513
+ for (const row of rows) {
514
+ if (!row || typeof row !== 'object') continue
515
+ const intervalPct = n(row, ['current_interval_remaining_percent', 'interval_remaining_percent', 'current_interval_remain_percent'])
516
+ const weeklyPct = n(row, ['current_weekly_remaining_percent', 'weekly_remaining_percent', 'current_weekly_remain_percent'])
517
+ if (intervalPct == null && weeklyPct == null) continue
518
+ picked = { row, intervalPct, weeklyPct }
519
+ break
520
+ }
521
+ if (!picked) return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'MiniMax 配额字段缺失' } }
522
+ const now = Date.now()
523
+ const remainsToReset = (row, keys) => {
524
+ const ms = n(row, keys)
525
+ return ms == null ? null : now + ms
526
+ }
527
+ const endAt = (row, keys) => {
528
+ const v = n(row, keys)
529
+ if (v == null) return null
530
+ return v < 1e12 ? v * 1000 : v
531
+ }
532
+ const windows = []
533
+ if (picked.intervalPct != null) {
534
+ windows.push({
535
+ key: 'rolling', label: '5h',
536
+ usedPct: clampPct(100 - picked.intervalPct),
537
+ resetAt: endAt(picked.row, ['end_time', 'current_interval_end_time', 'interval_end_time']) || remainsToReset(picked.row, ['remains_time', 'current_interval_remains_time', 'interval_remains_time']),
538
+ })
539
+ }
540
+ if (picked.weeklyPct != null) {
541
+ windows.push({
542
+ key: 'weekly', label: '周',
543
+ usedPct: clampPct(100 - picked.weeklyPct),
544
+ resetAt: endAt(picked.row, ['weekly_end_time', 'current_weekly_end_time']) || remainsToReset(picked.row, ['weekly_remains_time', 'current_weekly_remains_time']),
545
+ })
546
+ }
547
+ const plan = (typeof (picked.row.subscribe_title || picked.row.plan_name || body.plan_name) === 'string') ? String(picked.row.subscribe_title || picked.row.plan_name || body.plan_name) : ''
548
+ return { status: 'ok', fetchedAt: Date.now(), credential: { refs: env.refs, configured: true }, plan, windows }
549
+ },
550
+ }
551
+
552
+ // Xiaomi MiMo 余额:GET https://platform.xiaomimimo.com/api/v1/balance Bearer
553
+ const xiaomiBalance = {
554
+ id: 'xiaomi-balance',
555
+ refs: (cfg, route) => [cfg.credentials[route] || 'XIAOMI_API_KEY'],
556
+ async read(env) {
557
+ const key = await resolveKey(env)
558
+ if (!key) return { status: 'needs-credential', credential: { refs: env.refs, configured: false } }
559
+ const res = await fetchT('https://platform.xiaomimimo.com/api/v1/balance', { headers: { authorization: 'Bearer ' + key, accept: 'application/json' } }, 10000)
560
+ if (res.status === 401 || res.status === 403) throw err('model-usage/unauthorized', 'HTTP ' + res.status + '(Xiaomi Key 无效)')
561
+ if (!res.ok) throw err('model-usage/http', 'HTTP ' + res.status)
562
+ const body = await res.json()
563
+ const d = (body && (body.data || body.result)) || body || {}
564
+ const val = [d.balance, d.remaining, d.available_balance, d.total_balance].map(Number).find((v) => Number.isFinite(v))
565
+ if (val == null) return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'Xiaomi 未返回余额字段' } }
566
+ return {
567
+ status: 'ok',
568
+ fetchedAt: Date.now(),
569
+ credential: { refs: env.refs, configured: true },
570
+ balance: { currency: 'CNY', total: val.toFixed(2), toppedUp: '', granted: '', available: val > 0 },
571
+ }
572
+ },
573
+ }
574
+
575
+ // GitHub Copilot:GET https://api.github.com/copilot_internal/user Bearer(GitHub token)
576
+ // 响应 quota_snapshots: { premium_interactions|chat|completions: { entitlement, remaining, percent_remaining } }
577
+ const githubCopilot = {
578
+ id: 'github-copilot',
579
+ refs: (cfg, route) => [cfg.credentials[route] || 'GITHUB_TOKEN', 'GH_TOKEN', 'GITHUB_COPILOT_TOKEN'],
580
+ async read(env) {
581
+ const key = await resolveKey(env)
582
+ if (!key) return { status: 'needs-credential', credential: { refs: env.refs, configured: false } }
583
+ const res = await fetchT('https://api.github.com/copilot_internal/user', {
584
+ headers: { authorization: 'Bearer ' + key, accept: 'application/json', 'user-agent': 'dsh-model-usage' },
585
+ }, 10000)
586
+ if (res.status === 401 || res.status === 403) throw err('model-usage/unauthorized', 'HTTP ' + res.status + '(需要 GitHub Copilot token)')
587
+ if (!res.ok) throw err('model-usage/http', 'HTTP ' + res.status)
588
+ const body = await res.json()
589
+ const snap = body && body.quota_snapshots
590
+ if (!snap || typeof snap !== 'object') return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'Copilot 未返回 quota_snapshots(非 Copilot 账号或接口改版)' } }
591
+ const windows = []
592
+ let resetAt = null
593
+ const qr = Number(body.quota_reset_date)
594
+ if (Number.isFinite(qr)) resetAt = qr < 1e12 ? qr * 1000 : qr
595
+ for (const [key2, label] of [['premium_interactions', 'Premium'], ['chat', 'Chat'], ['completions', '补全']]) {
596
+ const it = snap[key2]
597
+ if (!it || typeof it !== 'object') continue
598
+ const pctRemain = Number(it.percent_remaining)
599
+ const remain = Number(it.remaining)
600
+ const ent = Number(it.entitlement)
601
+ let usedPct = null
602
+ let countBased = false
603
+ let remaining = null
604
+ let limit = null
605
+ if (Number.isFinite(pctRemain)) usedPct = clampPct(100 - pctRemain)
606
+ else if (Number.isFinite(remain) && Number.isFinite(ent) && ent > 0) usedPct = clampPct(((ent - remain) / ent) * 100)
607
+ if (Number.isFinite(remain) && Number.isFinite(ent)) { countBased = true; remaining = remain; limit = ent }
608
+ if (usedPct == null) continue
609
+ windows.push({ key: key2, label, usedPct, resetAt, countBased, remaining, limit })
610
+ }
611
+ if (!windows.length) return { status: 'unsupported', error: { code: 'model-usage/shape', message: 'Copilot 配额为空' } }
612
+ const plan = typeof body.copilot_plan === 'string' ? body.copilot_plan : ''
613
+ return { status: 'ok', fetchedAt: Date.now(), credential: { refs: env.refs, configured: true }, plan, windows }
614
+ },
615
+ }
616
+
400
617
  // 通用自定义额度:任何供应商都能通过 cordis.patch.yml 的 customQuota 配置接入
401
618
  // customQuota: { [route]: { url, auth:'bearer'|'raw'|'x-api-key'|'none', keyRef, headers,
402
619
  // balance:{path,currencyPath,currency}, windows:[{key,label,usedPath,limitPath,resetAtPath,resetAtUnit}] } }
@@ -455,11 +672,17 @@ const customQuota = {
455
672
  }
456
673
 
457
674
  export function adapterFor(route, cfg) {
458
- if (route === 'deepseek-official') return deepseekBalance
675
+ if (!route) return null
676
+ if (route === 'deepseek-official' || route === 'deepseek') return deepseekBalance
459
677
  if (route === 'deepseek-account') return deepseekAccount
460
678
  if (route === 'zai-coding-cn' || route === 'zai') return glmCoding
461
- if (route && /^openrouter/i.test(route)) return openrouter
462
- if (route && /^(kimi|moonshot)/i.test(route)) return kimiCoding
679
+ if (/^openrouter/i.test(route)) return openrouter
680
+ if (/^kimi-coding/i.test(route)) return kimiCoding
681
+ if (/^(moonshot|kimi)/i.test(route)) return moonshotBalance
682
+ if (/^minimax/i.test(route)) return minimaxPlan
683
+ if (/^opencode-go/i.test(route)) return opencodeGo
684
+ if (/^(xiaomi|mimo)/i.test(route)) return xiaomiBalance
685
+ if (/^github-copilot/i.test(route)) return githubCopilot
463
686
  if (cfg && cfg.customQuota && cfg.customQuota[route] && cfg.customQuota[route].url) return customQuota
464
687
  return null
465
688
  }
package/lib/client.js CHANGED
@@ -43,6 +43,7 @@ window.__ModuleLoader__.load({
43
43
  spendTitle: '今日实际消耗', spentWord: '支出', rechargedWord: '充值', windowSpentWord: '额度消耗', thTime: '时间', thInput: '输入', thOutput: '输出', thCache: '缓存读', thDur: '耗时', thTtft: '首字', noLog: '暂无请求记录',
44
44
  shortAccount: '账号', remainCompact: '剩 {n}%', remainPrefix: '剩 ', remainSuffix: '', statsError: '统计加载失败', retry: '重试', emptyData: '暂无数据', emptyUsage: '今天还没有调用记录',
45
45
  kpiRequests: '模型调用', kpiTokens: '消耗 Tokens', kpiCacheHit: '缓存命中率',
46
+ limitMcp: '每月 MCP 工具', limitMonthly: '每月限额', remainCalls: '剩余 {n}/{m} 次',
46
47
  groupCurrent: '当前会话在用', groupSub: '订阅窗口', groupApi: 'API 余额', groupWallet: '账号钱包', groupOther: '其他',
47
48
  trendTitle: '使用趋势',
48
49
  thProvider: '供应商', thModel: '模型', thRequests: '请求数', thTokens: 'Tokens',
@@ -78,6 +79,7 @@ window.__ModuleLoader__.load({
78
79
  spendTitle: 'Today\'s actual usage', spentWord: 'Spent', rechargedWord: 'Recharged', windowSpentWord: 'Quota used', thTime: 'Time', thInput: 'Input', thOutput: 'Output', thCache: 'Cache', thDur: 'Duration', thTtft: 'TTFT', noLog: 'No requests yet',
79
80
  shortAccount: 'Account', remainCompact: '{n}% left', remainPrefix: '', remainSuffix: ' left', statsError: 'Failed to load stats', retry: 'Retry', emptyData: 'No data', emptyUsage: 'No calls today yet',
80
81
  kpiRequests: 'Model calls', kpiTokens: 'Tokens', kpiCacheHit: 'Cache hit rate',
82
+ limitMcp: 'MCP tools / month', limitMonthly: 'Monthly', remainCalls: '{n}/{m} calls left',
81
83
  groupCurrent: 'In use this session', groupSub: 'Subscription windows', groupApi: 'API balance', groupWallet: 'Account wallet', groupOther: 'Other',
82
84
  trendTitle: 'Usage trend',
83
85
  thProvider: 'Provider', thModel: 'Model', thRequests: 'Requests', thTokens: 'Tokens',
@@ -263,7 +265,7 @@ window.__ModuleLoader__.load({
263
265
  let seg = ''
264
266
  if (p.balance) seg += curSym(p.balance.currency) + p.balance.total
265
267
  if (p.windows && p.windows.length) {
266
- seg += (seg ? ' · ' : '') + p.windows.map((w) => w.label + ' ' + trFn('remainCompact', { n: 100 - Math.round(w.usedPct) })).join(' · ')
268
+ seg += (seg ? ' · ' : '') + p.windows.map((w) => windowLabel(w, trFn) + ' ' + (w.countBased ? trFn('remainCalls', { n: w.remaining != null ? w.remaining : '—', m: w.limit != null ? w.limit : '—' }) : trFn('remainCompact', { n: 100 - Math.round(w.usedPct) }))).join(' · ')
267
269
  }
268
270
  if (seg) parts.push(nm + seg)
269
271
  }
@@ -445,12 +447,13 @@ window.__ModuleLoader__.load({
445
447
  // ---------------------------------------------------------------- atoms
446
448
  const LOGO_SLUGS = [
447
449
  [/^deepseek/, 'deepseek'],
448
- [/^zai/, 'zai'],
450
+ [/^(zai|glm|bigmodel|zhipu|chatglm)/, 'zai'],
449
451
  [/^openai$/, 'openai'],
450
452
  [/^anthropic/, 'anthropic'],
451
453
  [/^(google-)?gemini/, 'googlegemini'],
452
- [/^moonshot/, 'moonshotai'],
453
- [/^kimi/, 'kimi'],
454
+ [/^(moonshot|kimi|moonshotai)/, 'kimi'],
455
+ [/^openrouter/, 'openrouter'],
456
+ [/^minimax/, 'minimax'],
454
457
  [/^xai/, 'xai'],
455
458
  ]
456
459
  function logoSlug(route) {
@@ -495,6 +498,13 @@ window.__ModuleLoader__.load({
495
498
  }
496
499
 
497
500
  /** 图1 规范式窗口行:名称 + 剩余 N% + 重置倒计时 + 剩余填充细条 */
501
+ function windowLabel(w, tr) {
502
+ if (w.key === 'rolling') return tr('limitRolling')
503
+ if (w.key === 'weekly') return tr('limitWeekly')
504
+ if (w.key === 'mcp') return tr('limitMcp')
505
+ if (w.key === 'monthly') return tr('limitMonthly')
506
+ return w.label || ''
507
+ }
498
508
  function WinRow({ w, tr }) {
499
509
  const used = Math.round(w.usedPct)
500
510
  const remain = 100 - used
@@ -502,8 +512,10 @@ window.__ModuleLoader__.load({
502
512
  const fillColor = used >= 80 ? 'var(--dsw-alias-state-error-primary,#f04438)' : used >= 50 ? 'var(--dsw-alias-state-warn-primary,#f79009)' : 'var(--dsw-alias-label-primary,#191f28)'
503
513
  return h('div', { className: 'win' },
504
514
  h('div', { className: 't' },
505
- h('span', { className: 'lb' }, w.key === 'rolling' ? tr('limitRolling') : tr('limitWeekly')),
506
- h('b', null, tr('remaining', { n: remain }))),
515
+ h('span', { className: 'lb' }, windowLabel(w, tr)),
516
+ h('b', null, w.countBased && w.remaining != null
517
+ ? tr('remainCalls', { n: w.remaining, m: w.limit != null ? w.limit : '—' })
518
+ : tr('remaining', { n: remain }))),
507
519
  h('div', { className: 'track' },
508
520
  h('div', { className: 'fill', style: { width: remain + '%', background: fillColor } })),
509
521
  h('div', { className: 'f' },
@@ -643,7 +655,7 @@ window.__ModuleLoader__.load({
643
655
  function metricTextOf(p, tr) {
644
656
  if (!p) return ''
645
657
  if (p.windows && p.windows.length) {
646
- return p.windows.map((w) => w.label + ' ' + tr('remainCompact', { n: 100 - Math.round(w.usedPct) })).join(' · ')
658
+ return p.windows.map((w) => windowLabel(w, tr) + ' ' + (w.countBased ? tr('remainCalls', { n: w.remaining != null ? w.remaining : '—', m: w.limit != null ? w.limit : '—' }) : tr('remainCompact', { n: 100 - Math.round(w.usedPct) }))).join(' · ')
647
659
  }
648
660
  if (p.balance) return curSym(p.balance.currency) + p.balance.total
649
661
  return ''
@@ -656,9 +668,10 @@ window.__ModuleLoader__.load({
656
668
  const used = Math.round(w.usedPct)
657
669
  return h('span', { key: w.key || i },
658
670
  i > 0 ? h('span', { style: { color: 'var(--dsw-alias-label-tertiary,#98a2b3)' } }, ' · ') : null,
659
- w.label + ' ' + tr('remainPrefix'),
660
- h('b', { style: { color: pctColor(used) } }, remain + '%'),
661
- tr('remainSuffix'))
671
+ windowLabel(w, tr) + ' ',
672
+ w.countBased
673
+ ? h('b', { style: { color: pctColor(used) } }, (w.remaining != null ? w.remaining : '—') + '/' + (w.limit != null ? w.limit : '—'))
674
+ : h('span', null, tr('remainPrefix'), h('b', { style: { color: pctColor(used) } }, remain + '%'), tr('remainSuffix')))
662
675
  }))
663
676
  }
664
677
  if (p.balance) {
@@ -720,19 +733,23 @@ window.__ModuleLoader__.load({
720
733
  // 小型卡片:弹窗卡片的迷你版(头部 + 订阅迷你窗口条 / 余额)
721
734
  const bodyKids = []
722
735
  if (current && current.windows && current.windows.length) {
723
- bodyKids.push(h('div', { className: 'dmu-mwin', key: 'w0' },
724
- h('div', { className: 't' },
725
- h('span', null, current.windows[0].key === 'rolling' ? tr('limitRolling') : tr('limitWeekly')),
726
- h('b', null, tr('remaining', { n: 100 - Math.round(current.windows[0].usedPct) }))),
727
- h('div', { className: 'track' },
728
- h('div', { className: 'fill', style: { width: (100 - Math.round(current.windows[0].usedPct)) + '%', background: current.windows[0].usedPct >= 80 ? 'var(--dsw-alias-state-error-primary,#f04438)' : current.windows[0].usedPct >= 50 ? 'var(--dsw-alias-state-warn-primary,#f79009)' : 'var(--dsw-alias-label-primary,#191f28)' } }))))
729
- if (current.windows[1]) {
730
- bodyKids.push(h('div', { className: 'dmu-mwin', key: 'w1' },
731
- h('div', { className: 't' },
732
- h('span', null, current.windows[1].key === 'rolling' ? tr('limitRolling') : tr('limitWeekly')),
733
- h('b', null, tr('remaining', { n: 100 - Math.round(current.windows[1].usedPct) }))),
734
- h('div', { className: 'track' },
735
- h('div', { className: 'fill', style: { width: (100 - Math.round(current.windows[1].usedPct)) + '%', background: current.windows[1].usedPct >= 80 ? 'var(--dsw-alias-state-error-primary,#f04438)' : current.windows[1].usedPct >= 50 ? 'var(--dsw-alias-state-warn-primary,#f79009)' : 'var(--dsw-alias-label-primary,#191f28)' } }))))
736
+ for (const [i, w] of current.windows.slice(0, 3).entries()) {
737
+ const used = Math.round(w.usedPct)
738
+ const remain = 100 - used
739
+ const color = used >= 80 ? 'var(--dsw-alias-state-error-primary,#f04438)' : used >= 50 ? 'var(--dsw-alias-state-warn-primary,#f79009)' : 'var(--dsw-alias-label-primary,#191f28)'
740
+ if (w.countBased) {
741
+ bodyKids.push(h('div', { className: 'dmu-mwin', key: 'w' + i },
742
+ h('div', { className: 't' },
743
+ h('span', null, windowLabel(w, tr)),
744
+ h('b', null, tr('remainCalls', { n: w.remaining != null ? w.remaining : '—', m: w.limit != null ? w.limit : '—' })))))
745
+ } else {
746
+ bodyKids.push(h('div', { className: 'dmu-mwin', key: 'w' + i },
747
+ h('div', { className: 't' },
748
+ h('span', null, windowLabel(w, tr)),
749
+ h('b', null, tr('remaining', { n: remain }))),
750
+ h('div', { className: 'track' },
751
+ h('div', { className: 'fill', style: { width: remain + '%', background: color } }))))
752
+ }
736
753
  }
737
754
  } else if (current && current.balance) {
738
755
  bodyKids.push(h('div', { className: 'dmu-big', key: 'b0', style: { fontSize: 22, marginTop: 8 } },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponydev/dsh-model-usage",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "DSH Web 插件:实时显示模型供应商额度与用量(DeepSeek / GLM Coding Plan / OpenRouter / Kimi Coding Plan + 自定义适配器)",
5
5
  "keywords": [
6
6
  "dsh",