🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

用量统计面板 Jockjrop/dsh-usage-stats

DeepSeek Harnessv0.2.7
Jockjrop4 天前有提交已提供中文文档扫描:含敏感能力

在 DSH 里,看清 Token 用量、账户余额与供应商配额。

35.9/100
综合分
3
GitHub 星标
984
npm 周下载
—/5
用户评分

数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @sligqoer/dsh-usage-stats
npm 源 · @sligqoer/dsh-usage-stats 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · tool
装得上吗
实装验证未通过(runtime_smoke_failed),装前请到仓库确认最近更新与 issue;本次验证针对插件 v0.2.5,当前版本为 v0.2.7,该结论可能已不适用
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 4 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(runtime_smoke_failed · 2026/10/28) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@sligqoer/dsh-usage-stats @ 0.2.7
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖要求 >=0.2.1-rc.1 <=0.2.1-rc.3 · 最新 0.2.1-rc.5 兼容
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 00:32:48

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 87 处,展示前 68 条)
  • 写入本地文件
    lib/index.js:396
    await mkdir(dirname(storePath), { recursive: true })
  • 写入本地文件
    lib/index.js:400
    await writeFile(tmp, JSON.stringify(state), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    lib/index.js:401
    await rename(tmp, storePath)
  • 读取本地文件
    lib/index.js:460
    const raw = await readFile(storePath, 'utf8')
  • 读取本地文件
    lib/index.js:499
    workspaces = await readdir(sessionsDir, { withFileTypes: true })
  • 读取本地文件
    lib/index.js:507
    entries = await readdir(join(sessionsDir, ws.name), { withFileTypes: true })
  • 读取本地文件
    lib/index.js:516
    st = await stat(join(sessionsDir, ws.name, entry.name, name))
  • 写入本地文件
    lib/index.js:1799
    await mkdir(dirname(seatDiagFile), { recursive: true })
  • 读取本地文件
    lib/index.js:1800
    const existing = await readFile(seatDiagFile, 'utf8').catch(() => '')
  • 写入本地文件
    lib/index.js:1803
    await writeFile(seatDiagFile, kept.join('\n') + (kept.length ? '\n' : '') + line, 'utf8')
  • 读取本地文件
    lib/index.js:1811
    const text = await readFile(seatDiagFile, 'utf8').catch(() => '')
  • 发起网络请求
    lib/client.js:1221
    return fetch('/api/dsh-usage-stats/stats' + (q ? '?' + q : ''), { headers: { accept: 'application/json' } }).then(readJson)
  • 发起网络请求
    lib/client.js:1231
    return fetch('/api/dsh-usage-stats/logs?' + search.toString(), { headers: { accept: 'application/json' } }).then(readJson)
  • 发起网络请求
    lib/client.js:1240
    return fetch('/api/dsh-usage-stats/costs?' + search.toString(), { headers: { accept: 'application/json' } }).then(readJson)
  • 发起网络请求
    lib/client.js:1252
    return fetch('/api/dsh-usage-stats/dashboard?' + search.toString(), { headers: { accept: 'application/json' } }).then(readJson)
  • 发起网络请求
    lib/client.js:1255
    return fetch('/api/dsh-usage-stats/prices', {
  • 发起网络请求
    lib/client.js:1260
    return fetch('/api/dsh-usage-stats/rules', { headers: { accept: 'application/json' } }).then(readJson)
  • 写入剪贴板
    lib/client.js:3767
    navigator.clipboard.writeText(text).then(done).catch(fallback)
  • 读取本地文件
    lib/usage-preferences.js:18
    try { text = await readFile(path, 'utf8') }
  • 读取本地文件
    lib/usage-preferences.js:21
    try { text = await readFile(legacyPath, 'utf8') } catch (legacyError) { if (legacyError.code !== 'ENOENT') throw legacyError }
  • 写入本地文件
    lib/usage-preferences.js:40
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/usage-preferences.js:41
    await writeFile(path + '.tmp', JSON.stringify({ version: 1, settings: next }), { mode: 0o600 })
  • 写入本地文件
    lib/usage-preferences.js:42
    await rename(path + '.tmp', path)
  • 写入本地文件
    lib/supplemental-usage.js:25
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/supplemental-usage.js:26
    await writeFile(path + '.tmp', text, { mode: 0o600 }); await rename(path + '.tmp', path)
  • 写入本地文件
    lib/supplemental-usage.js:26
    await writeFile(path + '.tmp', text, { mode: 0o600 }); await rename(path + '.tmp', path)
  • 读取本地文件
    lib/supplemental-usage.js:32
    try { document = JSON.parse(await readFile(path, 'utf8')); if (document.version !== 1 || !Array.isArray(document.records)) throw new Error('Invalid ca
  • 读取本地文件
    lib/supplemental-usage.js:35
    try { document = JSON.parse(await readFile(legacyPath, 'utf8')) } catch (legacyError) { if (legacyError.code !== 'ENOENT') throw legacyError; return }
  • 读取本地文件
    lib/quota-controls.js:251
    try { text = await readFile(path, 'utf8') }
  • 读取本地文件
    lib/quota-controls.js:255
    try { return { file, modified: (await fileStat(file)).mtimeMs } } catch { return null }
  • 读取本地文件
    lib/quota-controls.js:259
    text = await readFile(latest.file, 'utf8')
  • 写入本地文件
    lib/quota-controls.js:288
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/quota-controls.js:290
    await writeFile(temp, payload, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    lib/quota-controls.js:291
    await rename(temp, path)
  • 读取本地文件
    lib/price-overrides.js:29
    try { text = await readFile(path, 'utf8') }
  • 写入本地文件
    lib/price-overrides.js:58
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/price-overrides.js:60
    await writeFile(temp, JSON.stringify({ version: 1, prices }), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    lib/price-overrides.js:61
    await rename(temp, path)
  • 读取本地文件
    lib/model-rules.js:107
    try { text = await readFile(path, 'utf8') }
  • 写入本地文件
    lib/model-rules.js:118
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/model-rules.js:120
    await writeFile(temp, JSON.stringify({ version: 1, rules: next }), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    lib/model-rules.js:121
    await rename(temp, path)
  • 读取本地文件
    lib/model-detection-history.js:40
    const document = JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    lib/model-detection-history.js:78
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/model-detection-history.js:79
    await writeFile(path + '.tmp', document, { mode: 0o600 })
  • 写入本地文件
    lib/model-detection-history.js:80
    await rename(path + '.tmp', path)
  • 读取本地文件
    lib/lm-fingerprint-engine.js:11
    .map(url => fileURLToPath(url)).find(path => existsSync(join(path, 'UPSTREAM.json')))
  • 读取本地文件
    lib/lm-fingerprint-engine.js:46
    const info = await stat(join(directory, name))
  • 读取本地文件
    lib/lm-fingerprint-engine.js:56
    const manifest = JSON.parse(await readFile(join(directory, 'UPSTREAM.json'), 'utf8'))
  • 读取本地文件
    lib/lm-fingerprint-engine.js:67
    !/^[a-f0-9]{64}$/.test(digest) || hash(await readFile(join(directory, name))) !== digest) throw new Error('指纹引擎文件校验失败。')
  • 读取本地文件
    lib/lm-fingerprint-engine.js:116
    try { activeManifest = JSON.parse(readFileSync(join(fallback, 'UPSTREAM.json'), 'utf8')) } catch { warning = '内置指纹引擎不可用,请重新安装插件。'; warningKind = 'fata
  • 读取本地文件
    lib/lm-fingerprint-engine.js:130
    const pointer = JSON.parse(await readFile(join(cache, 'current.json'), 'utf8'))
  • 写入本地文件
    lib/lm-fingerprint-engine.js:169
    } else { await mkdir(dirname(destination), { recursive: true }); await rename(staging, destination) }
  • 写入本地文件
    lib/lm-fingerprint-engine.js:169
    } else { await mkdir(dirname(destination), { recursive: true }); await rename(staging, destination) }
  • 写入本地文件
    lib/lm-fingerprint-engine.js:171
    await mkdir(cache, { recursive: true })
  • 写入本地文件
    lib/lm-fingerprint-engine.js:174
    await rename(temporary, join(cache, 'current.json'))
  • 删除本地文件递归
    lib/lm-fingerprint-engine.js:180
    if (rel && !rel.startsWith('..') && !isAbsolute(rel)) await rm(staging, { recursive: true, force: true }).catch(() => {})
  • 写入本地文件
    lib/lm-fingerprint-engine.js:183
    try { await mkdir(cache, { recursive: true }); await writePointer(temporary, { checkedAt, warning }); await rename(temporary, join(cache, 'check.json'
  • 写入本地文件
    lib/lm-fingerprint-engine.js:183
    try { await mkdir(cache, { recursive: true }); await writePointer(temporary, { checkedAt, warning }); await rename(temporary, join(cache, 'check.json'
  • 删除本地文件
    lib/lm-fingerprint-engine.js:184
    catch { await rm(temporary, { force: true }).catch(() => {}) }
  • 发起网络请求
    lib/lm-fingerprint-source.js:20
    downloadAgent ||= new EnvHttpProxyAgent()
  • 发起网络请求
    lib/lm-fingerprint-source.js:21
    return undiciFetch(url, { ...init, dispatcher: downloadAgent })
  • 发起网络请求
    lib/lm-fingerprint-source.js:23
    return globalThis.fetch(url, init)
  • 写入本地文件
    lib/lm-fingerprint-source.js:151
    await mkdir(join(directory, parts), { recursive: true })
  • 写入本地文件
    lib/lm-fingerprint-source.js:152
    await writeFile(join(directory, name), bytes)
  • 写入本地文件
    lib/lm-fingerprint-source.js:154
    await writeFile(join(directory, 'UPSTREAM.json'), JSON.stringify(manifest, null, 2) + '\n')
  • 读取本地文件
    lib/lm-fingerprint-worker.js:10
    const bank = JSON.parse(await readFile(join(root, 'data', 'unified_bank.json'), 'utf8'))
  • 读取本地文件
    lib/lm-fingerprint-worker.js:11
    const detector = codec.decodeDetector(await readFile(join(root, 'data', 'shared_detector.bin')))
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 查看Token用量
  • 账户余额与订阅配额
  • 用量热力图与24小时图表

DSH 网页界面的 token 用量统计:用量统计设置页,含用量热力图、24 小时 token 图表、按模型细分。外部打包补丁,不改 DSH 源码。

v0.2.82026-10-30
· 本次更新 / 更新内容 简体中文 · English · 🐛 问题修复 · 适配 DSH Desktop 0.2.1-rc.5,兼容范围改为 >=0.2.1-rc.1。 · 修复在 DSH Desktop 0.2.1-rc.4 与 0.2.1-rc.5 上「用量统计」不再出现在设置页、侧栏入口与仪表盘的问题。 English · 简体中文 · 🐛 问题修复 · 支持 DSH Desktop 0.2.1-rc.5,兼容范围 >=0.2.1-rc.1。 · 修复了在 DSH Desktop 0.2.1-rc.4 与 0.2.1-rc.5 上「用量统计」从设置页、侧栏快捷入口和仪表盘消失的问题。
v0.2.72026-10-29
· 本次更新 简体中文 · English · ✨ 新增与改进 · 用量统计的柱状图按模型分色,同一个模型在任何图表里颜色一致。 · 鼠标停在柱子上,除了这一段的总量,还能看到每个模型各用了多少。 · 柱子也能用键盘逐个聚焦、用触摸点按查看,读屏软件能读到每根柱子的数值。 · 近 7 天这类段数少的图表,柱子不再粗到糊成一片。 · 兼容 DSH Desktop >=0.2.1-rc.1 English · 简体中文 · ✨ 新增与改进 · 仪表盘柱子按模型分色,同一个模型在任何图表里颜色一致。 · 鼠标停在柱子上,除了这一段的总量,还能看到每个模型各用了多少。 · 柱子能用键盘逐个聚焦、在触摸屏上点按查看,读屏软件能读出每根柱子的数值。 · 段数少的图表,比如近 7 天,柱子不再粗得糊成一片。 · 兼容 DSH Desktop >=0.2.1-rc.1 <=0.2.1-rc.3(0.2.1-rc.1、0.2.1-rc.2 和 0.2.1-rc.3)。 · 🐛 问题修复 · 修复了刷新后不显示新数据、要重新选一次时间范围才出现的问题。 · 修复了「费用」标签页开着过了午夜或进入新的月份后,悄悄不再纳入新数据的问题。 · ⚡ 性能 · 仪表盘刷新从约 1.6 秒降到约 40 毫秒(用 67 个会话测得)。
v0.2.62026-10-28
· 本次更新 简体中文 · English · ✨ 新增与改进 · 新增「日志」页:按时间倒序查看每次请求的应用、服务商、模型、成本、输入/输出/缓存 token、输出速度与首字耗时,支持服务商/模型筛选、每页行数、翻页和刷新。 · 新增「成本」页与价格表:按内置价格表和自定义单价折算成本,展示总成本、区间成本、区间 token 与逐模型汇总;可为未收录或价格变动的模型维护输入、输出、缓存读写单价(美元/百万 token),保存后立即反映到成本与日志。 · 新增「规则」页:把同一模型的不同原始名称归并为一个名称,用量、日志和成本统一按归并后的名称统计;支持新增、编辑、移除,最多 1000 条并阻止循环归并。 · 新增侧边栏「用量统计」仪表盘:四张指标卡(成本、请求数、真实 token、缓存命中率),按小时、天、月展示柱状图,选择「全部」时切换为 53 周热力图;内置请求日志、服务商/模型筛选、每页行数与翻页。 · 新增日期范围选择器:仪表盘与成本页使用同一套预设、月历和起止日期控件;仪表盘额外支持具体时间与「结束时间跟随当前时刻」,成本页按天选择。 · 新增「快速上手」:右上角按钮打开左侧目录、右侧说明的引导窗口,按当前启用的模块介绍每个页面和按钮的用法。 · 新增「问题反馈」按钮与「控制」页顶部的 GitHub Star 提示,可直接前往 Issues 和仓库。 · 下拉框统一为自绘组件,支持键盘搜索、状态点、来源提示与主题色选择;悬浮提示改为跟随鼠标的圆角气泡,替换系统原生 tooltip,靠近窗口边缘自动翻转。 · 统一分叉会话、保留会话、检测用量与名称归并后的统计口径,token、成本与速度不再重复或遗漏。 · 新页面、错误提示与动态文案补齐中文、英语、日语翻译。 · 兼容 DSH Desktop >=0.2.1-rc.1 <=0.2.1-rc.3(0.2.1-rc.1、0.2.1-rc.2 和 0.2.1-rc.3)。 · 🐛 问题修复 · 修复后台语料同步运行时仪表盘请求被阻塞、偶尔卡住的问题:仪表盘现在直接返回热快照,只有手动刷新才等待同步。 · 修复设置面板中成本页日期范围浮层滑到侧边栏下方、日期字段和日历第一列被裁切的问题。 · 修复检测、配额、成本、规则和日志 API 的错误在英语和日语界面仍显示中文的问题。 · 统一成本页与仪表盘日期范围控件的样式和行为。 · ⚡ 性能与稳定性 · 仪表盘读取走热缓存,后台增量同步;打开、筛选和翻页不再等待会话扫描。 · 悬浮提示在绘制帧内定位,避免布局读取让密集图表显得卡顿。 · 价格覆盖和名称规则分别持久化到独立文件,仅所有者可读写(0600);两者上限均为 1000 条,写入前校验非法值、重复和循环。 · 模型名称解析按原始名称缓存结果,避免每个事件重复计算。 · 仪表盘「全部」区间复用 53 周热力图聚合,不再对同一份数据折叠两次。 · 🧰 工具链 · 测试套件现有 181 个测试,覆盖定价、规则、请求日志、成本分桶、仪表盘、时区、分叉会话和速度统计。 · 发布检查继续扫描工作区中的私有文件、校验第三方完整性并验证干净安装;新增的设置文件同样仅所有者可保存。
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-usage-stats 在 DSH 里,看清 Token 用量、账户余额与供应商配额。 为 DeepSeek Harness 桌面端打造的本地用量面板。 下载 ·功能 ·安装 ·使用 ·常见问题 ·更新日志 ·反馈问题 看清今日与累计用量、当日走势、热力图和模型输出速度。 逐次核对每次请求的 Token、费用与速度。 按模型查看区间花费,补齐未收录模型的价格。 把同一模型的多种名称归并成一条统计。 集中查看供应商余额、账号积分与周期额度。 确认预算后运行检测,查看候选排名与已发生用量。 开关各模块,调整模型选择、主题色与自动刷新。 从侧栏打开仪表盘,快速查看区间成本、趋势和最近的请求日志。 功能 | 页面 | 你可以做什么 | | 用量 | 查看今日与累计 Token、使用天数、小时调用次数、每日/每周热力图、趋势、模型明细与输出速度。 | | 日志 | 按时间查看每次请求的应用、供应商、模型、成本、Token 与速度,支持筛选和翻页。 | | 成本 | 按价格表折算成本,查看总成本、区间成本、区间 Tokens 与逐模型花费,可维护自定义单价。 | | 规则 | 将同一模型的不同原始名称归并为一个名称,让用量、日志和成本统一统计。 | | 配额 | 集中查看供应商余额、账号积分与周期配额,支持手动或定时刷新及自定义查询。
展开完整文档(README 剩余 1 节)
dsh-usage-stats

在 DSH 里,看清 Token 用量、账户余额与供应商配额。
为 DeepSeek Harness 桌面端打造的本地用量面板。

下载 ·功能 ·安装 ·使用 ·常见问题 ·更新日志 ·反馈问题

看清今日与累计用量、当日走势、热力图和模型输出速度。

逐次核对每次请求的 Token、费用与速度。
按模型查看区间花费,补齐未收录模型的价格。

把同一模型的多种名称归并成一条统计。
集中查看供应商余额、账号积分与周期额度。

确认预算后运行检测,查看候选排名与已发生用量。
开关各模块,调整模型选择、主题色与自动刷新。

从侧栏打开仪表盘,快速查看区间成本、趋势和最近的请求日志。

功能

| 页面 | 你可以做什么 |
| 用量 | 查看今日与累计 Token、使用天数、小时调用次数、每日/每周热力图、趋势、模型明细与输出速度。 |
| 日志 | 按时间查看每次请求的应用、供应商、模型、成本、Token 与速度,支持筛选和翻页。 |
| 成本 | 按价格表折算成本,查看总成本、区间成本、区间 Tokens 与逐模型花费,可维护自定义单价。 |
| 规则 | 将同一模型的不同原始名称归并为一个名称,让用量、日志和成本统一统计。 |
| 配额 | 集中查看供应商余额、账号积分与周期配额,支持手动或定时刷新及自定义查询。 |
| 检测 | 独立选择服务商和模型,确认预算后运行 LM Fingerprint 检测,查看请求进度、采样状态、候选排名与历史结果。 |
| 控制 | 调整展示偏好、配额查询设置、高级模型选择器与逐模型推理强度。 |

- 看清使用趋势:按日/周浏览热力图,切换 7/30 天趋势,按服务商与模型查看用量。
- 侧边栏仪表盘:从侧栏打开「用量统计」,切换成本、请求数、真实 Tokens 与缓存命中率,按小时、天、月或 53 周热力图查看,并内置请求日志、筛选与翻页。
- 快速上手与反馈:右上角「快速上手」按页面介绍用法,发送图标直达 GitHub Issues;「控制」页顶部可直接前往仓库点 Star。
- 比较输出速度:按 TPS 排序,显示平均首 Token 耗时(TTFT);缺少有效时间记录的样本不参与速度排名。
- 按需刷新配额:通过 DSH 凭据服务查询已配置服务商,账号配额需要对应的账号插件或宿主服务。自动查询默认关闭。
- 统一数值单位:大数值统一以 k / M / B 显示,中英日界面读法一致。
- 独立运行检测:按步骤选择模型、确认预算并查看结果;默认采样 3 次,也可选择 1 次初筛,支持进度查看、取消、超时和用量预算控制。
- 调整模型设置:分别控制高级模型选择器与模型推理强度,保留已有的模型属性、参数映射和个人设置。
- 跟随应用语言:支持中文、英语和日语,随 DSH 所选语言切换;用户自定义名称与配额标签保持原样。

检测通过随机数样本与参考库对照。排名和库内置信度表示与已知候选的接近程度,不能证明模型身份或能力。读取模型目录、预算和历史结果不会启动推理。

安装

当前插件版本为 0.2.8,适配 DSH Desktop 0.2.1-rc.5,兼容范围为 >=0.2.1-rc.1。版本不匹配时,宿主插件管理器会拒绝安装或启用。

推荐通过 DSH Desktop 安装 npm 包 @sligqoer/dsh-usage-stats。 已包含预构建模块,无需克隆仓库或在本机构建;通过包名安装后可使用插件页的「检查更新」。

1. 打开插件安装入口

在 DSH Desktop 主界面侧栏进入 插件 → 添加插件。

2. 填入完整 npm 包名

@sligqoer/dsh-usage-stats

将包名粘贴到 包名或地址,点击 安装,保留完整的 @sligqoer/ 前缀。

3. 启用并打开面板

点击 立即启用,进入 设置 → 用量统计。插件管理器提示需要重启时,完全退出并重新打开 DSH Desktop。

安装指定版本或已下载的压缩包

安装本次版本时,在同一入口填入:

@sligqoer/dsh-usage-stats@0.2.8

也可从 GitHub 发布页下载 .tgz 安装包和 SHA256SUMS,校验后填入压缩包的本地绝对路径,无需解压。

Get-FileHash ./sligqoer-dsh-usage-stats-0.2.8.tgz -Algorithm SHA256

发布附件包含版本安装包 sligqoer-dsh-usage-stats-0.2.8.tgz、通用安装包 dsh-usage-stats.tgz 和校验文件 SHA256SUMS;两个安装包内容一致。

更新与迁移

通过 npm 包名安装的用户可在插件页使用「检查更新」。通过 GitHub 地址、压缩包或本地路径安装的用户,需要下载新版重新安装。

使用旧包名 dsh-usage-stats 的用户,先卸载旧包,再安装 @sligqoer/dsh-usage-stats。更新保留本地配置与用量数据;升级记录见 CHANGELOG.md。

使用

1. 在「用量」查看概览、趋势、热力图和输出速度;侧栏「用量统计」可直接打开仪表盘。
2. 在「日志」按服务商、模型筛选每次请求;在「成本」选择日期范围查看花费并维护价格表;在「规则」把同一模型的不同名称归并为一个名称。
3. 在「配额」点击服务商或账号卡片的刷新按钮。自动查询默认关闭,可在「控制」确认提示后开启。
4. 在「检测」选择服务商与模型,设置采样次数和输出上限,点击「查看检测预算」,确认后点击「开始检测(会消耗 Token)」。读取目录或历史结果不会启动检测。
5. 在「控制」分别开启或关闭高级模型选择器、模型推理强度和模型检测,编辑自定义配额查询;右上角「快速上手」可查看各页面说明。

检测页按「选择检测模型 → 确认预算 → 检测结果」提示当前步骤。更改模型或参数后,需要重新查看预算;检测中可查看请求进度、逐次采样状态并取消。历史结果保留原模型与参数,检测详情和指纹引擎信息可按需展开。

数据与兼容

本地数据位于 DSH_HOME/storages:

| 文件或目录 | 内容 |
| usage-stats-corpus.json | 会话用量汇总。 |
| usage-stats-display.json | 用量展示偏好。 |
| usage-stats-quota-controls.json | 查询和模型设置、服务商配额缓存。 |
| usage-stats-prices.json | 模型自定义单价(美元/百万 Tokens)。 |
| usage-stats-rules.json | 模型名称归并规则。 |
| usage-stats-detections.json | 检测结果与逐次样本用量。 |
| usage-stats-lm-fingerprint/ | 通过校验的指纹引擎与参考库更新。 |
| usage-stats-supplemental.json | 按任务和样本 ID 去重的检测用量,重启后保留。 |

普通对话从 DSH 会话日志计数,检测用量按任务和样本 ID 去重后计入统计。请求诊断日志不参与 Token 汇总。更新会保留已保存的配置与历史用量。上述文件在支持的平台上以仅当前用户可读的权限写入。
从 0.2.0 升级后,模型检测改用 LM Fingerprint,不再提供旧版行为参考、KBF 导入/导出和能力基线测试;已发生的检测用量继续保留。发布安装包不包含个人会话、账号凭据、配额缓存或检测历史;本地缓存以仅当前用户可读的权限写入。

常见问题

支持 DSH Web 吗?

当前版本仅支持 DSH Desktop 的 desktop profile。

为什么配额卡片不显示或无法获取?

先确认供应商已配置、凭据可用、账号插件已启用且账户支持对应配额接口。普通模型 API Key 可能没有账单查询权限。

Token 总数就是账单金额吗?

不是。Token 统计来自本地会话和已上报的检测用量,账户余额与周期额度来自供应商接口。

检测排名能证明真实模型身份吗?

不能。候选排名表示与参考库的接近程度;请求模型不在参考库时,候选仅供比较。

接口

宿主服务 dshUsageStats 使用 protocolVersion: 1,提供 readStats、readControls、updateControls、readProviderQuotas 和 readSupplementalUsage。

HTTP 接口使用 /api/dsh-usage-stats/*,提供统计、控制、配额查询与检测功能,仅接受本机与可信来源请求,并禁用缓存。

开发

使用 Node.js 22 或更高(开发与 CI 使用 24),并安装 package-lock.json 锁定的依赖:

npm ci
npm run lint
npm run build
npm test
npm run check:release
npm run release

修改 src/ 后运行 npm run build 生成 lib/。src/client.js 是渲染器模板,client-messages.js、client-styles.js、client-format.js 等模块由构建按标记内联,发布产物仍是单个 lib/client.js。npm run lint 校验语法、JSON 文档与三语条目;npm run check:release 检查版本、构建一致性、第三方完整性与工作区隐私文件;npm run release 构建安装包并在独立临时项目中验证安装与加载,输出位于 release/。

GitHub 发布流程要求标签与包版本一致(本版为 v0.2.8),通过检查后使用同一份安装包发布 npm 与 GitHub Release。npm 可信发布对应的工作流文件为 .github/workflows/release.yml。第三方资源、来源版本和许可记录于 third_party/ 与 NOTICE,本项目使用 Apache-2.0 许可证。
预览分享卡片长什么样 ↓Jockjrop/dsh-usage-stats
分享 · DeepSeek Harness Hub
Jockjrop/dsh-usage-stats

在 DSH 里,看清 Token 用量、账户余额与供应商配额。

回到顶部