wenzetan/dsh-quota-panel3

dsh-quota-panel

Provider quota/balance widget for the dsh web surface: collapsed glanceable capsule expanding into a Harness-native card with a settings panel (provider visibility / refresh interval / warn thresholds), fed by a loopback Connection RPC channel whose host half proxies each provider with credentials that never reach the browser.

包名
dsh-quota-panel
版本
0.8.1-rc.5
许可证
MIT
最近更新
2026年8月19日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:wenzetan/dsh-quota-panel

Configuration

Out of the box: nothing. Install, restart, and any provider whose key resolves appears automatically. The table below is only for tuning.

All keys are optional — the structure and defaults live in the exported Config schema, so profile patches may omit every defaulted field.

KeyMeaningDefault
autoprobe the built-in catalog; providers with a resolvable key join the paneltrue
hiderow ids to drop (catalog and explicit rows alike)[]
proxiesnamed proxy definitions {: "http://host:port"}, HTTP(S) only{}
catalogpartial overrides for auto-discovered rows {: {...}}{}
refreshMsauto-refresh interval60000
providersexplicit rows; a same-id entry replaces the catalog row wholesale[]

Each catalog override may set: label / endpoint / format / proxy / refs (credential references to probe, UPPER_SNAKE) / currency (balance rows: symbol like $ or US$) / balanceTiers / warnPercent / errorPercent / windowLabels.

Explicit providers fields:

FieldMeaningDefault
idrow id (RPC rows align by id), ^[a-z0-9-]+$required
labelprovider name shown on the cardrequired
credentialcredential reference ($DSH_HOME/.credentials.yaml or environment)required
endpointquota JSON endpoint; base URL for openai-billingrequired
formatrow adapter (see table below)deepseek-balance
proxya proxy name defined in proxies; absent = direct
currency(balance rows) currency symbol, overrides the format defaultformat default
balanceTiers(balance rows) {critical, warn, healthy}{10, 20, 50}
lowBalancelegacy alias for balanceTiers.warn
windowLabels(usage-kind formats) labels for the usage windows{滚, 周, 月}
warnPercent / errorPercent(usage rows) thresholds70 / 90

Built-in provider catalog (auto discovery)

ProviderCredential refs probedEndpointRow kind
DeepSeekDEEPSEEK_API_KEYapi.deepseek.com/user/balance¥ balance
OpenRouterOPENROUTER_API_KEYopenrouter.ai/api/v1/credits$ balance (purchased − used)
SiliconFlow (global)SILICONFLOW_API_KEYapi.siliconflow.com/v1/user/info$ balance
SiliconFlow (CN)SILICONFLOW_CN_API_KEYapi.siliconflow.cn/v1/user/info¥ balance
Moonshot / KimiMOONSHOT_API_KEYapi.moonshot.cn/v1/users/me/balance¥ balance
MiniMax Coding (global)MINIMAX_API_KEYwww.minimax.io/v1/token_plan/remains5h prompt usage %
MiniMax Coding (CN)MINIMAX_CN_API_KEYapi.minimaxi.com/v1/token_plan/remains5h prompt usage %
StepFunSTEP_API_KEY / STEPFUN_API_KEYapi.stepfun.com/v1/accounts¥ balance (hover: cash/voucher)
xAIXAI_API_KEYapi.x.ai/v1/billing/credits$ balance
Zhipu GLMZHIPU_API_KEY / GLM_API_KEYopen.bigmodel.cn/api/monitor/usage/quota/limittext row (quota remaining/total; no public balance API)
智谱 GLM CodingZAI_CODING_CN_API_KEYopen.bigmodel.cn/api/monitor/usage/quota/limitcoding-plan windows (5h tokens / weekly / searches)
Z.AI GLM CodingZAI_API_KEYapi.z.ai/api/monitor/usage/quota/limitcoding-plan windows (5h tokens / weekly / searches)
Kimi CodingKIMI_API_KEYapi.kimi.com/coding/v1/usagesusage % (5h rate limit + weekly request pool)
OpenCode GoOPENCODE_GO_API_KEYopencode.ai/zen/go/v1/usagethree-window usage %

An additional openai-billing format adapts one-api / new-api style aggregators: set endpoint to the aggregator base URL and the host half requests {base}/v1/dashboard/billing/subscription (hard_limit_usd) plus {base}/v1/dashboard/billing/usage (total_usage); remaining = limit − used ($). Aggregator domains differ per deployment, so this format is explicit-config only.

