Files
hack/tools/scripts/fix_volcano_404.py
T

102 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""Re-verify the 32 old VolcanoArk channels directly, delete, and recreate
live ones with correct type=8 full-path config (PAYGO/CODING/AGENT separated)."""
import sys, json, time, re
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed
sys.path.insert(0, str(Path(__file__).resolve().parent))
import newapi_client as n
import importlib.util
spec = importlib.util.spec_from_file_location(
"r", str(Path(__file__).resolve().parent / "reconcile_newapi.py"))
R = importlib.util.module_from_spec(spec); spec.loader.exec_module(R)
chans = {c["id"]: c for c in json.load(open("/tmp/chans.json"))}
volc = [c for c in chans.values() if "VolcanoArk_" in c.get("name", "")
and "CodingPlan" not in c["name"]]
all_keys = R.load_all_keys()
def findkey(name):
suf = name.rsplit("_", 1)[-1].lower()
for k in all_keys:
if k["prov"] == "volcanoark" and (k["key"].lower()[-4:] == suf
or k["key"].lower()[-6:].endswith(suf)):
return k["key"]
return None
def mkch(name, ctype, base, key, models, test_model):
return dict(name=name, type=ctype, key=key, base_url=base, models=models,
test_model=test_model, model_mapping="", groups=["default"], group="default",
priority=0, weight=0, auto_ban=1)
print(f"re-verifying {len(volc)} old VolcanoArk channels direct...")
def work(c):
key = findkey(c["name"])
if not key:
return c["id"], c["name"], None, "NO_KEY"
v, detail, info = R.verify_volcano(key)
return c["id"], c["name"], key, (v, detail, info)
results = []
with ThreadPoolExecutor(max_workers=12) as ex:
futs = [ex.submit(work, c) for c in volc]
for f in as_completed(futs):
results.append(f.result())
if len(results) % 10 == 0:
print(f" {len(results)}/{len(volc)}")
live, dead, other = [], [], []
for cid, name, key, res in results:
if key is None:
other.append((cid, name, res)); continue
v, detail, info = res
if v == "USABLE":
live.append((cid, name, key, info, detail))
elif v == "DEAD":
dead.append((cid, name, detail))
else:
other.append((cid, name, detail))
print(f"\nUSABLE={len(live)} DEAD={len(dead)} OTHER={len(other)}")
for cid, name, key, info, detail in live:
print(f" + {cid} {name}: coding={info.get('coding')} agent={info.get('agent')} paygo={info.get('paygo')}")
for cid, name, d in dead:
print(f" x DEAD {cid} {name}: {d[:60]}")
for cid, name, d in other:
print(f" ? {cid} {name}: {str(d)[:60]}")
# delete all old, recreate live
print("\nrecreating live channels...")
created = 0
for cid, name, key, info, detail in live:
n.delete_channel(cid); time.sleep(0.15)
suf = name.rsplit("_", 1)[-1]
newids = []
if info.get("coding"):
ch = mkch(f"VolcanoCoding_{suf}", n.TYPE_ANTHROPIC,
"https://ark.cn-beijing.volces.com/api/coding", key,
"ark-code-latest", "ark-code-latest")
ok, msg = n.add_channel(ch)
if ok: created += 1; print(f" VolcanoCoding_{suf} OK")
if info.get("agent"):
ch = mkch(f"VolcanoAgent_{suf}", n.TYPE_CUSTOM,
"https://ark.cn-beijing.volces.com/api/plan/v3/chat/completions", key,
"ark-code-latest", "ark-code-latest")
ok, msg = n.add_channel(ch)
if ok: created += 1; print(f" VolcanoAgent_{suf} OK")
for model in info.get("paygo", []):
tag = model.split("-")[-1][:6]
ch = mkch(f"VolcanoPAYGO_{suf}_{tag}", n.TYPE_CUSTOM,
"https://ark.cn-beijing.volces.com/api/v3/chat/completions", key,
model, model)
ok, msg = n.add_channel(ch)
if ok: created += 1; print(f" VolcanoPAYGO_{suf}_{tag} ({model}) OK")
time.sleep(0.2)
# delete dead too
for cid, name, d in dead:
n.delete_channel(cid); print(f" deleted dead {cid} {name}")
time.sleep(0.1)
print(f"\n=== created {created} channels from {len(live)} live keys, removed {len(dead)} dead ===")