import json, urllib.request, time

AT = "fcat_0d2a3ccd686ec142946759cd716e055b60255b7d8bf26ec6"
BASE = "http://127.0.0.1:8000"

def req(method, path, body=None):
    data = json.dumps(body).encode() if body is not None else None
    r = urllib.request.Request(BASE + path, data=data, method=method)
    r.add_header("Authorization", "Bearer " + AT)
    r.add_header("Content-Type", "application/json")
    try:
        with urllib.request.urlopen(r, timeout=60) as resp:
            return resp.status, resp.read().decode()[:300]
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode()[:300]
    except Exception as e:
        return -1, str(e)

# 1. llm-proxy 配置
proxy_cfg = {
    "upstream_base": "http://10.200.0.20:3000",
    "api_key": "sk-m2ZMH0W1EYSL4vrXwE0WjvQTSOKhhX4oMp31zZskZ6xDPl96",
    "listen_addr": "127.0.0.1:39527",
    "embed_upstream": "http://10.200.0.10:39529",
    "embed_api_key": "",
}
for i in range(3):
    code, resp = req("PUT", "/api/plugins/llm-proxy/config", {"config": proxy_cfg})
    print(f"1. llm-proxy config attempt {i+1}: {code} {resp[:100]}")
    if code < 300: break
    time.sleep(5)
time.sleep(5)

# 2. sync-models
for i in range(3):
    code, resp = req("POST", "/api/llm/channels/1/sync-models")
    print(f"2. sync-models attempt {i+1}: {code} {resp[:150]}")
    if code < 300: break
    time.sleep(5)

# 3. 拉模型列表
code, resp = req("GET", "/api/llm/models")
print(f"3. models: {code}")
models = []
if code < 300:
    d = json.loads(resp) if resp else {}
    models = d if isinstance(d, list) else d.get("models", d.get("data", []))
    for m in models:
        print(f"   id={m.get('id')} key={m.get('model_key','?')[:50]}")
else:
    print("   resp:", resp[:200])

# 构建 key -> id 映射
key2id = {}
for m in models:
    mk = m.get("model_key", "")
    dn = m.get("display_name", "")
    if mk: key2id[mk] = m.get("id")
    if dn: key2id[dn] = m.get("id")

# 4. 路由
purposes = {
    "*": ["nvidia/nemotron-3-super-120b-a12b:free", "mistral-medium-latest", "openrouter/free"],
    "brain_thinking": ["minimax/minimax-m3:free", "nvidia/nemotron-3-ultra-550b-a55b:free", "nvidia/nemotron-3-super-120b-a12b:free", "mistral-large-latest"],
    "default": ["nvidia/nemotron-3-super-120b-a12b:free", "mistral-medium-latest", "openrouter/free"],
    "tool_multimodal": ["mistral-large-latest", "openrouter/free"],
}
for purpose, cands in purposes.items():
    resolved = []
    for i, ref in enumerate(cands):
        mid = key2id.get(ref)
        if mid is None:
            print(f"4. route {purpose}: SKIP {ref} (not found)")
            continue
        resolved.append({"target_type": "channel", "channel_id": 1, "channel_model_id": mid, "model_key": ref, "position": i})
    if not resolved:
        print(f"4. route {purpose}: NO CANDIDATES")
        continue
    body = {"use_streaming": True, "max_attempts": 8, "total_budget_seconds": 0, "all_cooling_policy": "fail_fast", "enabled": True, "candidates": resolved}
    code, resp = req("PUT", f"/api/llm/routes/{purpose}", body)
    print(f"4. route {purpose}: {code} {resp[:80]}")

# 5. probe 恢复健康
code, resp = req("GET", "/api/llm/models")
if code < 300:
    d = json.loads(resp) if resp else {}
    models = d if isinstance(d, list) else d.get("models", d.get("data", []))
    for m in models[:8]:
        mid = m.get("id")
        code, resp = req("POST", f"/api/llm/models/{mid}/probe")
        print(f"5. probe {mid}: {code} {resp[:60]}")

print("DONE")
