@loommii/dsh-provider-usage 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-provider-usage — DSH「用量中心」
2
2
 
3
- > 当前版本 **v0.8.0** · npm `@loommii/dsh-provider-usage` · [更新历史](docs/CHANGELOG.md)
3
+ > 当前版本 **v0.10.0** · npm `@loommii/dsh-provider-usage` · [更新历史](docs/CHANGELOG.md)
4
4
 
5
5
  DSH Web GUI 插件 **「用量中心」**:一个常驻右下角的用量卡片,实时显示你的 AI 服务用量 / 余额,不用再打开网页查;附带本地 Token 统计页,不联网也能看自己今天用了多少。
6
6
 
@@ -28,6 +28,7 @@ DSH Web GUI 插件 **「用量中心」**:一个常驻右下角的用量卡片
28
28
  | OpenCode Go(订阅) | 5 小时 / 7 天 / 月度三个窗口的已用百分比 + 进度条 + 重置倒计时 |
29
29
  | DeepSeek(余额) | 账户余额(CNY) |
30
30
  | Command Code(订阅+余额,自定义) | 5 小时 / 周 / 月窗口使用量 + 月度剩余额度(USD),主数字为本月剩余百分比(3 位小数向下取整) |
31
+ | AMD Radeon Cloud (中国)(余额+配额,自定义) | 今日剩余额度(pts)+ 今日已用/限额 + 单日窗口进度条 + 重置倒计时(无周/月窗口;国际版位置预留) |
31
32
 
32
33
  ## 功能
33
34
 
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.10.0(未发布)
4
+
5
+ - **新增提供方 AMD Radeon Cloud (中国)(余额+配额卡)**:实测端点 `GET {baseUrl}/usage`(`https://developer.amd.com.cn/radeon/api/v1/usage`,Bearer API Key)——今日剩余 pts 为主数字(3 位小数向下取整百分比)、副行已用/限额 + 剩余(pts)、单日窗口进度条 + 重置倒计时;透传今日/近24h/近30天/累计时间段汇总与按模型拆分(`by_model`)、单次调用明细(`recent`)
6
+ - **无周/月窗口**:AMD 只按日限额计(`daily_cost_limit/used/remaining_usd`),接口无 weekly/monthly 字段;适配器只画「今日」一行进度条
7
+ - **仅自定义添加**:`customOnly`(同 Command Code),Key 加密存插件私有库,默认引用 `RADEON_API_KEY`
8
+ - **国内 / 国际版本**:AMD Radeon Cloud 分两个版本——当前仅接入**中国版**(`developer.amd.com.cn`,显示名「AMD Radeon Cloud (中国)」),国际版 baseUrl/端点不同,适配器位置已预留(后续新增 `amd-radeon-usage-intl` 条目即可)
9
+ - 调研文档:`tmp/AmDRadeonCloud_usage调研.md`(含实测 curl 与字段表;官方文档页路径 404 已记录)
10
+
11
+ ## v0.9.0(2026-09-08)
12
+
13
+ ### 小功能
14
+
15
+ - **Command Code 官方 logo 替换「CC」文字占位**:卡片头部与切换菜单里的 Command Code 图标
16
+ 由紫色渐变底 + 「CC」文字改为官方 ⌘ 符号(白符号·黑底,viewBox 446×446),SVG 内联渲染、
17
+ 随容器裁切圆角;原始素材归档到 `lib/assets/cmdsymbol-light-black-bg.svg`(随包发布便于溯源)。
18
+
3
19
  ## v0.8.0(2026-09-03)
4
20
 
5
21
  ### 修复:重启/存储丢失后提供方清单被静默重建(严重数据丢失)
