Overview
@fufuf-c/dsh-token
README / EN
Package documentation
Registry summary
dsh.pub verifies the pinned bundle contract, runtime facts, and distribution semantics. The complete README remains in the source repository.
Read the full README on GitHubLIMITATIONS
Known limitations
- 规模上限参考(20 万请求 / 400 会话 / 120 模型的合成库,Node 24,2026-09 实测): 落盘 = `store.json` 元数据约 **142 KB** + `shards/` 约 **10 MB**(逐会话一个分片), 请求记录全量驻留内存,**堆占用约 59 MB**; 冷启动 `JSON.parse` + 分片载入约 0.12 s,`rebuildAll` 约 0.42 s; **0.9.5 起,有会话变更的扫描周期只重折被改动的会话**(unfold 旧列表 + fold 新列表), 不再整库重折,同时**只重写变化的分片** (改 2 个会话时约 0.19 s 的写量,而 0.8.x 是整库 19.98 MB / 0.17 s)。 端到端实测(真实 `scanStore` 路径,6 万请求 / 200 会话): **改 2 个会话 2.7 ms,而整库重折 71.6 ms(约 27×)**;无变化仍是 0.2 ms。 两条路都会在 `summary.aggMode` 里如实报出(`full` / `incremental` / `none`)。 冷启动与"聚合不可用"仍走整库重折 —— 没有旧账可减时增量只会多做一轮簿记。 稳态增量扫描实测 **34-52 ms**(无变化时只 list 一遍比对 revision,不解码任何会话), 冷启全量约 2.1 s;扫描周期可用 `refresh.scanSec` 调整或关掉(`0`)。 默认 `retention.days=0` 永久保留,长期大库建议开启保留期 (如 `{"retention":{"days":365}}`)控制体积 —— 开启后稳态扫描是零写放大的。 **`store.json` 的体积随会话数线性增长**(它每个脏周期整体重写):本机 64 会话约 32 KB, 即每会话约 0.5 KB;数千会话时该文件会到 MB 级,这是选分片布局换来的代价,已记录在案。 **分片布局的取舍**:单会话损坏只影响一个分片(其余照旧,该会话下轮从日志重折), 代价是文件数为**会话数**(数千会话即数千个小文件)。逐请求导出(JSON)另有 10 万行上限, 超过会拒绝(见路由表); - **`store.json` 不再含逐请求记录(0.9.0 起)**:它是**元数据 + 索引**,记录在 `shards/*.json`。备份时请连 `$DSH_HOME/dsh-token/` **整个目录**一起备份 (只备份 `store.json` 会丢掉全部用量记录,只留下配置与标题); - **逐请求 JSON 导出的行数上限是 10 万条**:20 万条会生成 68 MB 单个响应体,足以卡死 标签页。需要全量请缩小时间范围,或开启保留期; - `cost/saved/priced` 是**普通数据属性**,不是访问器(0.8.9 起):改完单价/时段后,下一次 **查询**就会用新价(所有查询入口与落盘前都先 flush),但直接读 `store.requests[id][i].cost` 的代码需要自己先 `flushAggregates(store)`; - 通过**域名**反代访问仪表盘时,设置类 POST 会被拒绝(防 DNS rebinding 的代价):Host 白名单只放行回环名、私网/链路本地/CGNAT/唯一本地 IP 与回环 IPv6,**域名与公网 IP 字面量一律拒绝**。私网 IP 直连(如 `http://192.168.1.5:3080`)与 `curl`(无 `Origin`)可用; - 仪表盘价格估算内置 **DeepSeek 官方价目**(¥/M),按官方页口径分档并区分时段 —— 见下方「价格口径」。**只有 DSH 内置官方模型(`deepseek-official`)套用该价目;中继/自建/第三方 路由一律无内置价**,成本计 0,需手动为它们录入自定义单价。未定价部分**不会被藏起来** —— `kpi.totals.unpricedTokens` / `unpricedModelCount` 显式给出,单价表显示"未定价 · 按 ¥0 计", 会话面板与 KPI 卡片都会标注"含未定价模型,费用偏低"。**因此"估算成本"要读成 "已定价部分的成本 + 未定价 token 数",不是完整账单;** > 0.8.5 起收紧了这条口径:此前第三方模型会按名字套用官方价估算,但中转实际计费与官方价 > 无关,那个数字**像账单却不是账单**。现在改为一律不计价,由"未定价"显式报出。 - 默认永久保留全部原始请求记录(会话下钻/导出依赖);设置 `retention.days` 可按天修剪, 修剪在扫描期执行,超龄会话整段清理; - **被宿主拒绝的老会话无法统计**:部分 v0 老日志(插件注入过非标准事件成员,或子代理 描述符为 v2)连 DSH 自身都拒绝迁移,插件只能跳过。这类会话进入隔离清单并计入 `meta.quarantinedCount`(设置页/`/dsh-token/api/meta` 可见),可用 `POST /dsh-token/api/scan` 或重启触发 `force` 重试。它们**上一次成功扫描的记录会保留**在 store 里(不会静默清零), 只是不再更新 —— 本机实测为 18 个会话 / 549 条记录; - **store 损坏时以"留证 + 重建"处理,不尝试原地修复**:形态体检只做结构判定 (字段/类型/NaN),不合格就改名成 `store.json.corrupt-<时间戳>` 再从会话日志重建。 这样不会丢数据、也不会丢证据,但**配置**(自定义单价、预算、保留期) 会随之回默认 —— 因为它们只存在 store 里,日志里没有。想保住配置,请把 `$DSH_HOME/dsh-token/` **整个目录**一起备份(0.9.0 起用量记录在 `shards/`,`store.json` 只是元数据与索引;单独备份 `store.json` 会丢掉全部用量记录); - **小时桶/高峰判定固定北京时间**(UTC+8),不跟随宿主时区,也不可配置;日/月桶按宿主 本地时区。两者口径不同是有意的:前者对齐官方计费,后者对齐用户对"今天"的直觉; - 单价表按 DSH settings 里的模型目录过滤。命名空间形态已知两种(`llm-pi-ai` 的 `providers.<路由>.models[]`,以及适配器自带命名空间的顶层 `models[]`,provider 名靠一张 小映射表补全)。**任何解析不出来时一律关闭过滤显示全部**,并在启动日志里打印所见的命名 空间名(不含任何值)—— 所以"读不到配置"只会退回旧行为,不会把界面清空; - 配置在 `$DSH_HOME/dsh-token/store.json`,用量记录在同目录 `shards/`(均未走 `settings.register`,动态插件沙箱无法构造 schemastery schema);单价表只**读** DSH settings,从不写它,且只取 `provider:model` 标识,settings 原文(含凭据相关字段) 绝不进入 API 载荷; - 会话标题取 DSH 的自动生成标题(`session/title` 事件),缺省回退首条用户消息。
