bowenliang123/dsh-context
bowenliang123/dsh-contextDSH 上下文洞察面板:Context 仪表盘 + /context命令 + Context 浏览器,查看 Context的分类组成、内容详情、演进趋势、压缩/注入事件、统计等一站式 Context 全生命周期管理。
按 DeepSeek 官方价目显示每轮、每会话与每工作区的对话费用人民币金额,支持峰谷分时与 Search/Fetch 按次计费。
token 按官方三档 + 峰谷实时计价;2026-11-01 起网页搜索/抓取按次计费(¥5/1000 次),一次不漏。每轮 · 每会话 · 每工作区,三处人民币金额。
简体中文 · English
三个显示位置:
位置 · 显示什么 每轮回答的操作行(token 用量胶囊右侧) · 这一轮花了多少 输入框底部 dock(官方 stats 胶囊旁) · 本会话累计 / 全部会话累计 侧边栏每个工作区行尾 · 该工作区(跨会话)累计
金额按 DeepSeek 官方 API 价格 计算,分两块口径:
① token 计费(按官方口径区分三种 token 与两类时段):
计费桶 · 取价档位 缓存命中输入(cacheReadTokens) · 缓存命中价 未命中输入(uncachedInputTokens) · 缓存未命中价 输出(outputTokens,已含 reasoning) · 输出价
峰谷:高峰时段 = 北京时间 周一至周五(不含中国法定节假日)9:00–12:00、14:00–18:00,高峰价 = 空闲价 × 2;其余时段(含周末、调休上班的周末、法定节假日全天)一律空闲价。
当前价目(CNY / 百万 token,[空闲, 高峰]):
模型 · 命中 · 未命中 · 输出 deepseek-flash · 0.02 / 0.04 · 1 / 2 · 4 / 8 deepseek-v4-pro · 0.15 / 0.30 · 4.5 / 9 · 13.5 / 27
② Search / Fetch 按次计费(官方公告 2026-10-25,北京时间 2026-11-01 00:00 起生效,之前的调用免费;不分峰谷):
API · 计费单位 · 价格 Search(web_search 服务端搜索) · 每 1,000 次成功请求 · 5 元 Fetch(web_fetch 服务端抓取) · 每 1,000 次成功请求 · 5 元
「一次成功请求」在日志里的判定:web_fetch 的 tool/result 无 isError/error 即一次;web_search 一次调用带 N 个子查询 = N 次请求(本机实测 35 次调用 / 59 子查询 = 59 条请求事件,严格对应)。生效线以请求发起时刻判定。
价表快照:token 价 2026-09-19 复核;Search/Fetch 价 2026-10-25(公告原文)。官方再次调价时,改lib/client.js与lib/cost-core.mjs两处的FLASH_PRICE/PRO_PRICE/WEB_REQUEST_UNITS(两份实现由测试保持逐位一致)。
每轮(token 用量旁边):
复制 反馈 分支 消耗 1.6M tokens ¥0.920 21:50
└─ 本插件
输入框底部(官方 stats 胶囊旁):
… 12 轮 · 3 步 · 42 tok/s 1.6M tokens · 缓存 92% ¥3.84
侧边栏工作区:
▼ 价格显示插件 ¥1.23
session-9cc5451a…
▼ ssh插件 ¥18.46
session-3611dbc7…▲ 角标;点开是完整明细(模型、时段、缓存命中率、三档单价、分项与合计;本轮有搜索/抓取时另有按次行)。pointer-events:none,不会拦截整行的折叠点击。数字 · 数据来源 · 覆盖范围 每轮金额 · 客户端:useChat → turn-tail 节点的 tokenUsage · 当前已加载的轮次 本会话 / 全部 / 工作区 · 宿主:扫描 ~/.dsh/sessions 全部会话日志 · 包含安装插件之前的历史会话
宿主账本以会话日志文件为唯一事实源:DSH 实时落盘,所以文件内容就是最新真相;插件每 15 秒增量重扫(只重扫 mtime/size 变化的文件),首次全量扫描在启动 1.2 秒后异步分片进行(实测本机 52 个会话 / 约 30MB 压缩日志 → 1.8 秒)。
会话日志是「每行一条 JSON、每行单独压成一个 zstd 帧」的多帧格式,zstdDecompressSync 只解第一帧。lib/session-scan.mjs 移植了官方 dsh-session-persistence-jsonl 的帧扫描逻辑(纯 JS、不碰 Node 私有 API)来逐帧解压。
工作区归属:session 头事件里的 cwd;宿主再用 workspaceRegistry 服务把 workspaceId ↔ path 对上,下发 byWorkspaceId,客户端按 data-row-key="workspace:" 直接匹配。
cacheWrite × 1.25 会把费用算高。outputTokens 已经包含推理 token。isError/error)与未出结果的调用不计。web_search 调用的 queries 数组有多长就发几次请求(与宿主日志里 web/deepseek-search-llm-request 事件数实测一致);客户端看不到该事件,所以两边统一按子查询数计,请求事件数留作 live-ledger 的交叉核对。1e-8 元 为单位整数相加(tokens × 价格 × 100),只在展示时换算,避免浮点漂移导致「合计 ≠ 各项之和」。Search/Fetch 同样走整数定标(每次 500,000 units)。方式一:npm(推荐)——已发布到 npm,预构建安装免 allowBuilds 构建授权:
# 在 DSH desktop profile 目录里执行(~/.dsh/profiles/desktop)
cd $env:USERPROFILE\.dsh\profiles\desktop
npm install dsh-faremeter
# 再把 "dsh-faremeter" 加进 package.json 的 dsh.profile.bundles 数组方式二:源码 / Release——克隆本仓库(或从 Releases 解压 zip)后在插件目录执行:
# 预览要做的改动(不落盘)
pwsh -File install-profile.ps1 -WhatIf
# 装进 desktop profile(自动完成依赖、bundles 与 junction 的全部改动)
pwsh -File install-profile.ps1
# 卸载
pwsh -File install-profile.ps1 -Uninstall脚本会:备份 profile 的 package.json → 加一条 link: 依赖 → 把 dsh-faremeter 追加进 dsh.profile.bundles → 在 profile 的 node_modules 下建 junction。
装完必须完全退出并重开 DSH Desktop(关窗口不够,要退出进程),客户端 bundle 才会被编进 window.__DSH_BOOT__。
项 · 值 插槽 · conversation.chat.assistant-actions(list,session 作用域,order: 20) 条目 id · faremeter 数据来源 · slot 标准 props 的 useChat → turn-tail 节点的 data.tokenUsage / data.closing.time 注入服务 · 只有 slots
胶囊的落点:先渲染一个不可见锚点拿到自己在官方操作行里的位置,再从锚点向上找 [data-clock="end"](已完成轮次的操作行),取其最后一个子节点(装着用量胶囊与时钟的 span),用 ReactDOM.createPortal 把胶囊渲染到一个插在「用量胶囊之后、时钟之前」的容器里。
定位不到时不会消失,而是回落到操作行原位:如果 DOM 形状变了、或者这一行没有用量胶囊,胶囊就直接渲染在插槽自己的位置(复制按钮右侧)。这样「插件没生效」和「定位没匹配上」不会长得一模一样。
取数口径:snapshot.nodes 在真实宿主里是 MutableChatNodeStore(有 get(key) 与 values(),没有 `forEach`)。这一点踩过坑:早期版本用 forEach 遍历,结果静默取不到任何节点,胶囊永远不出现。现在 nodeListOf() 同时兼容 store / Map / 普通对象三种形状,并有专门的回归测试钉住。
pwsh -File pack.ps1产物在 dist:
文件 · 用途 dsh-faremeter-.tgz · npm 标准包,DSH 插件安装走这个。内容严格按 package.json 的 files 白名单,不含测试与打包脚本 dsh-faremeter-.zip · 源码分发:解压即得完整插件目录,直接跑 install-profile.ps1 安装;额外带测试便于复核
脚本会先跑完四组测试再打包——测试不过就中止,不会产出带病产物。打包后还会做三件事:
lib/index.js、调 apply()、断言路由注册成功且 apply 不抛错、客户端产物关键标记齐全;打包时把 npm 缓存钉在 .npm-cache(而不是用户全局缓存),避免沙箱限制与污染。如果胶囊没出现,在浏览器控制台(Ctrl+Shift+I)手打下面这一行回车:
__DSH_FAREMETER__会返回一个诊断对象:
字段 · 看什么 applies · 0 = 客户端插件根本没被应用(bundle 没加载) entries · 为空 = 条目根本没被渲染;hasUseChat:false = 宿主没给 useChat;hasUsage:false = 没取到本轮用量 entries[].propKeys · slot 标准 props 的实际字段清单 placements · endInfo:false = 没找到「用量胶囊之后」的落点,此时胶囊会回落到操作行原位 notes[0].nodeStore · 宿主 snapshot.nodes 的实际能力(hasValues / hasForEach…)
注意:DevTools 会拦截「粘贴」,手打不受影响。
编辑 lib/client.js 顶部的价目表:
var FLASH_PRICE = { hit: [0.02, 0.04], miss: [1, 2], out: [4, 8] }; // [空闲, 高峰]
var PRO_PRICE = { hit: [0.15, 0.3], miss: [4.5, 9], out: [13.5, 27] };
var PRICING = { "deepseek-flash": FLASH_PRICE, ... };
// Search / Fetch 按次计费(每次成功请求的 units;¥5/1000 次 = 500,000)
var WEB_REQUEST_UNITS = 500000;
var WEB_BILLING_EFFECTIVE_MS = Date.UTC(2026, 10, 1) - 8 * 3600000; // 北京 2026-11-01 00:00lib/cost-core.mjs 里有同名常量,两处必须一起改(test/cost-core.test.mjs 会抓)。改完重开 DSH Desktop 生效。
每年 11 月国务院公布次年节假日安排后,需要把新年份的放假日补进 HOLIDAY_VALLEY,否则新年度的法定节假日会被按高峰价算(每个假日每天贵一倍)。漏补时面板会提示「节假日表尚未覆盖本年度」。
tokenUsage 只有整轮汇总,单轮金额按第一个模型估算(面板会注明);宿主账本按每次调用的真实模型计价。tool/result 的 isError/error 判定(与官方 client-ui-chat 的失败语义一致);Search 一次调用成功即计全部子查询。子查询被服务端内部重试的情况不可见,可能略少算。npm test # 四组测试:计价核心一致性 / 会话扫描与账本 / 客户端 / 宿主路由
node test/live-ledger.mjs --limit 5 # 用本机真实会话冒烟,打印工作区排行、Search/Fetch 口径交叉核对与自洽检查
python test/expected_cost.py --check # 42 个独立基准向量测试 · 锁定什么 test/cost-core.test.mjs · 宿主与客户端两份计价实现用同一批向量逐位一致(防止「每轮金额加起来 ≠ 会话总额」),并钉住 Search/Fetch 常量、生效线与按次计费 test/session-scan.test.mjs · zstd 多帧扫描、坏帧容错、同 (turn,step) 替换、llm/retry-started 累加、Search/Fetch 计次(成功/失败/生效线/子查询)、账本聚合与增量重扫 test/client.test.mjs · DOM 定位、组件真跑、底部累计胶囊、工作区行注入、两个插槽注册 test/host.test.mjs · 路由注册、回环校验、方法限制、JSON 形状与三种口径自洽 test/expected_cost.py · 与 JS 独立的 Python 实现,生成 42 个基准向量
test/vectors.json 的 42 个向量覆盖峰谷边界 8 个时刻、周末 / 法定节假日 / 调休上班周六、UTC 与其他偏移的时区换算、各类 token 组合、大数与小数值。JS 侧用 1e-9 容差与之对照——两套实现独立得出同一结果,才算可信。
test/harness.mjs 是一个离线测试台(假 DOM + 保状态 React 桩 + 假模块加载器),它会真正执行 lib/client.js 并渲染组件,因此「胶囊有没有插到用量旁边」「点击有没有弹面板」「工作区行有没有拿到金额」都是被真实执行验证过的,不是靠读代码推断。
lib/index.js 宿主:cordis 条目 + 只读账本路由 + 工作区 id 映射
lib/ledger.mjs 账本:扫描会话、增量重扫、按会话/工作区聚合
lib/session-scan.mjs 会话日志:zstd 多帧扫描与逐帧解压、事件折叠
lib/cost-core.mjs 计价核心(宿主侧,与客户端实现由测试钉住一致)
lib/client.js 客户端:每轮胶囊 / 底部累计 / 工作区金额注入
cordis.patch.yml bundle patch
install-profile.ps1 安装器
test/ 四组测试 + 离线测试台 + 独立基准向量(Python)
docs/pricing-notes.md 价格与峰谷规则的核实记录(含可信度分级与来源)
docs/host-api-notes.md 宿主 API 调研(账本/路由/工作区归属)
docs/workspace-ui-notes.md 工作区 UI 插入点调研(锚点与降级阶梯)