feat: multi-provider usage — Kimi collector via CDP, unified /api/usage, frontend grouping

This commit is contained in:
hmo
2026-07-19 19:46:08 +08:00
parent 94f5f9ec92
commit 7a43fec2b1
4 changed files with 420 additions and 38 deletions
+40 -9
View File
@@ -1195,15 +1195,46 @@ _usage_collector_running = False
@app.route("/api/usage")
def api_usage():
"""直读本地 usage_stats.json(秒级响应,不依赖 Windows bot"""
if not _USAGE_STATS_FILE.exists():
return jsonify({"ok": False, "error": "no data yet (collect never ran)",
"last_refresh_iso": None, "accounts": []})
try:
with open(str(_USAGE_STATS_FILE), "r", encoding="utf-8") as f:
return jsonify(json.load(f))
except Exception as e:
return jsonify({"ok": False, "error": f"read failed: {e}", "accounts": []})
"""读取 usage_stats.json,合并 Kimi 数据(如果存在)。"""
accounts = []
providers = {}
# 1. 主 OCG 数据
if _USAGE_STATS_FILE.exists():
try:
with open(str(_USAGE_STATS_FILE), "r", encoding="utf-8") as f:
data = json.load(f)
for a in data.get("accounts", []):
a["provider"] = a.get("provider", "opencode_go")
accounts.append(a)
providers["opencode_go"] = providers.get("opencode_go", 0) + 1
except Exception as e:
log.warning(f"usage: read failed: {e}")
# 2. Kimi 数据
kimi_file = TEMP_DIR / "usage_stats_kimi.json"
if kimi_file.exists():
try:
with open(str(kimi_file), "r", encoding="utf-8") as f:
kimi_data = json.load(f)
for a in kimi_data.get("accounts", []):
a["provider"] = a.get("provider", "kimi")
accounts.append(a)
providers["kimi"] = providers.get("kimi", 0) + 1
except Exception:
pass
if not accounts:
return jsonify({"ok": False, "error": "no data yet",
"last_refresh_iso": None, "accounts": [], "providers": {}})
return jsonify({
"ok": True,
"last_refresh_iso": max((a.get("last_update_iso","") for a in accounts), default=None),
"account_count": len(accounts),
"collected_count": sum(1 for a in accounts if a.get("error") is None),
"providers": providers,
"accounts": accounts,
})
@app.route("/api/usage/refresh", methods=["POST"])