Symptom
Add a quota/remaining row to the menu bar first section (currently Input / Output / Total in `StatusPopover.swift:138-197`) showing the remaining subscription quota for the enabled vendor(s) in Model Routing.
Research is complete — full findings, comparison table, third-party solutions, feasibility, architecture impact, and open UX decisions are written up here:
📄 docs/01-discovery/2026-06-05-vendor-quota-query-api-research.md
Read that doc first when starting implementation — it has everything needed to start fast.
Research summary
| Vendor / Plan |
API+KEY quota query? |
Auth |
| MiniMax Token/Coding Plan |
✅ Yes — GET /v1/token_plan/remains, Bearer, same model KEY |
reuse vendor KEY |
| 火山 Agent Plan |
⚠️ GetAFPUsage but needs AK/SK V4 signing (not inference key) |
separate credential |
| 火山 Coding Plan |
❌ No stable API (rate-limit headers only) |
— |
| 阿里百炼 Token Plan |
❌ Needs BSS OpenAPI AK/SK; Token Plan keys banned from automation polling |
separate credential + ban risk |
Recommendation (from doc §5)
- Phase 1 = MiniMax only — reuses the vendor's stored KEY, zero new credentials, zero ban risk. Build skeleton:
Vendor.quotaProvider enum + new Services/QuotaService + menu-bar quota row.
- Phase 2 — evaluate whether Volcengine/Bailian justify making the user enter AK/SK, given Bailian's automation-ban line.
Open decisions (need user confirmation before coding — new user-visible View)
- Quota row form: new row below Input/Output/Total, or 4th column? Multiple enabled vendors → show all or one?
- Scope: MiniMax-only first, or add Volcengine/Bailian AK/SK fields in the same pass?
- Bailian: skip auto-query (console only) or accept ban risk with manual refresh?
Prior Hypotheses
N/A — enhancement, not a bug.
Related Files
- `ModelProxy/Views/StatusPopover.swift:138-197` — first row renderer (`tokenSummaryCard`)
- `ModelProxy/Models/Vendor.swift:25-53` — vendor model (no type field; add `quotaProvider`)
- `ModelProxy/Models/ModelMapping.swift` / `ModelProxy/Proxy/RoutingSnapshot.swift:103` — `isEnabled` defines "enabled vendor"
- `ModelProxy/Services/TokenStatsStore.swift` — existing stats store pattern
- `docs/01-discovery/2026-06-05-vendor-quota-query-api-research.md` — full research doc
Notes
"Enabled = subscribed" is a heuristic with a caveat: enabling a mapping only means "route here", not "this vendor uses a subscription plan". A MiniMax vendor could hold a pay-as-you-go KEY (no plan to query). Implementation must gracefully hide quota when the endpoint returns 401/empty.
Symptom
Add a quota/remaining row to the menu bar first section (currently Input / Output / Total in `StatusPopover.swift:138-197`) showing the remaining subscription quota for the enabled vendor(s) in Model Routing.
Research is complete — full findings, comparison table, third-party solutions, feasibility, architecture impact, and open UX decisions are written up here:
📄
docs/01-discovery/2026-06-05-vendor-quota-query-api-research.mdRead that doc first when starting implementation — it has everything needed to start fast.
Research summary
GET /v1/token_plan/remains, Bearer, same model KEYGetAFPUsagebut needs AK/SK V4 signing (not inference key)Recommendation (from doc §5)
Vendor.quotaProviderenum + newServices/QuotaService+ menu-bar quota row.Open decisions (need user confirmation before coding — new user-visible View)
Prior Hypotheses
N/A — enhancement, not a bug.
Related Files
Notes
"Enabled = subscribed" is a heuristic with a caveat: enabling a mapping only means "route here", not "this vendor uses a subscription plan". A MiniMax vendor could hold a pay-as-you-go KEY (no plan to query). Implementation must gracefully hide quota when the endpoint returns 401/empty.