# dsh-peak-cost-mode

DeepSeek 峰谷计价省钱插件，适用于 [DeepSeek Harness](https://github.com/deepseek-ai/dsh)（DSH）：高峰计价时段（北京时间周一至周五 09:00–12:00、14:00–18:00，价格 ×2；周末全天谷价）自动切换 **caveman 超精简输出** 省输出 token，标题栏徽章 + 切换 toast 随时告知当前档位。

## 功能

- **自动监测** —— 每 30 秒按北京时间（UTC+8，无夏令时）对照 DeepSeek V4 峰谷时刻表：
  | 时段（北京时间） | 档位 | 价格 |
  |---|---|---|
  | 周一至周五 09:00–12:00 | 高峰 | ×2 |
  | 周一至周五 12:00–14:00 | 低谷 | ×1 |
  | 周一至周五 14:00–18:00 | 高峰 | ×2 |
  | 周一至周五 18:00–次日 09:00 | 低谷 | ×1 |
  | **周六/周日 全天** | **低谷（周末全天谷价）** | **×1** |
- **高峰省流** —— 高峰期间注入「高峰省流模式」提示段：要求模型以 caveman 超精简风格回复（去客套/铺垫/填充词，代码、命令、API 名、路径、精确错误信息、数字一律原样保留；安全警告与不可逆操作确认永不压缩）。
- **切换提醒** —— 每次档位切换弹 toast：
  - 低谷 → 高峰：「梁文锋来了，少说话多做事。」
  - 高峰 → 低谷：「梁文谷来了，一切正常。」
- **常驻状态徽章** —— 会话标题栏右侧（会话日志按钮左侧）：高峰红底「高峰 ×2 · 省流中」，主动省流绿底「🟢 低谷 · 主动省流中」，普通低谷绿底「低谷 ×1」；悬停显示完整信息（窗口/倍率/北京时间/下次切换）。点击徽章打开「省流收益报告」；低谷时报告右下角有「🟢 我要省钱！」按钮。
- **低谷主动省流（0.3.0）** —— 低谷时段点绿色徽章 → 「我要省钱！」立即进入省流模式：同样注入 caveman 提示段、同样记账（波次标记 `source: voluntary`，与官方高峰 `source: peak` 分开统计）。徽章保持绿色（带 🟢 区分「主动省流中」），报告面板今日/累计按「高峰省 / 主动省」分列展示。主动省流为持久开关：跨高峰续用（进峰自动并入高峰记账，出峰自动恢复主动省流），随时可在报告右下角「✋ 停止省流」。
- **省流收益计量（0.2.0）** —— 省流期间拦截每一次流式模型调用（`llm/stream`），按模型记录真实 token 用量（输入未命中 / 缓存命中 / 输出，DeepSeek 适配器输出的分离计数），再估算 caveman 压缩帮你省了多少、并按 DeepSeek 高峰输出价折成人民币：
  - `省下 tokens ≈ 高峰实际输出 × r/(1−r)`，**r = 压缩率，默认 0.6**（保守；可配 0–0.9）。
  - `省下 RMB = 省下 tokens × 模型高峰输出价 / 1e6`（高峰 = 低谷 ×2；如 V4-Flash 输出 ¥9.0/百万、V4-Pro ¥27.0/百万）。
  - **缓存命中考虑** —— 输入按缓存命中/未命中分列计费（Flash 命中 ¥0.05 vs 未命中 ¥1.5 → 差 30×，Pro 同理），展示输入缓存命中率健康度；并给出「缓存损益」一行（实际命中率高于基线为 +省，低于为 −多花）。**注意：缓存损益为平台缓存优惠参考，不计入插件省钱**——压缩输出不影响输入侧，实际命中率由平台提示词复用决定，故「省」仅计输出侧。
  - 台账按高峰波次封档，落盘 `${DSH_HOME:-~/.dsh}/dsh-peak-cost-mode/stats.json`，重启不丢（写不动则降级内存）。
  - 口径说明：**「省」是估算**（反事实——未压缩会输出多少无法精确得知），UI 中明确标注「估算」。
- **收益展示位置** —— 标题栏徽章（高峰实时计数）、输入框上方常驻读数（`conversation.composer.dock`）、出峰 toast（本波高峰汇总）、「收益报告」面板（点徽章）：本高峰/今日/累计 的 token + 人民币、按模型明细（无插件预估输出 → 实际输出 → 省 token/¥）、清空按钮（`POST /api/peak-cost/reset`）。报告只展示输出侧（压缩输出的真实贡献）；输入与缓存命中与插件无关，不展示。

## 安装

```sh
dsh plugin --profile web add dsh-peak-cost-mode
# 或从 GitHub 安装
dsh plugin --profile web add github:moon09300731/dsh-peak-cost-mode
```

安装后重启 `dsh web` 并硬刷新浏览器页面。

> **本地开发**：改完源码后若看不到变化，多半是 Host 加载的是 npm 安装副本而非源码目录。
> 请把 profile 的 `package.json` 依赖改为 `"dsh-peak-cost-mode": "file:/path/to/dsh-peak-cost-mode"`
> 后 `npm install` 重链（与 dsh-approval-gate 等本地插件同模式），再重启 `dsh web`。

## 验证费用计算

```sh
node scripts/verify.mjs          # 独立核算对照 /api/peak-cost/stats，40 项全 PASS 即正确
npm test                         # 单元测试（峰窗/公式/台账/防重复包裹）
```

## 配置

可选配置文件 `${DSH_HOME:-~/.dsh}/dsh-peak-cost-mode/config.json`：

```json
{
  "saveRatio": 0.6,
  "baseCacheHitRate": 0.5,
  "multiplier": 2,
  "peakWindows": [
    { "start": 9, "end": 12 },
    { "start": 14, "end": 18 }
  ],
  "weekendValley": true,
  "prices": {
    "deepseek-v4-flash": { "hit": 0.05, "miss": 1.5, "output": 4.5 },
    "deepseek-v4-pro": { "hit": 0.15, "miss": 4.5, "output": 13.5 }
  }
}
```

- `saveRatio` —— caveman 假设的输出压缩率（默认 0.6，范围 0–0.9）。
- `baseCacheHitRate` —— 无低谷实测时，「无插件」反事实输入账单采用的缓存命中率基线（默认 0.5）。
- `peakWindows` —— 北京时间高峰窗口数组，每项 `{ start, end }`（默认 `[{9,12},{14,18}]`）。
- `weekendValley` —— `true`（默认）表示周六/周日全天谷价；设为 `false` 可恢复旧的“周末也按峰谷”行为。
- `multiplier` —— RMB 折算的高峰倍率（默认 2）。
- `prices` —— 每个模型的低价谷价（元/百万 tokens）；精确模型键覆盖内置 flash/pro 默认。**价目会变，请以 DeepSeek 官方定价页为准；展示的省钱为估算，非账单。**

## 工作原理

- Host（`src/index.mjs`）：10 秒定时器计算北京时间 + 状态机（三态：`peak` 官方高峰 / `voluntary` 用户主动省流 / `none`）。任一省流态注册 `systemPrompt` 段落（`peak-cost-mode`，order 60）要求 caveman 精简输出；退出省流即移除。订阅 `llm/stream` waterfall，包住每次调用、正常收尾时采集 `usage`（输入/缓存命中/输出 token）+ 模型 id，有打开的省流波次即按波次 `source` 入账（高峰 `peak` / 主动 `voluntary` 分列统计）。暴露 `GET /api/peak-cost/state`、`GET /api/peak-cost/stats`、`POST /api/peak-cost/voluntary?active=true|false`（主动省流开关，持久化）、`POST /api/peak-cost/reset`。
- Client（`client.js`）：每 10 秒轮询 `/api/peak-cost/state`（快照镜像到 `localStorage` 键 `dsh.peakCost.v1`），渲染徽章（红=高峰省流 / 绿🟢=主动省流 / 绿=低谷正常）、toast、输入框读数和报告面板（右下角「我要省钱！」/「停止省流」按钮，今日/累计按高峰省·主动省分列）。

> 说明：提示段落注册在宿主作用域，高峰时段对部署内**所有会话**生效（这正是省钱的目的）。若只想对单个会话启用高峰压缩，请改用动态插件方式。

## 开发

```sh
npm test   # node --check src/index.mjs && node --check client.js
```

## 许可证

MIT © moon09300731
