# 架构 ## 整体结构 (v0.1.0) ``` ┌─────────────────────────────────────────────────────────────┐ │ DSH webview (浏览器) │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ conversation.composer.bar (DSH ship 容器) │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ │ │ [+][Full access]│[musage inline]│[model][↗] │ │ │ │ │ └──────────────────────────────────────────┘ │ │ │ │ modes (DSH flex) ↑↑↑ 我们注册到 .trailing │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ▲ │ │ 同源 fetch (JSON) │ webServer 路由 │ GET /musage/quota │ (后台轮询 / 缓存) │ ?provider=minimax|deepseek|... ▼ ▼ ┌─────────────────────────────────────────────────────────────┐ │ DSH host (Node.js) │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ musage-minimax-quota Plugin (host) │ │ │ │ - 定时器 60s → 走 PROVIDERS[provider] 查表 │ │ │ │ - 30s TTL 缓存, 错误指数退避 (5s base, 30min cap) │ │ │ │ - 5 个 provider 通用路径 (minimax / deepseek / │ │ │ │ kimi / openrouter / zhipu), 每个独立 schema 解析 │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ │ subprocess.spawn({argv: ['curl', '-H', 'Bearer xxx', url]})│ │ ▼ │ │ DSH subprocess Service (subprocess-local) │ │ │ HTTPS │ │ ▼ │ │ api.minimaxi.com / api.deepseek.com / api.kimi.com / │ │ openrouter.ai / open.bigmodel.cn │ └─────────────────────────────────────────────────────────────┘ Client 端: ┌─────────────────────────────────────────────────────────────┐ │ InlineReadout (React) │ │ - useEffect subscribe ctx.modelDirectories.directoryFor(sessionId)│ │ - 状态变化 → setProvider(route → mapped) │ │ - useEffect 依赖 [provider, timer] → fetch('/musage/quota │ ?provider=
') │
│ - renderDisplay 按 provider 分发 5h/7d 双窗 或 余额 │
└─────────────────────────────────────────────────────────────┘
```
## 关键设计
### 1. 复用 DSH 已配 key (零凭证输入)
- 不读本地 `keys.json`, 走 DSH `credentials.resolve(ref)`
- ref 名按 DSH 客户端设置规则: `${PROVIDER_UPPER}_API_KEY`
- `minimax-cn` → `MINIMAX_CN_API_KEY`
- `deepseek` → `DEEPSEEK_API_KEY`
- `kimi-coding` → `KIMI_CODING_API_KEY`
- `zai-coding-cn` → `ZAI_CODING_CN_API_KEY`
- `openrouter` → `OPENROUTER_API_KEY`
- 用户在 DSH 模型设置里配的 key 直接被用, plugin 完全不碰密钥存储
### 2. 多 provider 通用 host
- `PROVIDERS` 注册表: 每个 entry 含 `refs / urls / parse / authStyle?`
- `fetchProviderQuota(provider)` 查表, 走同一段 curl + 解析流程
- 5 个 parser 各自独立 (从 Musage 各 rs 文件抄 schema):
- `parseMinimaxResponse`: 2026-06-01 双 schema (percent-based / count-based)
- `parseDeepseekBalance`: `balance_infos[].total_balance` (v0.0.20 修对, 不是老 ccswitch `balance[]`)
- `parseKimiResponse`: `limits[].detail.{limit,remaining,resetTime}` + `usage.{...}`
- `parseOpenrouterResponse`: `total_credits - total_usage` = 余额
- `parseZhipuResponse`: `unit=3` (5h) + `unit=6` (周) 双窗口, **智谱特殊 `Authorization: