Repository navigation
Releases: fufuf-c/dsh-token
Release list
v0.9.6
主题:修 dsh 0.1.7-alpha.1 上"插件时好时坏、打开面板要等很久才出数"的根因 —— 宿主把遗留会话的 revision 换成了"文件身份 + 整库语料哈希",而本插件用 revision 当水位线,于是任一会话变动都让全部遗留会话失效、每轮整库重读。 无存储格式变更(STORE_VERSION 仍为 v8),升级不需要迁移动作;已在 0.1.7 上跑过的库第一轮就是零重读。
修复
- 水位线只认"本会话文件身份",不再受整库语料哈希牵连(
lib/session-source.mjs)。宿主@deepseek-ai/dsh-session-persistence-jsonl0.1.7-alpha.1 起,list()对sourceVersion < 当前格式的会话返回<dev:ino:size:mtimeNs:ctimeNs>:<historicalCorpusRevision()>;后者是整库所有会话文件路径 + 各自 stat 身份的 sha256。旧实现在scanStore里直接做wm.rev !== String(s.revision),粒度错配:
| 场景(70 会话 / 65 个 v3,仅改 1 个文件 mtime,内容零改动) | 0.9.5 | 0.9.6 |
|---|---|---|
| 无变化的一轮 | 88 ms | 88 ms |
| 只改 1 个文件的 mtime | 8 512 ms(changed=65) | ~90 ms(changed=0) |
而页面「进入界面时先扫描」(默认开启)意味着打开面板要等整轮扫完才出数据 —— 这正是"有时候不显示、过一会又能显示"。现在 ownRevisionToken() 只取前五段(文件身份);对新旧宿主都安全(≤0.1.6 本来就是五段,内存会话 memory:<n>:<i> 段数不足则原样返回)。
-
遗留会话的兄弟依赖改为精确追踪,而不是丢弃(同文件)。整库哈希原本承载的语义是"遗留会话解码时可能读兄弟文件"(宿主
prepareStoredMigration→children()会读origin === 'subagent' && parentSession === id的子会话参与解码)。直接删掉这层依赖会让父会话在子会话变化后不再重折(数据静默少算)。新增relatedFingerprints():按宿主真正读的那批文件算"父会话 id → 子会话 id+文件身份"指纹,并存入水位线的rel字段。于是子会话增删改只让该父会话重读,不波及别的父会话 —— 语义不弱于整库哈希,影响面从 O(全库) 收到 O(该父的子树)。 -
升级路径不会触发一次整库重读(同文件)。已在 0.1.7 上跑过的库里,水位线存的是六段形态(含整库哈希)。比较时对已存值与当前值都做归一化,所以升级后第一轮就是零重读,而不是把全部遗留会话判为"变了"。
-
dsh.engines.dsh补上>=0.1.7-0(package.json/README.md)。按 SemVer 规则预发布不落在普通范围里:0.1.7-alpha.1既不满足>=0.1.5-rc.1也不满足>=0.1.6-0,旧声明把本插件实际支持并已在跑的 0.1.7 预发布判成不兼容(插件市场会据此显示"不兼容")。同时把0.1.7-alpha.1记进compatibility.dshReleases。
测试
test/v096-hostrev.test.mjs(V73–V73e)。用宿主 0.1.7 的真实 revision 形态(含"20 个会话共享同一语料哈希")锁住:任一会话变动只重读它自己;语料哈希变化本身零重读;老库六段水位线零重读;子会话变化只波及它的父;以及两个纯函数的边界。这四条行为断言在旧逻辑下实测有 4 条失败,不是事后补的空测试。
Full Changelog: v0.9.5...v0.9.6
v0.9.5
主题:补掉唯一一处"与改动量脱钩"的计算 —— 扫描收尾的聚合重建从"只要有会话变化就
整库重折"改成"只重折被改动的会话"。 无存储格式变更(STORE_VERSION 仍为 v8),
升级不需要迁移动作;重启后第一轮扫描走完整重建(与旧行为一致),之后进入增量。
性能
-
聚合收尾改为增量(
lib/session-source.mjs的收尾分支 +lib/core.mjs的
unfoldSessionInto/incrementalRebuildInto)。
旧行为:dirty为真就rebuildAllChunked(全库)—— 代价 O(全库记录数),与"改了多少"
完全脱钩,20 万请求的库改 1 个会话也要重折 20 万条(作者实测 447 ms)。
新行为分三条路:情形 走哪条 数据变了(会话记录被替换 / 删除 / 修剪) 增量:只重折被改动的会话 改价格 / 高峰时段 / 保留期 整库重折(价格一改,每条记录的 cost 都过期) force全量扫描 / 冷启动 / 聚合不可用整库重折(没有"旧账"可减) 端到端实测(真实
scanStore路径,6 万请求 / 200 会话 / Node 24):场景 0.9.4 0.9.5 无变化扫描 0.2 ms 0.2 ms 改 2 个会话 66.6 ms(整库重折) 2.7 ms 冷启动首扫 整库重折 整库重折(同路径) 即"有变更的那一轮"约 25×,且库越大差距越大(O(改动量) vs O(全库))。
两条路都会在summary.aggMode里如实报出full/incremental/none,
所以"这一轮到底重折了什么"是可观测的,不必靠计时猜。足量说明(别把这条读成"扫描不再花钱了")。 增量只省掉"重折"那一段;读取与
折叠会话日志本身的开销一点没减 —— 变更的会话仍要被完整读出来并foldSession。
冷启动、force、以及任何改价的时刻仍是整库重折。本版没有做"日志的增量解码"。 -
等价性是硬门禁(
test/v095-incremental.test.mjs的 V67 / V67e)。
增量与全量在 25 轮随机改动(追加 / 缩短 / 删除 / 新增四种混跑)后,days/months/
逐记录派生字段与sessions必须逐值相同;查询与导出的 CSV 必须逐字节相同。
一个补充口径:聚合桶里的汇总额允许 1e-9 元的浮点公差(浮点减法不可逆,实测末位
差 ~1e-17),而四段用量与请求数是精确判定 —— 这个区别本身由 V69 锁定。
修复
-
newRequests统计虚高(lib/session-source.mjs)。此前是
+= 本会话全量条数,于是每次会话增长都把它整段再加一遍 —— 一个 3000 条的会话被改
10 次就虚报 3 万。现在是净新增条数。自测统计失真比没有统计更糟:它看起来像个
真实指标。 -
隔离清单在设置页从未渲染(
web/src/app/80-tab-settings.js)。服务端一直把
quarantinedCount/quarantined放在meta里(README 也说"设置页可见"),
但页面里一处都没用到 —— "有些会话统计不到"这件事对用户完全不可见。
现在新增「数据完整性」一节:总数、每个被跳过会话的 id / 错误类型 / 命中次数 / 错误
消息,并写明"保留上一次成功扫描的统计,不会静默清零"。超过服务端 50 条上报上限时
显示"仅列出前 50 个 · 共 N 个"。错误消息来自宿主解码器,按外部数据处理并转义。
文档
- README 修正"改外观"指引。原文让用户改
web/src/**后跑
node scripts/build-web.mjs,但package.json的files只发web/index.html——
web/src/**与scripts/**不在包里(由 V49/V50 锁定)。npm / git / tarball
三种安装方式下照做会扑空。已写明"这条只适用于 clone 仓库"。 - README 规模表补三行:有变更的扫描周期已改走增量(附上表实测数据)、
store.json体积随会话数线性增长(它每个脏周期整体重写,本机 64 会话约 32 KB)、
以及aggMode可观测。
与旧版的行为差异(需要知道的三条)
cost/saved的浮点末位可能与 0.9.4 不同(聚合桶汇总额吸附到 1e-12 元网格)。
这是为了消除增量减法的累积噪声,量级远小于任何有意义的金额;逐记录r.cost不受影响。days/months的键顺序变为规范序(字典序,含models/hours二级字典)。
数值不变;seriesQuery的输出字段顺序因此稳定下来。aggregatesNeedRebuild现在会拦住"有 requests 但 days 为空"这个矛盾态,
aggregatesReady对它返回 false。此前它被认为是自洽的(真空库确实是),而改成按需重折
之后这个中间态会一直留着,导致每个查询都拿到一张空账。
开发期工具(不进发布包)
scripts/bench-incremental.mjs—— 增量 vs 全量的等价性与性能对照(固定种子,可复现)。scripts/bench-scan-e2e.mjs—— 走完整scanStore路径的端到端对照。
Full Changelog: v0.7.1...v0.9.5
v0.7.1
主题:把"抄一份值"改成"接宿主变量"。 0.7.0 及以前,面板的字体、字号、底色都是从宿主
样式里复制出来的固定值 —— 复制值今天看着对,但用户一改设置、或宿主一换主题就静默失效,
而界面仍然"看起来正常",没人会发现。
修复
- 会话面板不再无视「外观」里的正文字号。 面板原来写死
font:15px/1.47,全文件不引用
--dsh-content-font-size。会话区里 chat / conversation / tool / goal / workflow-run 等
视图全部走宿主的字号变量,只有本面板不走。现在字号接--dsh-content-font-size、行高接
calc(24px + var(--dsh-content-font-delta,0px)),与相邻页签同一个口径。
(影响:把字号设成 12px 的用户,面板从 15px 变为 12px/22px。) - 面板底色不再与相邻页签有色差。 原来写死
#000(暗) /#f2f2f7(亮);会话根节点
(ConversationRoot) 实际画的是--dsw-alias-bg-base(#151517/#fff)。
现在底色接该 token,--d-bg退居兜底,切页签不再看到一整块异色。 - 字体族改接宿主钩子。 面板与仪表盘页原来各自抄了一份字体栈(且两份不同)。现在都写
var(--dsw-font-family, <DSH 的同一串 fallback>)——--dsw-font-family是 DSH 留给主题
覆写的钩子,宿主换字体时两处一起跟随。 - 仪表盘页的「自动」主题改为跟随 DSH 外观,而不是只跟随操作系统。 该页是独立文档,
看不到宿主 DOM 上的data-ds-dark-theme,因此由宿主在发送页面时注入
window.__DSH_TOKEN_THEME__(读同一个ui-theme设置段)。此前当用户把 DSH 钉成深色而
系统是浅色(或反之)时,仪表盘会和外壳反着来。 - 外观偏好纳入页面缓存键。 页面缓存原来只按
(path, mtime)失效;只改主题设置而不动
页面文件时,注入的旧偏好会被一直发出去。现在缓存键含偏好,改设置立即生效。 - 主题切换的提示文案由含糊的「跟随系统」改为说明实际来源(如「跟随 DSH(深色)」)。
- 系统深浅变化的重绘收窄:DSH 把外观钉成浅色/深色时,系统深浅与本页无关,不再触发重绘。
测试
- 新增两条宿主适配不回退断言:面板必须接宿主字体族/正文字号/底色,且不得再用
font
简写写死字号。这两条会在有人把绑定改回固定值时直接失败。 - 引用闭合检查的豁免从
--dsw-*扩展到宿主的整个命名空间(含--dsh-*,即内容字号这类
外壳运行参数),并在注释里写清两个前缀各自代表什么。 - e2e 新增两条:页面必须带注入的外观偏好引导脚本(且位于
<head>内、先于页面自身脚本);
只改设置、不动页面文件时注入值必须立刻换新。
说明
- 无破坏性改动:三个入口(侧边栏 / 对话区页签 / 设置页)的名称、插槽与 API 契约不变,
store.json结构版本不变。 - 侧边栏入口与设置页面板本来就正确使用
--dsw-alias-*,本次未改动。
Full Changelog: v0.7.0...v0.7.1
v0.3.1
DSH 本地 Token 用量统计插件——以 Token 为第一视角:不只回答"花了多少钱、用了多少量",还回答 Token 从哪来、缓存省了多少、哪些会话在烧 Token。数据全部来自本地会话日志,零上传、无在线依赖。仪表盘为 Apple 风格四 Tab 界面,开箱即用。
亮点
- 四段 Token 构成:未命中 / 缓存命中 / 缓存写入 / 输出
- 缓存省钱估算:命中量 × 未命中与命中的价差(核心差异化)
- 全局筛选贯穿所有面板:时间 + 模型多选 + 会话 + 工作目录,URL 可分享
- 会话下钻:四联统计、逐模型构成、逐请求明细、上下文增长曲线、🔥 异常激增标记
- 成本与预算:模型单价表(¥/M)、月度预算环形进度 + 外推月底预估 + 80%/100% 阈值变色
- 聚合快路径查询:日/月聚合索引(复杂度 O(天数)),10 万条请求库 kpi 25ms→1ms
- 增量扫描,空闲零写放大:未变化会话按 revision 跳过,store.json 原子写
- 保留期可配:
retention.days修剪超龄原始记录 - 多模型叠加趋势图 + 图例独立开关 + 24 桶小时直方图 + 12 个月活跃热力图
安装
# npm(包名 @fufuf-c/dsh-token):
dsh plugin --profile web add @fufuf-c/dsh-token
# 或 Release 预构建 tarball(更快,无需本地构建):
dsh plugin --profile web add "https://github.com/fufuf-c/dsh-token/releases/download/v0.3.1/fufuf-c-dsh-token-0.3.1.tgz"
# 装完安装依赖并重启
cd ~/.dsh/profiles/web && pnpm install
dsh webMIT License · 零依赖 · 数据全部本地存储