Bundle
@kongjianguan/dsh-tokstat
dsh usage & performance statistics: settings-panel plugin + TUI (tokens / TTFT / TPS / cost)
- Source
- kongjianguan
- License
- MIT
- Updated
- Updated 14 days ago
Readme
# dsh-tokstat <p align="center">读取 DeepSeek Harness (dsh) 会话日志的实时使用量与性能 TUI 统计面板 —— Tokens / TTFT / TPS / 成本一屏看全</p> <p align="center"> <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a> <a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/dsh-plugin-ecosystem-purple.svg" alt="dsh plugin"></a> </p>    ## Overview dsh-tokstat 直接读取 dsh 的会话日志(`~/.dsh/sessions/**/session.jsonl.zstd`, zstd 帧级增量解析),把散落在多个会话文件里的每一次 LLM 请求还原成可分析的 指标:**输入/输出/缓存 Tokens、TTFT(首 token 时延)、TPS、耗时、重试与失败、 估算成本**。 项目提供两种形态: - **dsh 设置面板插件**:在 dsh Web 设置页增加「统计」section,实时展示概览 / 模型 / 会话 / 请求,2s 轮询; - **Python TUI**:独立终端仪表盘(7 个视图,`o t m p s r e` 切换)。 适合谁: - 想了解自己每天在 dsh 上花了多少 token / 钱的用户; - 想评估模型与供应商性能(TTFT、TPS 分布)的用户; - 想排查重试、失败步骤的 agent 重度用户。 7 个视图(`o t m p s r e` 切换): | Tab | 内容 | |---|---| | 总览 | 请求数 / 总 Tokens / 平均 TTFT(TPS)(含 p50·p95)/ 成功率 / 缓存命中率 / 成本 / 耗时 Hero 卡 + Tokens 构成条 + 4 条实时火花线 + Top 模型/会话 | | 趋势 | 按小时/天(`h`/`d`)的柱状图:请求数、Tokens(输入+缓存 vs 输出)、平均 TTFT(绿≤5s/黄≤120s/红>120s)、平均 TPS | | 模型 / 供应商 | 各模型/供应商的用量、缓存命中率、TTFT 中位+p95、TPS、重试、成本,点击表头排序 | | 会话 | 每个会话的用量/性能/成本/用户消息/最后活动;点击行可查看单会话详情 | | 请求 | 逐条请求日志(1200 条上限),`f` 过滤,点击表头排序 | | 错误 | 重试原因分布(TRANSPORT/SERVER/TIMEOUT…)、逐条重试事件、失败步骤 | 指标设计参考了 cc-switch 的用量统计、new-api 与 sub-api 的数据看板,指标口径与 dsh 官方 `sessionStats` 投影一致(见 [指标定义](#指标定义))。 ## Compatibility - 数据格式基于 **dsh 0.1.0-rc.6** 的会话日志结构验证(2026-08-15),并已与 服务器端 `session_projcache.json` 投影交叉验证(llmMs/decodeTokens 精确相等, TTFT 误差 <10%;历史验证 <2%,个别新日志批量 chunk 近似可达 ~9%)。 - 插件形态:Node half 需要 **Node ≥ 23.6**(dsh 运行时 Node 26 已验证);client 面板运行在 dsh Web 设置页;peerDependencies 声明了 `@deepseek-ai/*` 版本范围。 - TUI 形态:**Python 3.11+**;依赖 textual ≥8.0、zstandard ≥0.23、PyYAML。 - 会话日志格式由 dsh 演进决定;若升级 dsh 后发现读取异常,请到仓库反馈。 ## Install / Uninstall ### 方式一:dsh 设置面板插件(推荐) 从 Git 仓库安装到指定 profile(例如 `web-dev`): ```bash dsh plugin --profile web-dev add https://github.com/kongjianguan/dsh-tokstat.git # 启动 dsh Web dsh --profile web-dev --port 3199 ``` 安装后打开 `http://127.0.0.1:3199/`,进入 **设置 → 统计** 即可看到面板。 插件数据通过 `/tokstat/stats` 由 dsh 进程内的 Node half 提供,无需额外服务。 本地开发安装: ```bash dsh plugin --profile web-dev add /path/to/dsh-tokstat # 或使用仓库内辅助脚本(自动写 package.json + 建 node_modules 链接) node scripts/link-profile.mjs --profile web-dev ``` 卸载: ```bash dsh plugin --profile web-dev remove @kongjianguan/dsh-tokstat ``` ### 方式二:Python TUI ```bash git clone https://github.com/kongjianguan/dsh-tokstat.git cd dsh-tokstat ./run.sh # 自动创建虚拟环境并安装依赖(等价于下方手动步骤) ``` 或手动: ```bash python3 -m venv .venv .venv/bin/pip install -r requirements.txt .venv/bin/python main.py ``` TUI 升级: ```bash git pull .venv/bin/pip install -r requirements.txt # 依赖有变更时 ``` TUI 卸载: ```bash rm -rf dsh-tokstat # 工具无后台进程、无系统级安装、无写出的数据文件 ``` ## Quick start ### dsh 设置面板插件 ```bash dsh plugin --profile web-dev add https://github.com/kongjianguan/dsh-tokstat.git dsh --profile web-dev --port 3199 # 浏览器打开 http://127.0.0.1:3199/ → 设置 → 统计 ``` ### Python TUI ```bash ./run.sh # 默认范围:全部 ./run.sh --range today # 只看今日 ./run.sh --refresh 5 # 降低刷新频率 ``` 示例输出(总览页核心指标): ```text 请求数 2,431 总 Tokens 384.33M 平均 TTFT 17.3s 平均 TPS 1889.9 成功率 99.6% 缓存命中率 98.8% 估算成本 ¥84.45 平均耗时 24.1s ``` 快捷键: | 键 | 作用 | |----|------| | `o t m p s r e` | 切换 总览/趋势/模型/供应商/会话/请求/错误 | | `1 2 3 4` | 时间范围:全部 / 今日 / 近7天 / 近30天 | | `h d` | 趋势粒度:小时 / 天 | | `f` | 聚焦请求日志过滤框(`Esc` 退出) | | `space` | 暂停 / 继续自动刷新 | | `Ctrl+R` | 立即刷新 | | `q` | 退出 | ## Configuration 全部通过命令行参数与一个 YAML 文件配置,无环境变量依赖: | 参数 / 文件 | 说明 | |---|---| | `--home PATH` | dsh 数据目录(默认 `$DSH_HOME` 或 `~/.dsh`) | | `--refresh SECONDS` | 轮询刷新间隔(默认 2) | | `--range all\|today\|7d\|30d` | 初始时间范围(默认 all) | | `--prices PATH` | 价格表 YAML 路径(默认项目内 `prices.yaml`) | `prices.yaml` 按**每百万 token** 定价(¥),内置 DeepSeek v4 官方价格,可增删: ```yaml deepseek-v4-flash: input: 1.00 # 每百万输入 token output: 2.00 # 每百万输出 token cacheRead: 0.20 # 每百万缓存命中 token ``` 模型 ID 自动归一化(去 `owner/` 前缀、去 `:后缀`、`@`→`-`、去日期后缀), `deepseek-v4-flash-0731` 先精确匹配、再逐级缩短匹配。未定价模型成本显示 `-`。 ## Permissions & data - **只读**:TUI 仅读取 `~/.dsh/sessions/` 下的会话日志(`session.jsonl.zstd`)与 `~/.dsh/settings.yaml`(用于定位数据目录);插件由 dsh 进程内的 Node half 通过 `sessionPersistence` 读取同一份会话日志;**不修改任何 dsh 数据**。 - **不联网**:TUI 全程离线运行;插件 client 面板只访问本机 dsh Web 的 `/tokstat/stats`,无遥测、无上报。 - 价格表与自定义参数仅存于本地文件;不会读取或上传你的 API 密钥。 - 插件 client 面板运行在浏览器,不直接接触文件系统;所有数据由 Node half 聚合后 通过本机 HTTP 提供。 - 会话日志包含对话内容;请勿将包含敏感对话的 `~/.dsh` 目录提交到任何仓库。 ## Troubleshooting | 现象 | 处理 | |---|---| | 启动后"暂无数据" | 确认 `--home` 指向正确(默认 `~/.dsh`),检查 `sessions/` 下是否有 `session.jsonl.zstd` | | 升级 dsh 后解析报错/数字异常 | 会话日志格式可能变化;提交 issue 并附 dsh 版本 | | TTFT 偏大 | 口径为 `step/start → 首 token`,含排队/思考时间,请以 p50/p95 为准 | | 刷新卡顿 | 降低 `--refresh`(如 5s);数据量大时总览/请求页重建较慢 | | 成本数字与账单不符 | 成本为估算;中转渠道请在 `prices.yaml` 配置实际价格 | | 设置页没有「统计」section | 确认 profile 已 `dsh plugin --profile <name> add` 本插件,并重启 dsh Web | | `/tokstat/stats` 404 | 插件未加载或该 profile 未启用 webServer;检查 boot 日志 | ## Development > 本项目的插件开发规范、设置面板扩展机制(`settings.section` slot)与收录条件 > 对照,见 [docs/plugin-development/](docs/plugin-development/README.md)。 ### 结构 ``` dsh-tokstat/ ├── index.mjs # Node half:Cordis 插件入口(/tokstat/stats) ├── src/client/index.js # client half 源码(设置面板 React) ├── lib/client.js # client bundle 产物 ├── src/host/ # Node half 聚合(fold/aggregate/pricing TS) ├── tui/ # Python TUI(独立可用) │ ├── main.py │ └── dshstats/ ├── scripts/ # build-client / gate / panel-harness / cdp-shot └── docs/ ``` TUI 内部结构: ``` tui/dshstats/ store.py zstd 帧扫描 + 增量 tail + 事件折叠(与 dsh 官方投影同口径) metrics.py 聚合:summary / 时间桶 / 分组 / 百分位 pricing.py 价格表 + 模型名归一化 ui/ textual 界面(7 个 tab + SortableTable/Bars/StatCard 组件) ``` ### 插件构建与门禁 ```bash pnpm install # 首次安装依赖(已提交 lockfile) pnpm run build:host # Node half → dist/index.mjs(esbuild 打包 TS) pnpm run build:client # 同步 lib/client.js pnpm gate # 结构门禁 + 三方对账 + 行为测试 pnpm gate --ci # CI/无真实 dsh 数据时:跳过三方对账,仍跑结构门禁 + 行为测试 ``` 不安装依赖也可直接跑(脚本只用 Node 内置能力/已提交 dist): ```bash node scripts/build-host.mjs # Node half → dist/index.mjs(需要 esbuild,已装则可用) node scripts/build-client.mjs # 同步 lib/client.js node scripts/gate.mjs # 结构门禁 + 三方对账 + 行为测试 ``` 改 client 后建议跑无头 Chrome 回归: ```bash node scripts/panel-harness.mjs --port 3320 # 另开 Chrome --headless=new --remote-debugging-port=9222 node scripts/cdp-shot.mjs "http://127.0.0.1:3320/" 8000 --click "请求" ``` ### 测试与验证 - 插件数据正确性:`node scripts/gate.mjs` 会跑 TS/Python/官方 projcache 三方对账。 - TUI 无头功能测试:`App.run_test()` + Pilot 模拟按键/切 tab;`app.save_screenshot()` 导出 SVG 核对布局。 - 数据正确性:解析结果与 `~/.dsh/storages/session_projcache.json` 中官方 `sessionStats` 投影交叉对比(llmMs/decodeTokens 应精确相等,TTFT <10%)。 - 贡献:fork + PR 即可;改动涉及事件折叠时请在 PR 中附交叉验证结果。 ## License & security - 本项目以 **MIT** 许可发布(见 [LICENSE](LICENSE))。 - 安全问题请通过 GitHub issue 私下说明(避免在公开 issue 中粘贴密钥或会话内容), 或直接邮件仓库维护者。 ## 指标定义 与 dsh 官方 `sessionStats` 投影一致: | 指标 | 定义 | |------|------| | 请求数 | `assistant/message` 事件数(一次组装完成的 LLM 调用) | | 输入/输出/缓存 Tokens | `usage` 的 `inputTokens` / `outputTokens` / `cacheReadTokens` | | TTFT | `step/start` → 第一个非空 token delta;持久化日志缺失逐条 delta 时由批量 `*-chunks` 的 `dt` 近似(误差 <10%) | | TPS | 输出 Tokens / 解码秒数 | | 成功率 | 请求数 / (请求数 + 失败步骤数) | | 缓存命中率 | 缓存读取 / (输入 + 缓存读取) | | 成本 | 按 `prices.yaml` 估算 | ## 已知限制 - TTFT 定义与 dsh 官方一致,含排队/思考时间,长尾明显——请以 p50/p95 为准。 - 部分会话的持久化日志只有批量 chunk(`*-chunks`),TTFT 为近似值(历史误差 <2%,个别新日志可达 ~9%)。 - 成本为估算,中转渠道价格请自行配置。 - TUI 形态是独立 Python 程序;仓库根同时提供 dsh 设置面板插件(Node half + client bundle),两者共享同一套指标口径。
Install
dsh plugin --profile web add github:kongjianguan/dsh-tokstat
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install kongjianguan-dsh-tokstat from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.