DSH Plugins Marketplace

DSH Plugins

Plugins

/

Just for Fun

/

DeepSeek-Balance-Whale-Widget

M

DeepSeek-Balance-Whale-Widget

Manifest valid★ 6.4k

DeepSeek Harness (DSH) is a little whale girl who lives in the bottom-right corner of the DSH interface, keeping an eye on your DeepSeek account balance. It bounces like QQ, supports drag-and-drop snapping, left-edge flip, and number-rolling animations. It activates automatically with the interface, so we recommend just bringing it along with your DSH installation.

hasBundlePatch

DSH Little Whale Bookkeeping Widget (DeepSeek Balance Whale Widget)

DSH Little Whale Bookkeeping Widget

A persistent widget in the bottom-right corner of the DeepSeek Harness (DSH) web UI: a little-whale bubble graphic + DeepSeek API balance + today's usage + per-turn cost, and bubble content is fully customizable (click sequence, modular layout, parallel weighted bubble picking, random phrases / random images). A standard DSH bundle plugin, installed with one dsh plugin command, no session token required.

Features

Bookkeeping & Display

  • 🐋 Persistent auto-launch: appears automatically every time the DSH web UI is opened (standard DSH bundle plugin)
  • 💰 Balance: auto-refreshes every 60 s + manual refresh by clicking the whale; the number gets a rolling animation when the balance changes; transient network glitches silently keep the last known balance without errors
  • 📊 Today's usage (Little Whale Bookkeeping): requires no token of any kind. Balance decreases are accumulated as observed spend; balance increases (top-ups / credits) are recorded separately and never offset existing spend; when a balance increase is detected a "pending balance-adjustment review" hint is shown, which you can correct under "Little Whale Bookkeeping → DeepSeek (built-in) → Settings → Balance Adjustment" using the actual accumulated received amount and non-API deductions — "observed spend" and "balance adjustment" both use the DeepSeek account's own figures (derived from that API key's balance observations, excluding other vendors; "local model cost" is the local estimate across all models) (per-turn detail is kept for 90 days or up to 20,000 entries, daily archives for 365 days; expired data is archived to .dshw-usage-archive.json); amounts are booked to 8 decimal places and displayed with 2
  • 💬 Per-turn cost: listens to DSH local session events, converts amounts using the model's actual usage (input / cache / output / reasoning tokens); a cost bubble pops up at the end of each turn; can be toggled, with an auto-close timer in seconds (0 = never auto-close), and bubble content is customizable (modular, amount referenced via {cost}); entry point: menu → per-turn cost hint → "Customize hint"
  • ⛰️ Peak/valley pricing: weekday peak 9:00–12:00, 14:00–18:00 (Beijing time), off-peak otherwise; from 2026-08-23 weekends are valley-priced all day. The peak/valley module supports status text, countdown, and multiple styles such as "Liang Wengfeng valley / !?QiangQiang?! / minimal"
  • 📒 Usage log window: today's model spend, last 7 days, and full records; model share bar; expand per date for line-by-line detail (with time and amount); supports searching by date or model name; model names carry friendly labels (deepseek-flash → DeepSeek-V4.1-Flash, legacy names annotated as "same as V4.1 Flash")

Interaction

  • 🖱️ Drag + snap: customizable snap zones on all four sides (by ratio or pixels), corners can be combined; snap can be disabled for free placement
  • 🔄 When snapped to the left edge the whole widget is mirrored horizontally (text reverses in sync, with animation)
  • 🧸 Press Q-elastic plushie effect (bottom coordinate stays fixed while pressing)
  • 🎚️ Main menu: size slider, sound toggle/volume, peak text, bubble toggle, per-turn cost toggle + "Customize hint" (per-turn cost content / auto-close seconds / task-end sound), snap settings, character/asset management, custom bubbles, balance alerts, today's budget
  • 🙈 Menu button can be hidden: when hidden, on desktop right-click the whale, on mobile long-press the whale for ~1.5 s to open the menu
  • 📱 Mobile-friendly: the whale is touch-draggable (custom touch takeover, so page gestures are not misjudged as scrolling and dragging doesn't fail); the bubble editor supports long-press 0.4 s to enter drag-reorder; the browser's default tap highlight square is removed

Bubble System (core)

  • 💬 Click sequence: first click shows the "first-click bubble", further clicks enter the "repeat-click" queue; the queue can be freely added/removed/reordered, and two bubbles can be made parallel A/B weighted picks (one is drawn per round according to weights)
  • 🔁 Tap character to advance the queue (optional, enabled in the "Custom Bubbles" window): when enabled, tapping the character advances one item (1→2→3…, after the last item the bubble collapses, next tap restarts from item 1); when disabled it behaves as before — tapping the character returns to the "first-click bubble". The setting lives only in this window and takes effect together with the window's "Save"
  • 🧩 Modular content: a bubble is composed of modules laid out by row; supported types
    • Text, hyperlinks
    • Random phrases (multiple weighted sentences, one drawn per display, no immediate repeats)
    • Image/animation (picked from the bubble image library, occupies an entire row)
    • Random image (multiple weighted images, one drawn per display, no immediate repeats, also occupies an entire row)
    • Balance value, today's usage, peak/valley period (built-in values, content auto-fetched, placeholder and style adjustable)
  • 🎨 Per-module styling: font (including custom fonts), size, bold/italic/underline, solid color or marquee gradient palette, background color; text and random-phrase modules support hover quick-edit
  • 🖐️ Drag layout: native desktop drag, mobile long-press drag; modules can be merged into the start/end of a row, rows can be split, whole rows can be reordered; max 6 modules per row, max 6 rows per bubble, image-type modules occupy a row and only one is allowed per bubble
  • 📚 Module library: "Save as" frequently used modules into the library, then reuse in any bubble by clicking or dragging

Alerts

  • 🔔 Balance alert: pops a reminder when balance drops below the set threshold; content is editable (includes image/random-image modules)
  • 💸 Today's budget: pops a reminder when today's usage reaches the set amount; content is likewise editable
  • 💬 Per-turn cost hint: a cost bubble pops after each turn ends; content is likewise editable (modular, amount via {cost}); content, auto-close seconds, and task-end sound are all set under menu → per-turn cost hint → "Customize hint"
  • All three support auto-close second settings; when bubble mode is unavailable they automatically degrade to a centered card (image modules are also rendered inside the card)

Sounds / Characters / Images

  • 🔊 Press & release sounds: two built-in presets, "Little Yellow Duck" and "Sound 1"; you can also import audio fragments and freely combine them into custom sound groups (a slot may be left empty = that event is muted)
  • 🎵 Task-end sound: played when a reply finishes; two built-in presets — default Minecraft·Experience Orb (assets/minecraft-exp-orb.wav) and A (assets/task-end-a.wav); any fragment or sound group can also be selected
  • ✂️ Audio fragment management: visual trimming and preview on import; the asset management window offers unified view/preview/delete
  • 🐳 Custom character: upload your own whale image (library management, can revert to default)
  • 🖼️ Bubble image library: two built-in images, petpet and money1; png/gif can also be uploaded, for use by image/random-image modules

Custom API (multi-vendor balance / quota)

In addition to the built-in DeepSeek balance, you can add any vendor under "Little Whale Bookkeeping → Models"; each model independently configures balance alert / today's budget / quota:

  • 🧩 Vendor templates (34, auto-fill credential name / currency / endpoint / field path / event match / probe URL after selection):
    • Can directly query balance or quota: DeepSeek (built-in), OpenRouter, Kimi / Moonshot (CN / International), StepFun, Novita, Zhipu GLM Coding Plan (Domestic / International z.ai), Kimi Coding, MiniMax Coding (Domestic / International), OpenCode Go (subscription, 5h / weekly / monthly three windows), OpenAI-compatible gateway (OneAPI / New API)
    • No official "query balance with API key" endpoint (marked as "(no balance endpoint)" in the dropdown; after selection, probeUrl verifies the key's liveness, balance displays "—", and today's usage is estimated from session events): SiliconFlow (CN / EN), Volcano Ark, OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Groq, Mistral AI, Together AI, Fireworks AI, DeepInfra, Cerebras, Aliyun Bailian (Tongyi Qianwen), Baidu Qianfan (Wenxin), Tencent Hunyuan, iFLYTEK Spark, ModelScope, local models (Ollama / LM Studio)
    • All manual: Custom HTTP (URL and field path written by you), Codex (local sessions, no endpoint needed)
  • 🔑 Secrets are not stored in config: keys are written to DSH's official credential service; the config file only stores the credential name (e.g. OPENROUTER_API_KEY); deleting a model also cleans up that model's quota module and settings
  • 💰 Balance: read via the template's endpoint and JSON field path (supports a.b[0].c and scale multipliers); "Test connectivity" can verify the key first
  • 📉 Today's usage: when a balance endpoint exists, records the observed decrease (first observation of the day sets the baseline; increases like top-ups never offset spend); vendors without a balance endpoint show a local session estimate
  • 🎯 Quota (subscription / resource pack): just fill the total; used amount is auto-accumulated from DSH session tokens (basis input + cacheRead + output, reasoning tokens included in output, persists across days); can also switch to manual entry; supports "no reset / daily / monthly"
  • 🧾 Subscription quota endpoint (kind:'quota' templates): directly reads the vendor's official "window used% + reset time", complementing the session-based quota above. Supports one endpoint returning multiple windows (currently OpenCode Go has 5h / weekly / monthly three windows), displaying used percentage and a compact reset countdown per window; templates describe each window's field paths via quota.json.windows
  • 💱 Unit price (optional): located at "Keys / Endpoints" panel → expand "Endpoints & Fields (Advanced)" → "Unit Price (Optional)". Each model can have its own unit price — cache hit / cache-miss input / output, units are "currency / 1M tokens"; currencies support CNY and USD, USD requires an exchange rate (CNY/USD); bookkeeping and the ledger settle uniformly in CNY (USD prices converted at the rate); unit prices are not peak/valley-split (both periods same price). Leave blank to use the built-in price list (DeepSeek flash / pro). Note: built-in DeepSeek does not support custom unit prices (always uses built-in peak/valley pricing); when quota unit is "Amount (CNY)", used amount must be entered manually
  • 🫧 Bubble modules: each model automatically gets two modules, "Balance·" and "Quota·", with placeholders {balance}, {today}, {quota}, {quota_used}, {quota_left}, {quota_total}, {quota_reset}

Note: Not all vendors provide a "query balance with API key" endpoint. SiliconFlow's balance endpoint has been officially retired (2026-08-11 release notes: /user/info stops serving from 2026-08-14, "a replacement API will be provided in due course", no replacement endpoint yet as of release), Volcano Ark's balance / usage and Aliyun Bailian / Baidu Qianfan / Tencent Hunyuan similarly belong to each cloud platform's AK/SK-signed OpenAPI, while OpenAI / Anthropic / Gemini / xAI / Groq / Mistral / Together / Fireworks / DeepInfra / Cerebras have no public balance-query endpoint at all — these templates uniformly use "no balance endpoint + key liveness probe", and today's usage is estimated from session events. Vendor subscription quota endpoints (Zhipu / Kimi Coding / MiniMax Coding / OpenCode Go) only work for subscription-plan accounts: Token resource-pack accounts calling the Zhipu endpoint will get "no coding plan for current user"; in that case use the "Quota (subscription / resource pack)" auto-statistics above.

Templates only provide default values: after selecting a template you can freely edit the endpoint URL and field paths; blank fields continue to use the template defaults (blank does not mean invalidated).

Codex Mode (local session statistics)

⚠️ Limitation: Codex support is currently only partial endpoint adaptation; this widget cannot be installed into Codex (it is a DSH Web plugin, and Codex is merely read as a data source); subscription windows have no real subscription sample to verify against, so please report any anomalies you encounter.

The widget can directly read local Codex session logs to tally token usage — so it is not limited to inside DSH; consumption you run in Codex CLI / desktop is also visible.

  • 📂 Data source: $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl (incl. archived_sessions/), plaintext JSONL; local files only, no network, no keys needed, never writes to ~/.codex
  • 📈 Stats basis: prefer the diff of cumulative totals (total_token_usage) from the log, which avoids double-counting when a turn has multiple records; model attribution decided by turn_context.payload.model; aggregate by day + model, with an incremental cache ($DSH_HOME/.dshw-codex.json, stores only aggregates and file offsets)
  • 🖥️ Display: model list shows Codex 今日 x · 近7天 y tokens; model submenu shows today / month / cumulative / last 7 days and session-file count; the "Test" button returns local stats directly
  • 🎯 Quota: for this model's "quota", the used source can optionally be Codex local session tokens (no reset = cumulative − baseline, daily = today, monthly = this month), reusing the same display and bubble module
  • 🪟 Subscription window (5h / weekly): the log's rate_limits carries a window snapshot; with a ChatGPT subscription, the submenu auto-appends 5h 已用 x% · 2小时30分后重置 | 周 已用 y% · 3天后重置 (field names are tolerant; the line is hidden for API-key billing or no subscription)

Directory layout

dsh-whale-widget/
├── package.json              # DSH bundle 插件元数据(dsh.bundle.patch 指向 cordis.patch.yml)
├── README.md                 # 本文件
├── cordis.patch.yml          # 插件挂载声明
├── lib/
│   ├── index.js              # 宿主侧插件本体(路由 + 记账 + 音效/图片/角色服务)
│   └── accounting.mjs        # 记账内核(定点金额运算 + 余额观测/校正账本)
├── assets/
│   ├── whale-widget.js       # 前端挂件本体(由宿主按 mtime 热读取)
│   ├── DSH2.png              # README 顶部展示图
│   ├── DSniang1.png          # 小鲸鱼本体(cut-out,气泡由代码绘制)
│   ├── DSniang02.png         # 备用整图(兼容旧版手动安装路径)
│   ├── rua.gif               # 随机台词/撒娇动图(可选)
│   ├── Ya1.mp3 / Ya2.mp3     # 预置音效「小黄鸭」按压 / 松开
│   ├── D1.mp3 / D2.mp3       # 预置音效「音效1」按压 / 松开
│   ├── minecraft-exp-orb.wav # 任务结束音内置默认音效(Minecraft·经验球)
│   ├── task-end-a.wav        # 任务结束音内置预设(A)
│   ├── bubble-petpet.gif     # 内置泡泡图:petpet
│   └── bubble-money1.gif     # 内置泡泡图:money1(余额预警默认内容的配图)
└── whale-widget-prompt.md    # 完整规格/维护提示词(面向二次开发)

Runtime data (all under $DSH_HOME, default ~/.dsh; the local dev environment is D:\TestBox\deepseek\):

File / DirectoryPurpose
.dshw-size.jsonWidget appearance and toggles (scale, volume, sound groups, peak style, snapping, etc.)
.dshw-usage.jsonAccounting ledger + per-day balance observation/correction summary + usage settings (task-end sound, balance warning, today's budget, per-turn cost notice content)
.dshw-usage.json.before-recharge-fix.bakBackup of the old-format ledger (0.3.1 creates it automatically before first writing the old ledger; existing files are not overwritten)
.dshw-turn.jsonPer-turn seq for consumption (prevents the frontend from mistaking a new turn for an old one after hot reload)
.dshw-bubble.jsonCustom bubble configuration (click sequence + module library + tap-role-advances-queue toggle)
.dshw-api.jsonCustom API model registry (vendor / credential name / endpoint fields / custom unit price / quota and usage accumulation; no secrets included)
.dshw-usage-archive.jsonLedger archive (per-turn details and per-day summaries past the retention period; details 90 days / 20k entries, per-day 365 days)
.dshw-codex.jsonCodex local session stats cache (aggregated by day/model + file offsets; contains no credentials)
whale-roles/Custom role images + roles.json index
whale-audio/Audio fragments <id>.wav + audio.json index (sound groups/fragments)
whale-bubble-imgs/Bubble image gallery + bubble-imgs.json index

Installation

Method A: you already have the full plugin resource package (local directory / archive) (recommended)

Use this when someone hands you a zip, or when you already have an unpacked plugin directory (the directory should contain package.json, cordis.patch.yml, lib/, assets/, README.md).

# 1) 若是 zip:先解压到一个固定、以后不会移动或删除的目录(不要放临时目录/下载目录)
#    例:D:\Plugins\dsh-whale-widget
#    要安装的是「包含 package.json 的那一层」,不要多套一层同名目录

# 2) 确认关键文件都在(缺 assets/ 会导致没图、没声)
Test-Path "D:\Plugins\dsh-whale-widget\package.json",
          "D:\Plugins\dsh-whale-widget\lib\index.js",
          "D:\Plugins\dsh-whale-widget\assets\whale-widget.js"

# 3) 如果之前从 GitHub / npm 装过同名插件,先卸载避免版本冲突
dsh plugin --profile web remove dsh-whale-widget

# 4) 用绝对路径安装(路径含空格要加引号)
dsh plugin --profile web add link:D:\Plugins\dsh-whale-widget

Notes:

  • link: is a symlink install: changes to files in the source directory take effect immediately; but after install you must not move/rename that directory — if you do, re-run add
  • To switch to a copy install: dsh plugin --profile web add file:D:\Plugins\dsh-whale-widget (from then on, source-directory changes are not synced; you must add again)
  • The resource package ships built-in assets such as assets/minecraft-exp-orb.wav, assets/task-end-a.wav, etc.; deleting files under assets silently degrades the corresponding features (no image / no sound)
  • After install, restart dsh web and press F5 to refresh the browser

Method B: install directly from GitHub

Clone locally, install in one command:

dsh plugin --profile web add github:MeteorNOX/DeepSeek-Balance-Whale-Widget

Notes:

  • After install the plugin shows up in DSH's plugin management page, where you can update it directly without running commands again
  • If your network requires a proxy, set the proxy environment variables first:
    $env:http_proxy="http://<ip>:<port>"; $env:https_proxy="http://<ip>:<port>"; $env:all_proxy="socks5://<ip>:<port>"; dsh plugin --profile web add github:MeteorNOX/DeepSeek-Balance-Whale-Widget
    
  • After installation, restart dsh web, then press F5 to refresh the browser

Method C: local install (from the current repo)

Run this in the repo root (the directory containing package.json):

dsh plugin --profile web add link:.

Notes:

  • dsh plugin 会把参数转发给 pnpm,并在成功后自动把 dsh-whale-widget 加入 dsh.profile.bundles
  • link:. 表示链接当前目录(仓库根目录本身就是插件包)。如果仓库在别处,用绝对路径:
    dsh plugin --profile web add link:D:\你的路径\DeepSeek-Balance-Whale-Widget
    
  • ⚠️ 不要用 link:.\dsh-whale-widget——仓库里没有 dsh-whale-widget/ 子目录,这样会安装成普通依赖而非插件
  • 安装完成后重启 dsh web,再 F5 刷新浏览器
  • 移动了源码目录后必须重新执行一次 add link:<新路径>;若提示冲突,先 dsh plugin --profile web remove dsh-whale-widget 再 add

Method D: install after publishing to npm

dsh plugin --profile web add dsh-whale-widget

Installation instructions for AI (copy-paste to an AI assistant)

请帮我安装插件 dsh-whale-widget。可能的来源有两种:GitHub 仓库
MeteorNOX/DeepSeek-Balance-Whale-Widget,或者我本地已经有这个插件的「完整资源包」。

步骤:
1. 确保 pnpm 可用(没有就先:npm install -g pnpm)
2. 在 Web profile 安装(按我实际拿到的来源任选一种):

   【来源一:从 GitHub 安装】
     dsh plugin --profile web add github:MeteorNOX/DeepSeek-Balance-Whale-Widget
   或从本地 git 仓库链接安装:
     dsh plugin --profile web add link:<仓库绝对路径>
   (注意:仓库根目录就是插件包,不要写成 link:.\dsh-whale-widget 这种带子目录的路径)

   【来源二:我本地已有完整资源包(zip 或已解压目录)】
   先确认「完整资源包」长什么样:一个目录,里面应当有
     package.json、cordis.patch.yml、lib/index.js、
     assets/(含 whale-widget.js、DSniang1.png、Ya1.mp3、minecraft-exp-orb.wav、task-end-a.wav 等)、README.md
   然后按下面做:
   a) 如果给我的是 zip:先解压到一个**固定、以后不会移动或删除**的目录,例如
        D:\Plugins\dsh-whale-widget
      不要解压到临时目录/下载目录/会被清理的位置;也不要多套一层——
      要安装的是**包含 package.json 的那一层**,不是外面那个同名压缩包目录
   b) 检查文件完整性(任意一条 False 就先告诉我,不要继续装):
        Test-Path "<资源包目录>\package.json"
        Test-Path "<资源包目录>\lib\index.js"
        Test-Path "<资源包目录>\assets\whale-widget.js"
      并确认 package.json 里 name 是 dsh-whale-widget、带 dsh.bundle.patch 字段
   c) 如果之前从 GitHub / npm 装过同名插件,先卸载避免版本冲突:
        dsh plugin --profile web remove dsh-whale-widget
   d) 用**绝对路径**安装(路径含空格要加引号):
        dsh plugin --profile web add link:<资源包目录>
      link: 是软链安装:源目录改了立即生效,但安装后不能移动/重命名该目录;
      移动后必须重新执行一次 add。若想按拷贝安装可用:
        dsh plugin --profile web add file:<资源包目录>
      (file: 以后源目录改动不会同步,需要重新 add)