Dual-site provider ids (custom id → site mapping)

Some providers run separate international and China sites with different endpoints, credential references and currencies. The catalog models each site as its own provider id, so configuring the matching key is all it takes — and an explicit providers: entry reusing one of these ids replaces the catalog row wholesale (same fields, your endpoint/label/currency):

provider idSiteEndpointCredential refCurrency
siliconflowSiliconFlow globalapi.siliconflow.com/v1/user/infoSILICONFLOW_API_KEY$
siliconflow-cnSiliconFlow Chinaapi.siliconflow.cn/v1/user/infoSILICONFLOW_CN_API_KEY¥
minimaxMiniMax Coding globalwww.minimax.io/v1/token_plan/remainsMINIMAX_API_KEY— (usage %)
minimax-cnMiniMax Coding Chinaapi.minimaxi.com/v1/token_plan/remainsMINIMAX_CN_API_KEY— (usage %)
zaiZ.AI GLM Coding globalapi.z.ai/api/monitor/usage/quota/limitZAI_API_KEY— (usage %)
zai-coding-cn智谱 GLM Coding Chinaopen.bigmodel.cn/api/monitor/usage/quota/limitZAI_CODING_CN_API_KEY— (usage %)

Both sites of one provider can be on the panel at the same time (configure both keys); hide: ["siliconflow"] drops either row individually.

The currency symbol for balance-kind rows comes from the format by default (siliconflow-balance renders ¥) and can be overridden per row: catalog rows carry currency (the global SiliconFlow row sets $), a catalog: override may set it, and explicit providers: entries accept a currency field (e.g. "US$").

Built-in formats

formatRow kindUpstream response shape
deepseek-balance¥ balance{ balance_infos: [{ currency, total_balance, granted_balance, topped_up_balance }] }
openrouter-credits$ balance{ data: { total_credits, total_usage } }
siliconflow-balancebalance (¥ by default, per-row currency override){ data: { balance, chargeBalance, totalUsage } }
moonshot-balance¥ balance{ data: { total_balance } }
minimax-remainsusage %{ base_resp, model_remains: [{ model_name, current_interval_total_count, current_interval_usage_count, current_interval_remaining_percent, end_time, current_weekly_total_count, current_weekly_usage_count, weekly_end_time }] } — coding model row (MiniMax-M*) preferred; counts are remaining-side (used = total − count); weekly window only when current_weekly_total_count > 0
stepfun-accounts¥ balance{ balance, total_cash_balance, total_voucher_balance }
xai-credits$ balance{ total: { val } } (cents → dollars)
openai-billing$ balanceaggregator dashboard/billing endpoints
zhipu-quotatext{ code: 200, data: { limits: [{ remaining, number }] } } (limits without remaining fall back to percentage)
opencode-usageusage %`{ usage: { rolling
zai-coding-quotausage %{ code: 200, data: { limits: [{ type: TOKENS_LIMIT | TIME_LIMIT, unit, number, percentage, currentValue, usage, nextResetTime }] } } — semantic mapping (glm-plan-usage2, issue #2): TOKENS_LIMIT unit=3 → 5h window, unit=6 → weekly, TIME_LIMIT → MCP monthly lane; unknown units fall back to nextResetTime ordering; every window prefers the percentage field
kimi-coding-usageusage %{ usage: { limit, used, remaining, resetTime }, limits: [{ window: { duration, timeUnit }, detail: { limit, used, remaining, resetTime } }] } — 5h = the duration=300 window, weekly = duration=10080 (fallback: top-level usage); used = limit − remaining

Proxy (providers that cannot be reached directly)

Configure per-provider proxies in the frontend settings panel (⚙ → 代理): fill an HTTP(S) proxy URL (e.g. http://127.0.0.1:7890, user:pass allowed), saved to browser localStorage, effective immediately — leave it empty to fall back to the profile config or a direct connection. Requests still run host-side: the browser sends each row's proxy URL in the fetch-all payload, the host validates it (http/https only, socks rejected) and fetches through it — keys never reach the browser, but the proxy itself can observe them (see Known issues & risks under Security).

The profile proxies map + row-level proxy / catalog..proxy remain available as default proxies (used when the frontend field is empty). Precedence: frontend settings > profile config > direct.