@@ -0,0 +1,18 @@
1
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2
+ viewBox="580 280 200 200" style="display:block" xml:space="preserve">
3
+ <style type="text/css">
4
+ .st0{fill-rule:evenodd;clip-rule:evenodd;}
5
+ .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
6
+ </style>
7
+ <g>
8
+ <polygon class="st0" points="586,288 778.8,288 778.8,480.8 586,480.8 586,288 "/>
9
+ <path class="st1" d="M658.2,461.3h-10.5l-3.2-7.7h-17.4l-2.9,7.7h-10.3l15.7-39h11.3L658.2,461.3L658.2,461.3L658.2,461.3z
10
+ M635.4,431.6l-5.7,15.2h12L635.4,431.6L635.4,431.6z"/>
11
+ <polygon class="st1" points="696.2,422.3 704.7,422.3 704.7,461.3 695,461.3 695,437 684.4,449.2 682.9,449.2 672.4,437
12
+ 672.4,461.3 662.7,461.3 662.7,422.3 671.2,422.3 683.7,436.8 696.2,422.3 "/>
13
+ <path class="st1" d="M729.3,422.3c14.2,0,21.6,8.9,21.6,19.6c0,11.2-7.1,19.4-22.7,19.4h-16.1v-39H729.3L729.3,422.3L729.3,422.3z
14
+ M721.8,454.2h6.3c9.8,0,12.7-6.6,12.7-12.4c0-6.7-3.6-12.4-12.8-12.4h-6.2V454.2L721.8,454.2z"/>
15
+ <polygon class="st1" points="702.5,333.4 660.1,333.4 634,307.5 728.8,307.4 728.8,402.1 702.5,375.6 702.5,333.4 "/>
16
+ <polygon class="st1" points="660.4,376.4 660.2,338.2 633.3,365 633.3,402.8 672.2,402.8 698.5,376.4 660.4,376.4 "/>
17
+ </g>
18
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="446" height="446" viewBox="0 0 446 446" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="446" height="446" fill="black"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M226.665 18.1979H218.375C166.389 18.1979 129.23 18.2366 100.991 22.0332C73.2761 25.7594 56.8935 32.8027 44.8481 44.8481C32.8027 56.8935 25.7594 73.2761 22.0332 100.991C18.2365 129.23 18.1979 166.389 18.1979 218.375V226.665C18.1979 278.651 18.2365 315.809 22.0332 344.048C25.7594 371.764 32.8027 388.146 44.8481 400.192C56.8935 412.237 73.276 419.28 100.991 423.007C129.23 426.803 166.389 426.842 218.375 426.842H226.665C278.651 426.842 315.809 426.803 344.048 423.007C371.764 419.28 388.146 412.237 400.191 400.192C412.237 388.146 419.28 371.764 423.006 344.048C426.803 315.809 426.842 278.651 426.842 226.665V218.375C426.842 166.389 426.803 129.23 423.006 100.991C419.28 73.2761 412.237 56.8935 400.191 44.8481C388.146 32.8027 371.764 25.7594 344.048 22.0332C315.809 18.2366 278.651 18.1979 226.665 18.1979ZM31.9803 31.9803C0 63.9605 0 115.432 0 218.375V226.665C0 329.608 0 381.079 31.9803 413.059C63.9605 445.04 115.432 445.04 218.375 445.04H226.665C329.608 445.04 381.079 445.04 413.059 413.059C445.04 381.079 445.04 329.608 445.04 226.665V218.375C445.04 115.432 445.04 63.9605 413.059 31.9803C381.079 0 329.608 0 226.665 0H218.375C115.432 0 63.9605 0 31.9803 31.9803Z" fill="white"/>
4
+ <path d="M306.202 85.5845C276.837 85.5845 252.95 109.472 252.95 138.837V161.66H192.09V138.837C192.09 109.472 168.202 85.5845 138.837 85.5845C109.472 85.5845 85.5845 109.472 85.5845 138.837C85.5845 168.202 109.472 192.09 138.837 192.09H161.66V252.95H138.837C109.472 252.95 85.5845 276.837 85.5845 306.202C85.5845 335.568 109.472 359.455 138.837 359.455C168.202 359.455 192.09 335.568 192.09 306.202V283.38H252.95V306.202C252.95 335.568 276.837 359.455 306.202 359.455C335.567 359.455 359.455 335.568 359.455 306.202C359.455 276.837 335.567 252.95 306.202 252.95H283.38V192.09H306.202C335.567 192.09 359.455 168.202 359.455 138.837C359.455 109.472 335.567 85.5845 306.202 85.5845ZM283.38 161.66V138.837C283.38 126.209 293.574 116.015 306.202 116.015C318.831 116.015 329.025 126.209 329.025 138.837C329.025 151.466 318.831 161.66 306.202 161.66H283.38ZM138.837 161.66C126.209 161.66 116.015 151.466 116.015 138.837C116.015 126.209 126.209 116.015 138.837 116.015C151.466 116.015 161.66 126.209 161.66 138.837V161.66H138.837ZM192.09 252.95V192.09H252.95V252.95H192.09ZM306.202 329.025C293.574 329.025 283.38 318.831 283.38 306.202V283.38H306.202C318.831 283.38 329.025 293.574 329.025 306.202C329.025 318.831 318.831 329.025 306.202 329.025ZM138.837 329.025C126.209 329.025 116.015 318.831 116.015 306.202C116.015 293.574 126.209 283.38 138.837 283.38H161.66V306.202C161.66 318.831 151.466 329.025 138.837 329.025Z" fill="white"/>
5
+ </svg>
package/lib/client.js CHANGED
@@ -25,9 +25,12 @@ window.__ModuleLoader__.load({
25
25
  const Z_INDEX = 2147483000;
26
26
  // 适配器元数据(与 host ADAPTERS 对应;logo 与显示名用于设置页/菜单)
27
27
  const ADAPTER_META = {
28
- 'usage-percent': { displayName: 'OpenCode Go(订阅额度)' },
28
+ 'usage-percent': { displayName: 'OpenCode Go' },
29
29
  'balance-json': { displayName: 'DeepSeek' },
30
- 'commandcode-credits': { displayName: 'Command Code(订阅+余额)' },
30
+ 'commandcode-credits': { displayName: 'Command Code' },
31
+ // AMD Radeon Cloud 分国内 / 国际两个版本(国内 = developer.amd.com.cn;国际版 baseUrl/端点不同)。
32
+ // 当前仅接入中国版「AMD Radeon Cloud (中国)」;国际版位置预留,后续接入时新增适配器条目即可。
33
+ 'amd-radeon-usage': { displayName: 'AMD Radeon Cloud (中国)' },
31
34
  };
32
35
  // 供应商实例清单(用户可配置:名称可改、可增删、可同类型多个;key 引用走 DSH 凭证)
33
36
  const PROVIDERS_KEY = 'dsh-provider-usage.providers';
@@ -47,6 +50,17 @@ window.__ModuleLoader__.load({
47
50
  // DeepSeek:官方鲸 logo PNG(225×225 RGBA)→ data URI,透明底直接展示
48
51
  const LOGO_DEEPSEEK = 'data:image/png;base64,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';
49
52
 
53
+ // Command Code:官方 ⌘ logo(白符号·黑底,viewBox 446×446)→ 内联 SVG(替换原「CC」文字占位)
54
+ const LOGO_CC = React.createElement('svg', { viewBox: '0 0 446 446', 'aria-hidden': 'true', style: { display: 'block', width: '100%', height: '100%' } },
55
+ React.createElement('rect', { width: '446', height: '446', fill: '#000000' }),
56
+ React.createElement('path', { fillRule: 'evenodd', clipRule: 'evenodd', fill: '#FFFFFF', d: 'M226.665 18.1979H218.375C166.389 18.1979 129.23 18.2366 100.991 22.0332C73.2761 25.7594 56.8935 32.8027 44.8481 44.8481C32.8027 56.8935 25.7594 73.2761 22.0332 100.991C18.2365 129.23 18.1979 166.389 18.1979 218.375V226.665C18.1979 278.651 18.2365 315.809 22.0332 344.048C25.7594 371.764 32.8027 388.146 44.8481 400.192C56.8935 412.237 73.276 419.28 100.991 423.007C129.23 426.803 166.389 426.842 218.375 426.842H226.665C278.651 426.842 315.809 426.803 344.048 423.007C371.764 419.28 388.146 412.237 400.191 400.192C412.237 388.146 419.28 371.764 423.006 344.048C426.803 315.809 426.842 278.651 426.842 226.665V218.375C426.842 166.389 426.803 129.23 423.006 100.991C419.28 73.2761 412.237 56.8935 400.191 44.8481C388.146 32.8027 371.764 25.7594 344.048 22.0332C315.809 18.2366 278.651 18.1979 226.665 18.1979ZM31.9803 31.9803C0 63.9605 0 115.432 0 218.375V226.665C0 329.608 0 381.079 31.9803 413.059C63.9605 445.04 115.432 445.04 218.375 445.04H226.665C329.608 445.04 381.079 445.04 413.059 413.059C445.04 381.079 445.04 329.608 445.04 226.665V218.375C445.04 115.432 445.04 63.9605 413.059 31.9803C381.079 0 329.608 0 226.665 0H218.375C115.432 0 63.9605 0 31.9803 31.9803Z' }),
57
+ React.createElement('path', { fill: '#FFFFFF', d: 'M306.202 85.5845C276.837 85.5845 252.95 109.472 252.95 138.837V161.66H192.09V138.837C192.09 109.472 168.202 85.5845 138.837 85.5845C109.472 85.5845 85.5845 109.472 85.5845 138.837C85.5845 168.202 109.472 192.09 138.837 192.09H161.66V252.95H138.837C109.472 252.95 85.5845 276.837 85.5845 306.202C85.5845 335.568 109.472 359.455 138.837 359.455C168.202 359.455 192.09 335.568 192.09 306.202V283.38H252.95V306.202C252.95 335.568 276.837 359.455 306.202 359.455C335.567 359.455 359.455 335.568 359.455 306.202C359.455 276.837 335.567 252.95 306.202 252.95H283.38V192.09H306.202C335.567 192.09 359.455 168.202 359.455 138.837C359.455 109.472 335.567 85.5845 306.202 85.5845ZM283.38 161.66V138.837C283.38 126.209 293.574 116.015 306.202 116.015C318.831 116.015 329.025 126.209 329.025 138.837C329.025 151.466 318.831 161.66 306.202 161.66H283.38ZM138.837 161.66C126.209 161.66 116.015 151.466 116.015 138.837C116.015 126.209 126.209 116.015 138.837 116.015C151.466 116.015 161.66 126.209 161.66 138.837V161.66H138.837ZM192.09 252.95V192.09H252.95V252.95H192.09ZM306.202 329.025C293.574 329.025 283.38 318.831 283.38 306.202V283.38H306.202C318.831 283.38 329.025 293.574 329.025 306.202C329.025 318.831 318.831 329.025 306.202 329.025ZM138.837 329.025C126.209 329.025 116.015 318.831 116.015 306.202C116.015 293.574 126.209 283.38 138.837 283.38H161.66V306.202C161.66 318.831 151.466 329.025 138.837 329.025Z' }));
58
+
59
+ // AMD Radeon Cloud:官方 SVG logo(黑色方块底 + 白色箭头/AMD 字标),viewBox 裁切为正方形
60
+ // 来源:lib/assets/amd-radeon-logo.svg(由 amd-seeklogo.svg 修正 viewBox 后生成)
61
+ const LOGO_AMD_SVG = 'data:image/svg+xml,' + encodeURIComponent(`<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="580 280 200 200" style="display:block"><style>.st0{fill-rule:evenodd;clip-rule:evenodd}.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFF}</style><g><polygon class="st0" points="586,288 778.8,288 778.8,480.8 586,480.8"/><path class="st1" d="M658.2 461.3h-10.5l-3.2-7.7h-17.4l-2.9 7.7h-10.3l15.7-39h11.3l17.3 39zm-22.8-29.7l-5.7 15.2h12l-6.3-15.2z"/><polygon class="st1" points="696.2 422.3 704.7 422.3 704.7 461.3 695 461.3 695 437 684.4 449.2 682.9 449.2 672.4 437 672.4 461.3 662.7 461.3 662.7 422.3 671.2 422.3 683.7 436.8"/><path class="st1" d="M729.3 422.3c14.2 0 21.6 8.9 21.6 19.6 0 11.2-7.1 19.4-22.7 19.4h-16.1v-39h17.2zm-7.5 31.9h6.3c9.8 0 12.7-6.6 12.7-12.4 0-6.7-3.6-12.4-12.8-12.4h-6.2v24.8z"/><polygon class="st1" points="702.5 333.4 660.1 333.4 634 307.5 728.8 307.4 728.8 402.1 702.5 375.6 702.5 333.4"/><polygon class="st1" points="660.4 376.4 660.2 338.2 633.3 365 633.3 402.8 672.2 402.8 698.5 376.4 660.4 376.4"/></g></svg>`);
62
+ const LOGO_AMD = React.createElement('img', { src: LOGO_AMD_SVG, alt: '', style: { display: 'block', width: '100%', height: '100%' } });
63
+
50
64
  const zh = {
51
65
  loading: '查询中…',
52
66
  refresh: '刷新',
@@ -55,6 +69,7 @@ window.__ModuleLoader__.load({
55
69
  rolling: '5小时滚动',
56
70
  weekly: '7天(每周)',
57
71
  monthly: '每月',
72
+ daily: '今日',
58
73
  used: '已用',
59
74
  errorTitle: '无法获取用量',
60
75
  nav: '用量中心',
@@ -78,8 +93,8 @@ window.__ModuleLoader__.load({
78
93
  '.dsh-pu-card-head{display:flex;align-items:center;gap:8px;margin-bottom:10px}',
79
94
  '.dsh-pu-logo{width:30px;height:30px;border-radius:8px;flex:none;display:flex;align-items:center;justify-content:center;overflow:hidden;background:transparent}',
80
95
  '.dsh-pu-logo.go svg,.dsh-pu-logo.deepseek img{display:block}',
81
- '.dsh-pu-cc-logo{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;background:linear-gradient(135deg,#5B3A9E,#8E5BD8);color:#fff;font-size:13px;font-weight:800;letter-spacing:.5px;font-family:inherit;flex:none}',
82
- '.dsh-pu-cc-logo-sm{width:22px;height:22px;border-radius:6px;font-size:10px}',
96
+ '.dsh-pu-cc-logo{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;overflow:hidden;flex:none}',
97
+ '.dsh-pu-cc-logo-sm{width:22px;height:22px;border-radius:6px}',
83
98
  '.dsh-pu-cc-sub{display:flex;align-items:center;gap:10px;margin:-6px 0 6px;font-size:11px;color:#C9B8BE;white-space:nowrap}',
84
99
  '.dsh-pu-cc-sub .dsh-pu-cc-used{color:#EFE0E5;font-weight:600}',
85
100
  '.dsh-pu-cc-sub .dsh-pu-cc-remain{color:#FFB3C6;font-weight:600}',
@@ -448,12 +463,15 @@ window.__ModuleLoader__.load({
448
463
  var meta = data && data.fetchedAt ? fmtTime(data.fetchedAt) + (data.stale ? ' · ' + zh.stale : '') : zh.loading;
449
464
  var isBalance = current.adapter === 'balance-json';
450
465
  var isCommandCode = current.adapter === 'commandcode-credits';
451
- var logoClass = isBalance ? 'deepseek' : (isCommandCode ? 'commandcode' : 'go');
466
+ var isAmd = current.adapter === 'amd-radeon-usage';
467
+ var logoClass = isBalance ? 'deepseek' : (isCommandCode ? 'commandcode' : (isAmd ? 'amd' : 'go'));
452
468
  var logoEl = isBalance
453
469
  ? React.createElement('img', { src: LOGO_DEEPSEEK, width: 24, height: 24, alt: '' })
454
470
  : (isCommandCode
455
- ? React.createElement('span', { className: 'dsh-pu-cc-logo', 'aria-hidden': 'true' }, 'CC')
456
- : LOGO_OCGO);
471
+ ? React.createElement('span', { className: 'dsh-pu-cc-logo', 'aria-hidden': 'true' }, LOGO_CC)
472
+ : (isAmd
473
+ ? React.createElement('span', { className: 'dsh-pu-cc-logo', 'aria-hidden': 'true' }, LOGO_AMD)
474
+ : LOGO_OCGO));
457
475
 
458
476
  var body = null;
459
477
  if (loading && !data) {
@@ -475,38 +493,44 @@ window.__ModuleLoader__.load({
475
493
  (data.monthly && data.monthly.usedPct !== null
476
494
  ? React.createElement(WindowRow, { key: 'm', label: zh.monthly, win: data.monthly, bar: 'magenta' })
477
495
  : null)].filter(Boolean)
478
- : [React.createElement(WindowRow, { key: 'r', label: zh.rolling, win: data.windows.rolling, bar: 'pink' }),
479
- React.createElement(WindowRow, { key: 'w', label: zh.weekly, win: data.windows.weekly, bar: 'orange' }),
480
- React.createElement(WindowRow, { key: 'm', label: zh.monthly, win: data.windows.monthly, bar: 'magenta' })])
496
+ : (isAmd
497
+ // AMD:单日窗口进度条(对齐网页 Today Used / Remaining;无周/月)
498
+ ? [React.createElement(WindowRow, { key: 'd', label: zh.daily, win: data.windows.daily, bar: 'magenta' })]
499
+ : [React.createElement(WindowRow, { key: 'r', label: zh.rolling, win: data.windows.rolling, bar: 'pink' }),
500
+ React.createElement(WindowRow, { key: 'w', label: zh.weekly, win: data.windows.weekly, bar: 'orange' }),
501
+ React.createElement(WindowRow, { key: 'm', label: zh.monthly, win: data.windows.monthly, bar: 'magenta' })]))
481
502
  : null;
482
503
  var warn = data.isValid === false && data.invalidMessage
483
504
  ? React.createElement('div', { className: 'dsh-pu-error' }, data.invalidMessage)
484
505
  : null;
485
- // Command Code 混合卡:主数字 = 月剩余百分比(3 位小数向下取整),副行 = 已用/总额 + 剩余额度
506
+ // Command Code / AMD 混合卡:主数字 = 剩余百分比(3 位小数向下取整),副行 = 已用/总额 + 剩余额度
507
+ // Command Code 读 monthly.remainingPct;AMD 读 windows.daily.remainingPct(今日)
486
508
  var cc = null;
487
- if (isCommandCode) {
488
- var monthlyInfo = data.monthly || null;
509
+ var remainPct = null;
510
+ if (isCommandCode || isAmd) {
511
+ var pctInfo = isAmd ? (data.windows && data.windows.daily) : (data.monthly || null);
489
512
  // 新服务端直接给 remainingPct;旧服务端只有 usedPct → 按 100−usedPct 兜底(与 host 公式数学等价)
490
- var remainPct = monthlyInfo
491
- ? (monthlyInfo.remainingPct !== undefined && monthlyInfo.remainingPct !== null
492
- ? monthlyInfo.remainingPct
493
- : (monthlyInfo.usedPct === undefined || monthlyInfo.usedPct === null
513
+ remainPct = pctInfo
514
+ ? (pctInfo.remainingPct !== undefined && pctInfo.remainingPct !== null
515
+ ? pctInfo.remainingPct
516
+ : (pctInfo.usedPct === undefined || pctInfo.usedPct === null
494
517
  ? null
495
- : Math.floor(Math.max(0, Math.min(100, 100 - monthlyInfo.usedPct)) * 1000) / 1000))
518
+ : Math.floor(Math.max(0, Math.min(100, 100 - pctInfo.usedPct)) * 1000) / 1000))
496
519
  : null;
497
- var usedStr = data.used === null ? '--' : Number(data.used).toFixed(2);
498
- var quotaStr = data.totalQuota === null ? '--' : Number(data.totalQuota).toFixed(2);
499
- var remainStr = data.remaining === null ? '--' : Number(data.remaining).toFixed(2);
520
+ var unitSym = isAmd ? '' : '$';
521
+ var usedStr = data.used === null ? '--' : Number(data.used).toFixed(isAmd ? 3 : 2);
522
+ var quotaStr = data.totalQuota === null ? '--' : Number(data.totalQuota).toFixed(isAmd ? 3 : 2);
523
+ var remainStr = data.remaining === null ? '--' : Number(data.remaining).toFixed(isAmd ? 3 : 2);
500
524
  cc = React.createElement('div', { className: 'dsh-pu-cc-sub' },
501
- React.createElement('span', { className: 'dsh-pu-cc-used' }, '已用 $' + usedStr + ' / $' + quotaStr),
502
- React.createElement('span', { className: 'dsh-pu-cc-remain' }, '剩余 $' + remainStr));
525
+ React.createElement('span', { className: 'dsh-pu-cc-used' }, (isAmd ? zh.daily + ' ' : '') + '已用 ' + unitSym + usedStr + ' / ' + unitSym + quotaStr + (isAmd ? ' pts' : '')),
526
+ React.createElement('span', { className: 'dsh-pu-cc-remain' }, (isAmd ? zh.daily + ' ' : '') + '剩余 ' + unitSym + remainStr + (isAmd ? ' pts' : '')));
503
527
  }
504
528
  // 窗口行/主值/警告条已覆盖全部信息,extra 全文不再展示(保持卡片干净)
505
529
  var extra = null;
506
530
  body = React.createElement('div', null,
507
531
  React.createElement('div', { className: 'dsh-pu-remain' },
508
- React.createElement('span', { className: 'dsh-pu-remain-big' }, isCommandCode ? (remainPct === null ? '--' : remainPct.toFixed(3) + '%') : main),
509
- React.createElement('span', { className: 'dsh-pu-remain-label' }, isCommandCode ? ' ' + zh.remaining + '(' + zh.monthly + ')' : ' ' + mainLabel)),
532
+ React.createElement('span', { className: 'dsh-pu-remain-big' }, (isCommandCode || isAmd) ? (remainPct === null ? '--' : remainPct.toFixed(3) + '%') : main),
533
+ React.createElement('span', { className: 'dsh-pu-remain-label' }, (isCommandCode || isAmd) ? ' ' + zh.remaining + '(' + (isAmd ? zh.daily : zh.monthly) + ')' : ' ' + mainLabel)),
510
534
  warn,
511
535
  cc,
512
536
  winRows,
@@ -521,8 +545,10 @@ window.__ModuleLoader__.load({
521
545
  var mini = p.adapter === 'balance-json'
522
546
  ? React.createElement('img', { src: LOGO_DEEPSEEK, width: 16, height: 16, alt: '' })
523
547
  : (p.adapter === 'commandcode-credits'
524
- ? React.createElement('span', { className: 'dsh-pu-cc-logo dsh-pu-cc-logo-sm', 'aria-hidden': 'true' }, 'CC')
525
- : LOGO_OCGO);
548
+ ? React.createElement('span', { className: 'dsh-pu-cc-logo dsh-pu-cc-logo-sm', 'aria-hidden': 'true' }, LOGO_CC)
549
+ : (p.adapter === 'amd-radeon-usage'
550
+ ? React.createElement('span', { className: 'dsh-pu-cc-logo dsh-pu-cc-logo-sm', 'aria-hidden': 'true' }, LOGO_AMD)
551
+ : LOGO_OCGO));
526
552
  return React.createElement('button', {
527
553
  key: p.id, type: 'button', className: 'dsh-pu-menu-item' + (active ? ' active' : ''),
528
554
  onClick: function (e) { if (draggedRef.current) { draggedRef.current = false; return; } e.stopPropagation(); setSettings({ providerId: p.id }); setMenuOpen(false); },
@@ -893,7 +919,7 @@ window.__ModuleLoader__.load({
893
919
  setMode('manual');
894
920
  setEdit(null);
895
921
  setFormError(null);
896
- setForm({ provider: '', name: 'Command Code', adapter: 'commandcode-credits', key: '', nameTouched: false });
922
+ setForm({ provider: '', name: 'AMD Radeon Cloud (中国)', adapter: 'amd-radeon-usage', key: '', nameTouched: false });
897
923
  }
898
924
  function cancelAdd() { setMode(null); setEdit(null); setFormError(null); }
899
925
 
@@ -1120,7 +1146,7 @@ window.__ModuleLoader__.load({
1120
1146
  className: 'zGbnIq_input zGbnIq_selectInput', value: form.adapter,
1121
1147
  onChange: function (e) {
1122
1148
  var next = Object.assign({}, form, { adapter: e.target.value });
1123
- if (!form.nameTouched) next.name = e.target.value === 'balance-json' ? 'DeepSeek' : (e.target.value === 'commandcode-credits' ? 'Command Code' : 'OpenCode Go');
1149
+ if (!form.nameTouched) next.name = e.target.value === 'balance-json' ? 'DeepSeek' : (e.target.value === 'commandcode-credits' ? 'Command Code' : (e.target.value === 'amd-radeon-usage' ? 'AMD Radeon Cloud (中国)' : 'OpenCode Go'));
1124
1150
  setForm(next);
1125
1151
  },
1126
1152
  }, adapterOptions)),
package/lib/index.js CHANGED
@@ -21,8 +21,8 @@ export const name = 'provider-usage'
21
21
 
22
22
  /** 插件版本单一来源:package.json(UA 标识用;bundle 内嵌等读不到时回退字面量)。 */
23
23
  const PLUGIN_VERSION = (() => {
24
- try { return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version || '0.7.0' }
25
- catch { return '0.7.0' }
24
+ try { return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version || '0.10.0' }
25
+ catch { return '0.10.0' }
26
26
  })()
27
27
  const USER_AGENT = 'dsh-provider-usage/' + PLUGIN_VERSION
28
28
 
@@ -51,7 +51,7 @@ const LOCAL_DEPS_CHECK_MS = 300000
51
51
  const ADAPTERS = [
52
52
  {
53
53
  id: 'usage-percent',
54
- displayName: 'OpenCode Go(订阅额度)',
54
+ displayName: 'OpenCode Go',
55
55
  baseUrl: 'https://opencode.ai/zen/go',
56
56
  usagePath: '/v1/usage',
57
57
  defaultCredentialRef: 'OPENCODE_GO_API_KEY',
@@ -71,7 +71,7 @@ const ADAPTERS = [
71
71
  // Command Code:DSH 非内置提供方(pi-ai 注册表无 commandcode),只允许「添加自定义提供方」
72
72
  // (customOnly),Key 只存插件私有库(settingsProviderKey: null → 凭证链跳过 DSH 模型设置)。
73
73
  id: 'commandcode-credits',
74
- displayName: 'Command Code(订阅+余额)',
74
+ displayName: 'Command Code',
75
75
  baseUrl: 'https://api.commandcode.ai',
76
76
  usagePath: '/alpha/billing/credits',
77
77
  subscriptionPath: '/alpha/billing/subscriptions',
@@ -80,6 +80,21 @@ const ADAPTERS = [
80
80
  customOnly: true,
81
81
  description: 'Command Code 订阅使用量(5小时/周窗口)+ 月度剩余额度(USD)',
82
82
  },
83
+ {
84
+ // AMD Radeon Cloud(Model API):DSH 非内置提供方,只允许「添加自定义提供方」(customOnly),
85
+ // Key 只存插件私有库。实测可用端点 = {baseUrl}/usage(文档页 /api/profile/model-usage 404,见 tmp 调研)。
86
+ // 返回今日剩余额度(pts)+ 今日/近24h/近30天/累计汇总 + 按模型拆分;无周/月窗口。
87
+ // AMD Radeon Cloud 分国内 / 国际两个版本:本条目 = 中国版(developer.amd.com.cn);国际版
88
+ // baseUrl/端点不同,预留位置——后续接入时新增一个 amd-radeon-usage-intl 适配器条目即可。
89
+ id: 'amd-radeon-usage',
90
+ displayName: 'AMD Radeon Cloud (中国)',
91
+ baseUrl: 'https://developer.amd.com.cn/radeon/api/v1',
92
+ usagePath: '/usage',
93
+ defaultCredentialRef: 'RADEON_API_KEY',
94
+ settingsProviderKey: null,
95
+ customOnly: true,
96
+ description: 'AMD Radeon Cloud (中国) Model API 用量/余额(今日剩余 pts + 时间窗口汇总)',
97
+ },
83
98
  ]
84
99
 
85
100
  /** 旧 provider id → 适配器 id(向后兼容 /api/provider-usage/opencode-go 与 query?provider=…)。 */
@@ -88,6 +103,9 @@ const LEGACY_PROVIDER_MAP = { 'opencode-go': 'usage-percent', 'deepseek-balance'
88
103
  /** Command Code 混合卡适配器(模块级常量,避免每次查询重复 find)。 */
89
104
  const COMMANDCODE_ADAPTER = ADAPTERS.find((a) => a.id === 'commandcode-credits') || null
90
105
 
106
+ /** AMD Radeon Cloud 余额卡适配器(模块级常量,避免每次查询重复 find)。 */
107
+ const AMD_RADEON_ADAPTER = ADAPTERS.find((a) => a.id === 'amd-radeon-usage') || null
108
+
91
109
  function isLoopbackRequest(req) {
92
110
  const addr = req.socket && req.socket.remoteAddress
93
111
  if (addr !== '127.0.0.1' && addr !== '::1' && addr !== '::ffff:127.0.0.1') return false
@@ -385,6 +403,95 @@ function parseCommandCodeCredits(creditsBody, subBody) {
385
403
  }
386
404
  }
387
405
 
406
+ // ── AMD Radeon Cloud(v0.10 调研新增):余额+配额卡 ─────────────────────
407
+ // 官方接口(实测):GET {baseUrl}/usage → 今日剩余 pts + 四个时间段汇总 + 按模型拆分。
408
+ // 无周/月窗口(文档页 /api/profile/model-usage 404;接入以实测 /usage 为准,见 tmp 调研)。
409
+ // 数据形态对齐 Command Code 混合卡:主数字 = 今日剩余百分比(3 位小数向下取整),
410
+ // 副行 = 已用/限额 + 剩余(单位 pts,等价 USD,网页用 pts 表述),单日窗口进度条。
411
+
412
+ /** 今日剩余百分比:钳制 [0,100] 后保留 3 位小数向下取整(与 commandcodeMonthlyRemainingPct 同语义)。 */
413
+ function amdRadeonRemainingPct(limitUsd, remainingUsd) {
414
+ const limit = Number(limitUsd)
415
+ if (!Number.isFinite(limit) || !(limit > 0)) return null
416
+ const remaining = Number(remainingUsd)
417
+ if (!Number.isFinite(remaining)) return null
418
+ const pct = Math.max(0, Math.min(100, (remaining / limit) * 100))
419
+ return Math.floor(pct * 1000) / 1000
420
+ }
421
+
422
+ /** 把 /usage 响应换算成结构化结果(余额 + 单日窗口 + 时间段/按模型汇总透传)。 */
423
+ function parseAmdRadeonUsage(body) {
424
+ let data = body
425
+ if (typeof data === 'string') {
426
+ try { data = JSON.parse(data) } catch { return { error: 'bad-json' } }
427
+ }
428
+ const limitUsd = data && data.daily_cost_limit_usd
429
+ const usedUsd = data && data.daily_cost_used_usd
430
+ const remainingUsd = data && data.daily_cost_remaining_usd
431
+ // 文档说 502 时汇总字段全 0 且 status 说明原因;字段缺失视为不可用
432
+ if (limitUsd === undefined || limitUsd === null || usedUsd === undefined || usedUsd === null || remainingUsd === undefined || remainingUsd === null) {
433
+ return { error: 'no-usage' }
434
+ }
435
+ const toNum = (v) => { const n = Number(v); return Number.isFinite(n) ? n : null }
436
+ const limit = toNum(limitUsd)
437
+ const used = toNum(usedUsd)
438
+ const remaining = toNum(remainingUsd)
439
+ const remainingPct = amdRadeonRemainingPct(limit, remaining)
440
+ const usedPct = (limit !== null && used !== null && limit > 0) ? Math.max(0, Math.min(100, (used / limit) * 100)) : null
441
+ const nextResetAt = typeof data.daily_reset_at === 'string' && data.daily_reset_at ? data.daily_reset_at : null
442
+ const periodStartedAt = typeof data.period_started_at === 'string' && data.period_started_at ? data.period_started_at : null
443
+
444
+ // 时间段汇总(today / last_24_hours / last_30_days / all_time 同构)→ 透传原始字段
445
+ const windowOf = (name) => {
446
+ const w = data && data[name]
447
+ if (!w || typeof w !== 'object') return null
448
+ return {
449
+ requests: w.requests,
450
+ errors: w.errors,
451
+ totalTokens: w.total_tokens,
452
+ promptTokens: w.prompt_tokens,
453
+ completionTokens: w.completion_tokens,
454
+ reasoningTokens: w.reasoning_tokens,
455
+ cachedTokens: w.cached_tokens,
456
+ kvCacheHitRate: w.kv_cache_hit_rate,
457
+ cost: w.cost,
458
+ lastRequestAt: w.last_request_at,
459
+ }
460
+ }
461
+
462
+ const extraParts = []
463
+ if (used !== null && limit !== null) extraParts.push('今日已用 ' + used.toFixed(3) + ' / ' + limit.toFixed(3) + ' pts')
464
+ if (remaining !== null) extraParts.push('今日剩余 ' + remaining.toFixed(3) + ' pts')
465
+ if (nextResetAt) extraParts.push('重置 ' + formatCountdown(nextResetAt))
466
+ if (data.rpm_limit !== undefined) extraParts.push('RPM ' + data.rpm_limit)
467
+
468
+ return {
469
+ planName: 'AMD Radeon Cloud (中国)',
470
+ remaining,
471
+ unit: 'pts',
472
+ used,
473
+ totalQuota: limit,
474
+ nextResetAt,
475
+ extra: extraParts.join(';'),
476
+ // 单日窗口:卡片只有一行进度条(对齐网页 "Today Used / Today Remaining / RPM Limit")
477
+ windows: {
478
+ daily: { usedPct, remainingPct, used, cap: limit, resetsAt: nextResetAt, periodStartedAt },
479
+ },
480
+ // 透传时间段汇总与按模型拆分(供副行/展开/本地统计对照)
481
+ periods: {
482
+ today: windowOf('today'),
483
+ last_24_hours: windowOf('last_24_hours'),
484
+ last_30_days: windowOf('last_30_days'),
485
+ all_time: windowOf('all_time'),
486
+ },
487
+ byModel: (Array.isArray(data.by_model) ? data.by_model : null),
488
+ recent: (Array.isArray(data.recent) ? data.recent : null),
489
+ cards: null,
490
+ isValid: true,
491
+ invalidMessage: null,
492
+ }
493
+ }
494
+
388
495
  // ── 插件主体 ────────────────────────────────────────────────────────
389
496
 
390
497
  export function apply(ctx, rawConfig) {
@@ -546,6 +653,9 @@ export function apply(ctx, rawConfig) {
546
653
  totalQuota: value.totalQuota,
547
654
  nextResetAt: value.nextResetAt,
548
655
  monthly: value.monthly,
656
+ periods: value.periods,
657
+ byModel: value.byModel,
658
+ recent: value.recent,
549
659
  extra: value.extra,
550
660
  windows: value.windows,
551
661
  cards: value.cards,
@@ -685,10 +795,14 @@ export function apply(ctx, rawConfig) {
685
795
  return fail(cfg, state, 'parse', '接口响应不是有效 JSON', res.status)
686
796
  }
687
797
 
688
- const parsed = cfg.id === 'balance-json' ? parseBalance(body) : parseUsage(body)
798
+ const parsed = cfg.id === 'balance-json'
799
+ ? parseBalance(body)
800
+ : (AMD_RADEON_ADAPTER && cfg.id === AMD_RADEON_ADAPTER.id ? parseAmdRadeonUsage(body) : parseUsage(body))
689
801
  if (parsed.error === 'no-usage') {
690
802
  recordSnapshot(key, { attemptAt, httpStatus: res.status, error: 'no-usage' })
691
- return fail(cfg, state, 'parse', '没有找到 OpenCode Go 用量数据', res.status)
803
+ return fail(cfg, state, 'parse', (AMD_RADEON_ADAPTER && cfg.id === AMD_RADEON_ADAPTER.id)
804
+ ? '没有找到 AMD Radeon Cloud (中国) 用量数据(daily_cost_*)'
805
+ : '没有找到 OpenCode Go 用量数据', res.status)
692
806
  }
693
807
  if (parsed.error === 'no-balance') {
694
808
  recordSnapshot(key, { attemptAt, httpStatus: res.status, error: 'no-balance' })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loommii/dsh-provider-usage",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "DSH 插件(用量中心):常驻用量卡片 · 多提供方用量/余额查询(OpenCode Go 订阅 + DeepSeek 余额 + Command Code 订阅/余额,对齐 cc-switch 查询语义)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",