3. 如果报 pnpm 阻止构建脚本(allowBuilds 相关),在 ~/.dsh/profiles/web/pnpm-workspace.yaml 的
   allowBuilds 下加对应 key,然后重跑
4. 重启 dsh web,然后 F5 刷新浏览器

安装后验证:
- dsh --profile web --dump-config 应该能看到 dsh-whale-widget 在 bundles 里
- curl http://127.0.0.1:3080/dsh-whale/balance.json 应返回 200 JSON(含 totalBalance)
- curl http://127.0.0.1:3080/dsh-whale/widget.js 应返回 200 JS
- curl "http://127.0.0.1:3080/dsh-whale/audio-fragment.wav?id=exp_orb" 应返回 200 audio/wav
- curl "http://127.0.0.1:3080/dsh-whale/audio-fragment.wav?id=end_a" 也应返回 200 audio/wav
  (用来确认资源包里的内置音效已随包就位;若是 404 说明 assets/ 不完整)

另外请检查 DSH 凭据里是否配置了 DEEPSEEK_API_KEY(没有就提示用户配置)。

凭据(安装后必读)

只需一个凭据:

  • DEEPSEEK_API_KEY (required): DeepSeek API key, used to fetch the balance (GET https://api.deepseek.com/user/balance). Configure it in the DSH credentials service (the credential management UI / .dsh/.credentials.yaml).

DEEPSEEK_PLATFORM_TOKEN is not needed. The early "live·token" mode has been retired; today's usage is now computed uniformly by Little Whale accounting (balance delta + session events) and works out of the box with zero tokens.

添加自定义模型时,还会按需用到各自厂商的凭据名(都可不配,用到哪个配哪个):

Credential namePurpose
OPENROUTER_API_KEYOpenRouter balance (/api/v1/credits)
MOONSHOT_API_KEYKimi / Moonshot CN balance (CNY)
MOONSHOT_INTL_API_KEYKimi / Moonshot international balance (USD, separate account system)
SILICONFLOW_API_KEYSiliconFlow /v1/models reachability check
ARK_API_KEYVolcano Ark /api/v3/models reachability check
ZHIPU_API_KEYZhipu (subscription quota endpoint / Coding endpoint)
OPENCODE_GO_API_KEYOpenCode Go subscription quota (opencode.ai/zen/go/v1/usage, auth is Authorization: Bearer <key>)
CUSTOM_API_KEYCustom HTTP / OpenAI-compatible relay

⚠️ 自定义模型面板里的「凭据名」决定密钥写进哪个 ref。换厂商时请确认这一栏跟着模板变了,否则新密钥会写进上一家厂商的凭据名里(覆盖掉原来的 key)。v679 起新增模型会自动跟随模板。

Uninstall

dsh plugin --profile web remove dsh-whale-widget

从旧手动安装升级

If you previously installed manually the old way (copying whale-balance.mjs + editing cordis.patch.yml), clean up first:

$web = "$env:USERPROFILE\.dsh\profiles\web"

Remove-Item "$web\whale-balance.mjs" -ErrorAction SilentlyContinue
Remove-Item "$web\whale-balance.cjs" -ErrorAction SilentlyContinue
Remove-Item "$web\DSniang1.png" -ErrorAction SilentlyContinue
Remove-Item "$web\DSniang02.png" -ErrorAction SilentlyContinue

Then edit $web\cordis.patch.yml and remove this old patch:

- insert:
    - id: whale-balance-widget
      name: ./whale-balance.mjs?v=1

如果里面只有这段,直接改成:

[]

清理后再执行上面的安装命令。

Verification

dsh --profile web --dump-config | Select-String -Pattern "whale"

curl http://127.0.0.1:3080/dsh-whale/balance.json
curl http://127.0.0.1:3080/dsh-whale/size.json
curl http://127.0.0.1:3080/dsh-whale/widget.js
curl http://127.0.0.1:3080/dsh-whale/image.png
curl http://127.0.0.1:3080/dsh-whale/audio.json
  • /dsh-whale/balance.json → 200 JSON, containing {ok:true, totalBalance, currency, todayUsage}
  • /dsh-whale/size.json → GET returns the config; PUT writes it
  • /dsh-whale/widget.js → 200 JS (the frontend widget body)
  • /dsh-whale/image.png → 200 image/png
  • /dsh-whale/audio.json → 200, containing groups / fragments (built-in fragments: exp_orb = Minecraft·Experience Orb, end_a = A)
  • /dsh-whale/audio-fragment.wav?id=exp_orb → 200 audio/wav (built-in task-end sound; no user import needed)
  • /dsh-whale/audio-fragment.wav?id=end_a → 200 audio/wav (built-in task-end sound A)
  • After F5 in the browser, the widget appears in the bottom-right corner

⚠️ About the curl calls above: all 21 /dsh-whale/* routes are now behind the DSH browser trust fence (connection.requestRejection). Therefore bare curl without session credentials returns 401 (spoofed Host header returns 403) — this is expected behavior, not a broken API. To verify the API is alive, see a 401/403 response, which means the route is registered and the fence is working; accessing the same path in a browser (with the session) yields 200.

FAQ

  • Widget doesn't appear: confirm the install command succeeded; dsh --profile web --dump-config shows dsh-whale-widget; restart dsh web then F5.
  • Images/sounds not showing, no sound: confirm the plugin's assets/ is complete (DSniang1.png, *.mp3, minecraft-exp-orb.wav, etc.); missing files silently degrade the features.
  • Balance reports "DEEPSEEK_API_KEY not configured": set it up in DSH credentials.
  • Today's usage shows --: wait for one successful balance observation first; stats start from that observation time — consumption before it is outside the interval.
  • Today's usage differs from the official site: first verify same account, same currency, and same stats interval; if there was a recharge or other balance adjustment, use "Little Whale accounting → DeepSeek (built-in) → Settings → Balance correction" to enter the actual credited amount. The balance API only returns a balance snapshot, not recharge history; when a recharge and spending fall within the same refresh interval, the actual credited amount is needed for correction.
  • Spending number didn't change after recharging: expected — a recharge doesn't increase spending; a "pending balance adjustment to reconcile" notice appears above the number, prompting you to add the cumulative credited amount for this stats interval.
  • Per-turn cost not showing: confirm "auto-show cost after each turn" is checked in the menu; a full turn must end (turn/end) before settlement. When the balance-change bubble and the cost bubble compete for the layer, the notice degrades to a centered card.
  • Per-turn cost bubble content: Menu → Per-turn cost notice → "Custom notice" to edit (modular, amount uses {cost}); you can also set auto-close seconds and the task-end sound here.
  • Task-end sound didn't play: this toggle defaults to off (the built-in Minecraft·Experience Orb is selected by default; a built-in preset A is also available); turn it on under Menu → Per-turn cost notice → "Custom notice". If a custom fragment file is deleted, it falls back / mutes.
  • Can't drag the whale on mobile: this version has taken over dragging with touch events; do a hard refresh to fetch the latest whale-widget.js; if it still fails, report your browser version.
  • Menu button hidden — how to open the menu: right-click the whale on desktop, long-press the whale for ~1.5 s on mobile.
  • Frontend code changes not taking effect: the frontend assets/whale-widget.js is hot-read by the host by mtime, so a hard refresh (Ctrl+F5) is enough; changes to the host's lib/index.js require restarting dsh web.
  • Can't read the model name: the ledger records the API model id; deepseek-flash is DeepSeek-V4.1-Flash, and the old names deepseek-v4-flash / -vision-exp are now also served by the same V4.1-Flash and priced as Flash (the panel is annotated).

Pricing table

金额按 CNY / 百万 tokens 计,[空闲时段, 高峰时段];高峰 = 工作日 9:00–12:00、14:00–18:00(北京时间),空闲价为高峰价的一半;2026-08-23 起周末全天按谷价。表在 lib/index.js 顶部 PRICING / BASE_PRICE / PRO_PRICE,官方调价时改这里。

ModelCache hitCache missOutput
deepseek-flash (DeepSeek-V4.1-Flash)0.02 / 0.041 / 24 / 8
deepseek-v4-pro (V4 Pro)0.15 / 0.304.5 / 9.013.5 / 27.0

Old model names deepseek-v4-flash and deepseek-v4-flash-vision-exp remain callable, billed at Flash prices.

开发与维护

  • In the repo, lib/index.js is the host body, lib/accounting.mjs is the accounting kernel (fixed-point money math + observation/correction ledger), and assets/whale-widget.js is the frontend body; host changes (including the accounting kernel) require restarting dsh web, while frontend-only changes take effect with a hard refresh.
  • Full specs, visual parameters, route list, architecture decisions and the generation prompt are in whale-widget-prompt.md.
  • Local dev loop: after dsh plugin --profile web add link:., edit frontend → Ctrl+F5; edit host → restart dsh web.

致谢

  • The recharge-logging fix (separately accounting for balance increases vs. decreases, an explicit balance-correction formula, per-account/currency observation windows, atomic ledger writes and migration backup) was independently designed and implemented as a working fix branch by GitHub user @Yang-huai406; 0.3.1 ports and merges it on top of that solution and retains this project's existing sound fixes. Thanks for his support.
  • OpenCode Go subscription quota (multi-window quota quota.json.windows, per-window display and compact reset countdown, window selection in the "subscription quota" module) was contributed by GitHub user @ELFsay (#99), now merged into main. Thanks for his contribution.
  • Contributors of past merged PRs (in merge order, all already in this repo's code / release flow):
    • @ztzpro (#1): transformed the balance whale widget into a standard DSH plugin package (today's cordis.patch.yml + bundle structure comes from here);
    • @under-the-ocean (#6 / #7): automatic npm publishing on push, upgrading npm for Trusted Publishing (OIDC) support — the current release flow is still this one;
    • @21253soursweetlemon (#16 / #18): fall back to text lines when a gif fails to load, right-edge scrollbar avoidance, anchor position memory (no floating on window changes, snaps back to place — the starting point of the position system);
    • @fangbm (#15 / #19 / #31 / #33 / #46): stable ordering for multi-currency balances, two defects in the per-turn cost bubble, weekends off-peak all day, currency-aware accounting, auto-creating a Release and generating a PR changelog at publish time;
    • @xiaolinnnnnnn (#26): Windows desktop (Tauri v2) refactor.

License

The code of this project is open-sourced under the MIT License. See LICENSE for details.

⚠️ Art assets under assets/ (images / animated images / sound effects) are NOT covered by the MIT license: they are provided by the maintainers or generated with AI tools, are distributed with the plugin "as-is", and are solely for running this plugin. No re-licensing rights are granted, nor are they claimed as original works. For per-item sourcing, metadata cleanup notes, and takedown procedures, see PROVENANCE.md.

Compatibility

DSH 0.1.7-alpha.1: failedDSH 0.2.1-alpha.2: failedDSH 0.2.0-rc.1: failed

Versions

Latest versionPublishedSize
0.1.0——
0.2.1——
0.2.6——
0.2.8——
0.2.10——
0.2.7——
0.3.1——
0.3.2——
0.3.0——
0.3.18——
0.3.3——
0.3.4——
0.3.5——
0.3.7——
0.3.6——
0.3.9——
0.3.8——
0.3.10——
0.3.11——
0.3.12——

Comments

Loading…

Similar plugins

DeepSeek-Balance-Whale-Widget-Bowl

by Witherwithwinter

DeepSeek Harness(DSH)Web 界面右下角的常驻余额挂件。基于 MeteorNOX/DeepSeek-Balance-Whale-Widget 修改的铁盆鲸鱼娘版。

UI & ExperienceManifest valid

★ 33

MIT

JavaScript

Oct 5, 2026

dsh plugin --profile web add dsh-whale-widget-bowl

by ShanHaiFish

DeepSeek Harness 悬浮鲸鱼娘宠物:跟随会话模型显示 OpenCode Go 三窗口额度、DeepSeek 账户累计消费/余额、DeepSeek 官方 API 余额。

Manifest valid

★ 0

MIT

JavaScript

Oct 21, 2026

dsh plugin --profile web add dsh-usage-pet

by chencujinlin

DSH / DeepSeek Harness 桌面端鲸鱼娘开场动画插件:原生加载联动、工作台就绪后拍走提示、衔接右下角挂件。

Manifest valid

★ 0

Python

Oct 20, 2026

dsh plugin --profile web add dsh-whale-startup

by Win-Hao

像素化的 DeepSeek 小鲸鱼,浮在 dsh web 右下角,跟着你的 Harness 会话状态做反应。A DSH plugin: the DeepSeek whale as a pixel-animated desktop pet.

Manifest valid

★ 0

MIT

JavaScript

Aug 20, 2026

dsh plugin --profile web add seek-on-dsh

by Andersen216

鲸鱼娘桌宠:DSH Web 界面里的 Live2D 桌宠(模型素材非商业,CC BY-NC-SA 4.0)

Just for FunManifest valid

★ 68

NOASSERTION

JavaScript

Oct 20, 2026

dsh plugin --profile web add dsh-whale-girl-live2d

by Linzr-lly

趴趴鲸鱼娘 🐋 趴在 DeepSeek Harness 对话框上的二次元鲸鱼娘桌宠插件:手绘 SVG、灵动动态、零外部依赖

Manifest valid

★ 0

JavaScript

Aug 20, 2026

dsh plugin --profile web add dsh-whale-lap