# DeepSeek Monitor Plugin (Peak/Valley Edition) Β· DSH Native
A DSH-native plugin that monitors real-time token usage and cost from your DSH
conversations, calculated using **DeepSeek's official peak/valley pricing**,
with a floating glassmorphism panel at the top-right corner of the DSH web UI.

---
## 1. Feature Overview
| Feature | Description |
|---------|-------------|
| π§Ύ Today's Tokens | Real-time cumulative token consumption (input + cache read + output) |
| π° Today's Cost | Cost calculated with official pricing + peak/valley tier (valley = 50% off) |
| π¬ Sessions | Number of user messages sent today (`turn/start` events β one turn per interaction, excludes tool-call steps) |
| π Avg / Session | Average tokens per call today |
| π΄π’ Status Ring | 48px breathing ring: green = valley (half price), red = peak (full price) |
| π Real-time Clock | Beijing time (UTC+8, no DST), shows HH:MM:SS + weekday |
| π Quota Bar | Today's cost vs limit (default Β₯10, turns yellow β₯70%, red β₯90%) |
| π’π΄ Legend | Valley 0.5Γ / Peak 1.0Γ with official time windows |
| π Copy Report | One-click copy of today's usage summary to clipboard |
| π Refresh | Immediate data refresh (auto-polls every 2 seconds) |
| π±οΈ Drag | Drag by the header bar to reposition the panel |
| β Collapse | Collapse into a pill showing current cost + tier |
| β Hide | Permanently hide (state remembered in localStorage) |
---
## 2. Peak/Valley Schedule & Pricing (Official)
> Source:
### Peak/Valley Windows (official rules, effective 2026-08-23)
| Period | Rule | Multiplier |
|--------|------|:----------:|
| **Weekdays** | Peak: 09:00β12:00, 14:00β18:00 Beijing; Valley: rest | Peak 1.0Γ / Valley 0.5Γ |
| **Weekends (Sat & Sun)** | **All-day valley pricing, no peak/valley split** | 0.5Γ (half) |
### Official Pricing (CNY per 1M tokens)
| Model | Item | Peak 1.0Γ | Valley 0.5Γ |
|-------|------|----------:|----------:|
| **deepseek-v4-flash** | cache hit | 0.10 | 0.05 |
| | cache miss (input) | 3.00 | 1.50 |
| | output | 9.00 | 4.50 |
| **deepseek-v4-pro** | cache hit | 0.30 | 0.15 |
| | cache miss (input) | 9.00 | 4.50 |
| | output | 27.00 | 13.50 |
> The tier is determined by the event timestamp β no splitting within a single request.
---
## 3. Data Source (Real, Not Simulated)
The plugin listens on the DSH server-side event stream:
```
DSH session events (session/event)
ββ assistant/message event (carries TokenUsage: inputTokens / outputTokens / cacheReadTokens / cacheWriteTokens)
ββ dsh-monitor accumulates into today's statistics
ββ in-memory state (served via API)
ββ ~/.dsh/dsh-monitor.json (persisted, daily rollover at 00:00)
```
- Data comes from DSH's internal event system β **no browser extension needed**
- Counted once per completed model call (`assistant/message` event) for tokens/cost, no duplicate counting
- Sessions count `turn/start` events (agent-loop opens one turn per user interaction) β a conversation with multiple tool-call steps still counts as 1; restored from the persistence file on restart (natural-day accumulation, same as tokens)
- On restart, the plugin recovers from the persisted file and continues
---
## 4. Installation (Skip if already installed)
### 4.1 Plugin Source
```
dsh-monitor\
βββ package.json # Plugin manifest
βββ lib\
β βββ index.js # Server: event listener, pricing, API, UI injection
β βββ ui.js # Client: floating panel (polls /api/dsh-monitor)
β βββ types\index.d.ts
βββ README.md
```
### 4.2 Register in DSH Web Profile
1. **`~/.dsh/profiles/web/package.json`** β add dependency:
```json
{
"name": "dsh-profile-web",
"private": true,
"dependencies": {
"dsh-monitor": "file:./dsh-monitor"
},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app"
]
}
}
}
```
> β οΈ The `bundles` array holds bundle packages only (`@deepseek-ai/dsh-base`,
> `@deepseek-ai/dsh-web-app`). **Do not** put a single plugin in `bundles`,
> or DSH will hang on startup.
2. **`~/.dsh/profiles/web/cordis.patch.yml`** β load via `insert`:
```yaml
# Your profile patch layer (append to the end)
- insert:
- id: dsh-monitor
name: 'dsh-monitor'
config:
quotaLimit: 50 # optional: today's quota cap in CNY, default 10
```
3. **Install dependencies** (in the profile directory):
```powershell
cd ~/.dsh/profiles/web
corepack pnpm install
```
4. **Restart DSH**: `dsh web` (or however you usually start DSH)
### 4.3 Verify
- Open and press **F5**
- The floating panel should appear at the top-right
- Directly visit β should return JSON
---
## 5. Usage
1. **Open**: After starting DSH, press F5 to show the panel
2. **Drag**: Grab the header bar ("DEEPSEEK Β· Monitor") to reposition
3. **Collapse**: Click `β` to collapse into a pill (shows cost + tier)
4. **Hide**: Click `β` to hide permanently (state saved in localStorage)
5. **Copy Report**: Click "π Copy Report" for a clipboard-ready summary:
```
γDEEPSEEK Usage Reportγ2026-08-21 Β· Valley Β· Half Price
Tokens: 270,647 (Input 2,849 / Cache Hit 266,112 / Output 1,686)
Cost: Β₯0.0252 (Peak Β₯0 / Valley Β₯0.0252)
Sessions: 3
Avg: 90,216 tokens/session
Quota: 0% (Β₯0.0252 / Β₯10)
Peak/Valley: Peak 09:00-12:00/14:00-18:00 Γ1.0 | Valley rest Γ0.5 (daily)
Model: deepseek-v4-flash Β· Current rate: cache hit Β₯0.05/1M Β· miss Β₯1.5/1M Β· output Β₯4.5/1M
```
6. **Refresh**: Click "π Refresh" to poll immediately (auto-polls every 2 s)
---
## 6. Data & Persistence
### 6.1 File Structure (`~/.dsh/dsh-monitor.json`)
```json
{
"date": "2026-08-21",
"tokens": 270647,
"cost": 0.0252,
"sessions": 3,
"inputTokens": 2849,
"outputTokens": 1686,
"cacheReadTokens": 266112,
"peakCost": 0,
"valleyCost": 0.0252,
"history": {
"2026-08-20": { "...": "..." }
}
}
```
### 6.2 Daily Rollover
- At **00:00 Beijing time**, yesterday's data moves into `history`, today resets
- History keeps **90 days**, auto-prunes older entries
- System clock changes do not affect (event timestamps are used)
### 6.3 Cost Formula
```
cost = cacheRead/1e6 Γ cacheUnitPrice + input/1e6 Γ missUnitPrice + output/1e6 Γ outputUnitPrice
(unit prices are chosen by the event timestamp's peak/valley tier)
```
---
## 7. REST API
The frontend polls this endpoint; it can also be used by other tools.
```
GET /api/dsh-monitor
```
Example response:
```json
{
"ok": true,
"isValley": true,
"tier": "valley",
"stats": {
"date": "2026-08-21",
"tokens": 270647,
"cost": 0.0252,
"sessions": 3,
"avgPerSession": 90216,
"inputTokens": 2849,
"outputTokens": 1686,
"cacheReadTokens": 266112,
"peakCost": 0,
"valleyCost": 0.0252
},
"quota": { "used": 0.0252, "limit": 10, "pct": 0 },
"prices": {
"model": "deepseek-v4-flash",
"peak": { "cached": 0.10, "uncached": 3.0, "output": 9.0 },
"offpeak": { "cached": 0.05, "uncached": 1.5, "output": 4.5 }
},
"demoMode": false,
"updatedAt": 1787286745749,
"peakHours": "Beijing 09:00-12:00, 14:00-18:00 (daily)",
"valleyHours": "Rest of the day (50% off)"
}
```
---
## 8. Configuration
Built-in defaults β modify `lib/index.js` to adjust:
| Setting | Location | Default | Notes |
|---------|----------|---------|-------|
| Price table | `PRICING` constant | flash/pro official | Update when DeepSeek changes prices |
| Quota limit | `buildPayload()` β `quota.limit` | `10` (CNY) | Progress bar denominator |
| Report model | `buildPayload()` β `model` | `deepseek-v4-flash` | Model name in report |
| Poll interval | `lib/ui.js` β `pollTimer` | 2000 ms | Panel refresh rate |
| History window | `maybeRollover()` β `90` | 90 days | Rolling window |
---
## 9. FAQ
**Q1: The panel does not appear.**
A: Press F5 to refresh. Verify the index.html source contains `dsh-monitor/ui.js`. Check that DSH is the newly restarted instance.
**Q2: All numbers are 0.**
A: Send a message first. Visit `/api/dsh-monitor` and check the `_diag` field:
- `eventsSeen = 0` β event listener not active (plugin not loaded; check cordis.patch.yml)
- `eventsSeen > 0` but `assistantMessages = 0` β no assistant message completed
- `withUsage = 0` β LLM adapter did not report usage
- `accumulated > 0` β working normally
**Q3: Is data lost after restart?**
A: No. It is restored from `~/.dsh/dsh-monitor.json` on startup. Manual deletion resets to 0.
**Q4: Is the cost simulated?**
A: No. It is computed from real `TokenUsage` (input/output/cacheRead) in DSH session events, multiplied by the official price table and peak/valley tier.
**Q5: Difference from the browser extension?**
A: The browser extension injects into the page's network layer, which cannot intercept DSH model calls (they go through the Node backend). The DSH-native plugin reads the event stream directly on the server side, making it more accurate. The browser extension is still useful for `chat.deepseek.com` usage.
---
## 10. Uninstallation
1. Remove the `- insert: [...] dsh-monitor` block from `cordis.patch.yml`
2. Remove `"dsh-monitor": "file:..."` from `package.json` β `dependencies`
3. Run `corepack pnpm install` (cleans up the node_modules link)
4. Restart DSH
---
## 11. Development & Debugging
```powershell
# Syntax check
node --check lib/index.js
node --check lib/ui.js
# Start a test instance (port 3090, does not affect the production 3080 instance)
dsh web --port 3090 --no-open
# Then visit http://127.0.0.1:3090/api/dsh-monitor
# Sync source changes to profile (file: link):
cd ~/.dsh/profiles/web
corepack pnpm install
# Then restart DSH
```
> β οΈ Changes to `lib/index.js` require `corepack pnpm install` + DSH restart to take effect. `lib/ui.js` is read at runtime, but the injection logic in `index.js` also needs a restart.
---
## Changelog
| Version | Date | Notes |
|---------|------|-------|
| 1.3.0 | 2026-08-23 | Official peak/valley rule update: weekends (Sat/Sun) now all-day valley pricing, weekdays keep original windows |
| 1.2.1 | 2026-08-21 | Fixed sessions resetting to 0 on restart; switch to `turn/start` counting (one turn per interaction, reliable for direct web messages too) |
| 1.2.0 | 2026-08-21 | Quota cap now configurable (`config.quotaLimit`, default 10) β no code changes needed |
| 1.1.0 | 2026-08-21 | Sessions count changed to user messages (`user/message` + `source.kind=user` filter), fixed multi-step tool call inflation |
| 1.0.0 | 2026-08-21 | First DSH-native release: real event accumulation, official peak/valley pricing, floating panel UI, daily rollover |