docs: update EXECUTION_BOARD + VNEXT_COMPLETION_CHECKLIST for vNext.1 closure
- EXECUTION_BOARD: record vNext.1 release gate completion, remote43 binary swap, fresh 3-layer acceptance status - VNEXT_COMPLETION_CHECKLIST: upgrade to 'conditionally complete (vNext.1)', update all checklists - add vnext_fresh_acceptance.py: standalone fresh 3-layer acceptance probe script
This commit is contained in:
116
scripts/acceptance/vnext_fresh_acceptance.py
Normal file
116
scripts/acceptance/vnext_fresh_acceptance.py
Normal file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
"""vNext.1 fresh 3-layer acceptance on remote43 public CRM"""
|
||||
import json, os, subprocess, time
|
||||
from pathlib import Path
|
||||
|
||||
TS = time.strftime("%Y%m%d_%H%M%S")
|
||||
ART = Path(os.environ.get("ARTIFACT_DIR", f"artifacts/fresh-vnext1-acceptance/{TS}"))
|
||||
if not ART.is_absolute():
|
||||
ART = Path(os.getcwd()) / ART
|
||||
ART.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
CRM = os.environ.get("CRM_BASE", "https://sub.tksea.top/portal-admin-api")
|
||||
AKEY = os.environ.get("OPENAI_ZHONGZHUAN_API_KEY", "")
|
||||
MMKEY = os.environ.get("MINIMAX_53HK_API_KEY", "")
|
||||
DSKEY = os.environ.get("DEEPSEEK_OFFICIAL_API_KEY", "")
|
||||
CTOKEN = os.environ.get("CRM_ADMIN_TOKEN", "")
|
||||
|
||||
log = open(ART / "run.log", "w")
|
||||
|
||||
def L(msg):
|
||||
print(msg)
|
||||
log.write(msg + "\n")
|
||||
log.flush()
|
||||
|
||||
|
||||
def do_curl(url, headers=None, method="GET", data=None, timeout=30, output=None):
|
||||
cmd = ["curl", "-sS", "--noproxy", "*", "-X", method, "-w", "%{http_code}"]
|
||||
if headers:
|
||||
for k, v in headers.items():
|
||||
cmd += ["-H", f"{k}: {v}"]
|
||||
if data:
|
||||
cmd += ["-d", data]
|
||||
if output:
|
||||
cmd += ["-o", str(output)]
|
||||
cmd.append(url)
|
||||
try:
|
||||
r = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
||||
return r.stdout.strip(), r.stderr
|
||||
except subprocess.TimeoutExpired:
|
||||
return "timeout", ""
|
||||
|
||||
|
||||
L(f"vNext.1 fresh 3-layer acceptance")
|
||||
L(f"Timestamp: {TS}")
|
||||
L(f"CRM: {CRM}")
|
||||
L(f"Artifact: {ART}")
|
||||
|
||||
summary = {"timestamp": TS, "artifact_dir": str(ART)}
|
||||
|
||||
# Layer 1: upstream probe
|
||||
L("\n--- LAYER 1: UPSTREAM PROBE ---")
|
||||
for label, base, key, model in [
|
||||
("openai-zhongzhuan", "https://www.openai-proxy.org", AKEY, "gpt-5.4"),
|
||||
("minimax-53hk", "https://api.minimax.chat", MMKEY, "MiniMax-M3"),
|
||||
("deepseek-official", "https://api.deepseek.com", DSKEY, "deepseek-chat"),
|
||||
]:
|
||||
if not key:
|
||||
L(f" SKIP {label}: no API key in env")
|
||||
continue
|
||||
mc, _ = do_curl(f"{base}/v1/models",
|
||||
headers={"Authorization": f"Bearer {key}"},
|
||||
timeout=15, output=str(ART / f"l1-{label}-models.body.json"))
|
||||
L(f" {label} models -> HTTP {mc}")
|
||||
|
||||
payload = json.dumps({"model": model, "messages": [{"role": "user", "content": "ping"}]})
|
||||
cc, _ = do_curl(f"{base}/v1/chat/completions",
|
||||
method="POST",
|
||||
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
|
||||
data=payload, timeout=30,
|
||||
output=str(ART / f"l1-{label}-chat.body.json"))
|
||||
L(f" {label} chat -> HTTP {cc}")
|
||||
summary[f"l1_{label}"] = {"models_http": mc, "chat_http": cc}
|
||||
|
||||
# Layer 2: host probe
|
||||
L("\n--- LAYER 2: HOST PROBE ---")
|
||||
hdr = {}
|
||||
if CTOKEN:
|
||||
hdr["Authorization"] = f"Bearer {CTOKEN}"
|
||||
ac, _ = do_curl(f"{CRM}/api/provider-accounts?limit=10",
|
||||
headers=hdr, timeout=15,
|
||||
output=str(ART / "l2-accounts.body.json"))
|
||||
L(f" accounts -> HTTP {ac}")
|
||||
|
||||
acct_count = 0
|
||||
p = ART / "l2-accounts.body.json"
|
||||
if p.stat().st_size > 10:
|
||||
try:
|
||||
d = json.load(open(p))
|
||||
acct_count = len(d.get("accounts", d.get("data", [])))
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
L(f" account_count={acct_count}")
|
||||
summary["l2_host"] = {"accounts_http": ac, "count": acct_count}
|
||||
|
||||
# Layer 3: user-key probe
|
||||
L("\n--- LAYER 3: USER-KEY PROBE ---")
|
||||
if AKEY:
|
||||
# CRM reverse-proxy /v1/chat/completions
|
||||
chat_payload = json.dumps({"model": "gpt-5.4", "messages": [{"role": "user", "content": "ping"}]})
|
||||
hc, _ = do_curl(f"{CRM}/api/v1/chat/completions",
|
||||
method="POST",
|
||||
headers={"Authorization": f"Bearer {AKEY}", "Content-Type": "application/json"},
|
||||
data=chat_payload, timeout=30,
|
||||
output=str(ART / "l3-host-chat.body.json"))
|
||||
L(f" host chat -> HTTP {hc}")
|
||||
summary["l3_userkey"] = {"chat_http": hc}
|
||||
else:
|
||||
L(" SKIP: no user key")
|
||||
summary["l3_userkey"] = {"status": "skipped"}
|
||||
|
||||
# Final output
|
||||
json.dump(summary, open(ART / "99-summary.json", "w"), ensure_ascii=False, indent=2)
|
||||
L(f"\n=== FINAL SUMMARY ===")
|
||||
L(json.dumps(summary, ensure_ascii=False, indent=2))
|
||||
L(f"\nArtifact path: {ART}")
|
||||
log.close()
|
||||
Reference in New Issue
Block a user