xchannel1987/dsh-token-usage-xc

xchannel1987/dsh-token-usage-xc

DSH Token 用量统计插件 - 今日 Token 用量按模型分桶、缓存命中率、7 日趋势图、可选顶栏徽标、持久化存储自动清理。

用量与计费

dsh-token-usage-xc

中文 | English

DSH Token Usage Statistics Plugin — Real-time tracking of today's and last 7 days' token consumption, bucketed by model with cache hit rate analysis and trend charts.

DSH 0.1.7 compatible (>=0.1.7-rc.1): settings namespace adapted to the 0.1.7 mechanism (host exports Config + volatile fields).

✨ Core Features

📊 Today's Token Usage

New "Today's Token Usage" section in settings page showing:

  • Per-Model Statistics: Input/Output/Cache Read/Cache Write tokens
  • Cache Hit Rate: cacheRead / (uncachedInput + cacheRead) × 100%
  • Request Count: API calls per model
  • Daily Total: Aggregated data across all models

📈 7-Day Trend Chart

  • Stacked Bar Chart: 7-day usage trend with model-colored segments
  • Date Navigation: View any historical date
  • Model Filter: Select specific models to display

🔔 Header Badge (Optional)

  • Real-time Display: Shows today's total tokens in conversation header
  • Click to Expand: Click badge for detailed breakdown
  • Compact Format: K/M/B notation with hover for exact values
  • Mobile Layout (≤1023px): the header row reads Hamburg │ PTC mode │ Remaining meter │ Usage badge │ Background jobs — the badge sits second-to-last with jobs rightmost, aligned on the same row as the drawer toggle without overlap; ≤380px wraps automatically while preserving visual order
  • Mobile Compactness: the "tok" suffix is hidden and padding tightened so a 390px-wide single row fits completely

💾 Data Persistence

  • Daily Storage: ~/.dsh/storages/dsh-token-usage-xc/<YYYY-MM-DD>.json
  • Restart Resilient: Data auto-recovers after restart
  • Auto Cleanup: 7-day automatic cleanup of old data
  • Startup Backfill: Backfills usage before plugin loaded today

🔧 Data Sources

SourceDescription
session/eventListen to assistant/message event's usage field
Model AttributionRead event's message.source.model directly
Session WatermarkDedupe by seq to avoid double counting

Why not parse session.jsonl.zstd directly?
The file is multi-zstd-frame concatenated, requiring frame boundary scanning like the persistence backend. Plugins use sessionQuery to avoid reimplementing this complex logic.

📦 Installation

# Using DSH CLI
dsh plugin --profile web add dsh-token-usage-xc

# Or using npm
npm install dsh-token-usage-xc

Restart DSH after installation. You'll see a new "Today's Token Usage" section in settings.

⚙️ Configuration

OptionDefaultDescription
enabledtrueEnable statistics
refreshIntervalSec60Frontend refresh interval (10-3600s)
backfilltrueBackfill today's usage on startup
headerBadgefalseShow total token badge in conversation header

🎮 Usage

View Today's Usage

  1. Open DSH Settings
  2. Find "Today's Token Usage" section
  3. View per-model breakdown

View 7-Day Trend

  1. Click "Trend" tab in usage panel
  2. View stacked bar chart
  3. Click dates for details

Enable Header Badge

  1. Enable "Show today's total tokens in conversation header" in settings
  2. Today's total appears in conversation header
  3. Click badge for quick details

🔌 Data Interface

RPC endpoints for other plugins:

// rpc.call("/api", "dsh-token-usage-xc/today", {})  -> physical route: POST /api/dsh-token-usage-xc/today
// (preferred since 0.2.24; legacy rpc.call("/dsh-token-usage-xc","today") still served on dsh <0.1.5 or patched hosts)
{
  available: boolean;
  date: string;           // 'YYYY-MM-DD'
  totalTokens: number;
  requests: number;
  models: {
    model: string;
    modelName: string | null;
    provider: string;
    uncachedInputTokens: number;
    outputTokens: number;
    cacheReadTokens: number;
    cacheWriteTokens: number;
    totalTokens: number;
    requests: number;
  }[];
}

// rpc.call("/api", "dsh-token-usage-xc/last7days", {})
// Returns last 7 days' aggregated data

📐 Statistics Methodology

  • Total Tokens = uncachedInput + cacheRead + cacheWrite + output
  • Cache Hit Rate = cacheRead / (uncachedInput + cacheRead) × 100%
  • Final Usage Only: Each assistant/message has exactly one usage, naturally deduped
  • Event Time Bucketing: Bucketed to YYYY-MM-DD based on event.time

📄 License

MIT