Skip to content

Dashboard: DeepSeek tab renders no statistics — no deepseek branch in the card render dispatch (Moonshot likely affected too) #137

Description

@t1p

Summary

On v2.14.5 the DeepSeek dashboard tab (/?provider=deepseek) renders no balance cards and no statistics at all, even though the backend collects and serves the data correctly. The tab falls through to the Synthetic default renderer, so the card grid stays empty and the usage chart shows the Synthetic dataset labels with 0 points.

Moonshot (the other balance-based provider) looks affected by exactly the same gap.

Environment

  • onWatch v2.14.5 (linux/amd64), self-hosted, dashboard on :9211
  • Reproduced in a fresh browser session (no cached JS) and directly against the API
  • DEEPSEEK_API_KEY set in .env; provider_visibility.deepseek = {"dashboard":true,"polling":true}
  • DeepSeek polling works: balance snapshots are written every 2 min

Steps to reproduce

  1. Configure DEEPSEEK_API_KEY so the DeepSeek provider is enabled.
  2. Open http://localhost:9211/?provider=deepseek.

Expected

Total / Granted / Topped-Up balance cards populated from /api/current?provider=deepseek, as documented for DeepSeek in the README.

Actual

  • The quota grid exists but is empty: document.getElementById('quota-grid-deepseek').children.length === 0 (no innerHTML).
  • "Usage Insights" → "Unable to load insights."
  • The usage chart shows the Synthetic datasets (Subscription, Search, Tool Calls) with 0 points each.
  • Session History / Logging History / Cycle Overview show empty states.

Contrast: the Codex/Anthropic tabs render fine.

Backend is fine (curl evidence)

GET /api/current?provider=deepseek
→ 200 {"balance":{"available":true,"total":4.02,"toppedUp":4.02,"granted":0,"currency":"USD",
       "description":"DeepSeek API balance","avgPerCycle":0.03,"completedCycles":1,"rate":0.04,"status":"healthy",...}}

GET /api/history?provider=deepseek&range=24h   → 200 (46 KB; total_balance / granted_balance / topped_up_balance)
GET /api/logging-history?provider=deepseek&range=24h → 200 (121 KB)
GET /api/sessions?provider=deepseek            → 200 (8 KB)
GET /api/insights?provider=deepseek            → 200 {"stats":[],"insights":[]}

So the data is present; only the client rendering is missing.

Root cause

In internal/web/static/app.js (v2.14.5), the card render dispatch that runs after GET /api/current only branches for these providers:

copilot, anthropic, codex, antigravity, minimax, gemini, cursor,
openrouter, grok, kimi, opencode, ollama, muse, commandcode, zai

There is no else if (provider === 'deepseek') (and none for moonshot). Therefore provider === 'deepseek' falls through to the final default branch — the Synthetic renderer:

} else if (provider === 'zai') {
  updateCard('tokensLimit', data.tokensLimit);
  updateCard('timeLimit', data.timeLimit);
  updateCard('toolCalls', data.toolCalls);
} else {
  updateCard('subscription', data.subscription);
  updateCard('search', data.search);
  updateCard('toolCalls', data.toolCalls);
}

/api/current?provider=deepseek returns { capturedAt, balance } — no subscription/search/toolCalls — so updateCard(...) finds no matching elements and nothing is rendered. That matches the empty #quota-grid-deepseek and the Synthetic chart labels.

Confirming grep on the shipped asset (/static/app.js, 556 976 bytes):

$ grep -n -i deepseek app.js
6952:  } else if (provider === 'minimax' || provider === 'gemini' || provider === 'openrouter' || provider === 'moonshot' || provider === 'deepseek') {
7372:  if (provider === 'deepseek') { ... chart datasets ...
7380:    return buildDynamicDatasetsForRows(rows, range, dsDisplayNames, dsColors, dsFallback, 'deepseek');
7718:    } else if (slot.provider === 'deepseek') { ... chart datasets ...
7722:      datasets = createDynamicDatasets(slot.rows, dsDN, dsCM, dsFB, 'deepseek');
8062:  const usePercent = ... || provider === 'deepseek' || ...
8063:  const deltaUsesPercent = usePercent && provider !== 'minimax' && provider !== 'moonshot' && provider !== 'deepseek';
12557:      <option value="deepseek" ...>DeepSeek</option>

All 8 hits are in chart/settings code — there is no card renderer for deepseek (nor moonshot), even though the chart dataset builders already know the balance fields (total_balance, granted_balance, topped_up_balance).

Also note: internal/web/static/app.js on main is byte-identical to v2.14.5 (both 556 976 bytes, identical deepseek lines), so this is not fixed yet on main.

Suggested fix

Add a deepseek (and moonshot) branch to the dispatch that renders the balance cards from data.balance — e.g. Total / Granted / Topped-Up — reusing the existing card markup/classes for balance providers.

Happy to open a PR if you can point me at the preferred card markup/CSS classes for balance-based providers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions