"""窗口压力诊断:线上是否真的逼近 / 撞过模型上下文上限(DESIGN §8.8 垫子够不够厚)。

三个问题,全部按 DB 实测回答:
1. usage_events(kind=chat)的 units.tokens_in = provider 实报 prompt tokens,
   逐 model_profile 对照 config/models/*.yaml 的 reliable_context / max_context:
   有多少调用越过 50% 压缩线 / 85% 折叠线 / 100% reliable / 硬上限 max_context。
2. tasks.run_error 里有没有 context/length 类的 provider 超限报错(终态错误)。
3. kind=context_fold 的事件量 = 折叠实际触发了多少次(85% 线被踩的次数)。

结论口径:若 (1) 无越过 100% reliable 的调用且 (2) 无超限终态错误 → 现有
50%/85% 双层门槛 + reliable 与 max 之间的余量足够,run 中途折叠 / 超限自愈
继续搁置(§5 无信号不实施)。
"""
import json
import os
import re
from collections import defaultdict
from pathlib import Path

import yaml

ROOT = Path(__file__).resolve().parent.parent
for line in (ROOT / ".env").read_text(encoding="utf-8").splitlines():
    if line.strip().startswith("ZCBOT_DB_URL="):
        os.environ["ZCBOT_DB_URL"] = line.split("=", 1)[1].strip()
from sqlalchemy import create_engine, text  # noqa: E402

engine = create_engine(os.environ["ZCBOT_DB_URL"])

# model_profile("family.variant")→ (reliable_context, max_context),直读 yaml
caps: dict[str, tuple[int, int]] = {}
for f in (ROOT / "config" / "models").glob("*.yaml"):
    data = yaml.safe_load(f.read_text(encoding="utf-8")) or {}
    family = data.get("family", f.stem)
    for variant, var in (data.get("variants") or {}).items():
        caps[f"{family}.{variant}"] = (
            int(var.get("reliable_context", 64_000)),
            int(var.get("max_context", 128_000)),
        )

with engine.connect() as conn:
    rows = conn.execute(text(
        "select model_profile, task_id, units, created_at::date"
        " from usage_events where kind='chat'"
    )).fetchall()
    folds = conn.execute(text(
        "select model_profile, count(*), min(created_at)::date, max(created_at)::date"
        " from usage_events where kind='context_fold' group by 1"
    )).fetchall()
    errs = conn.execute(text(
        "select task_id, model_profile, run_error, updated_at::date from tasks"
        " where run_error is not null and run_error <> ''"
    )).fetchall()

# ---- 1. prompt tokens vs 各模型门槛 ----
stat = defaultdict(lambda: {"n": 0, "max": 0, "max_task": "", "over50": 0,
                            "over85": 0, "over100": 0, "overmax": 0, "top": []})
for profile, task_id, units, day in rows:
    tin = int((units or {}).get("tokens_in") or 0)
    s = stat[profile]
    s["n"] += 1
    if tin > s["max"]:
        s["max"], s["max_task"] = tin, str(task_id)[:8]
    rel, mx = caps.get(profile, (64_000, 128_000))
    if tin >= rel:
        s["over100"] += 1
        s["top"].append((tin, str(task_id)[:8], str(day)))
    elif tin >= rel * 0.85:
        s["over85"] += 1
    elif tin >= rel * 0.5:
        s["over50"] += 1
    if tin >= mx:
        s["overmax"] += 1

print("=== 1. chat 调用 prompt tokens vs 窗口门槛(usage_events 实报)===")
print(f"{'model_profile':<28}{'calls':>7}{'max_in':>9}{'(task)':>10}"
      f"{'>=50%':>7}{'>=85%':>7}{'>=100%rel':>10}{'>=max':>7}")
for profile in sorted(stat, key=lambda p: -stat[p]["max"]):
    s = stat[profile]
    rel, mx = caps.get(profile, (0, 0))
    known = "" if profile in caps else "  [!] 无 yaml 档案,按默认 64k/128k 算"
    print(f"{profile:<28}{s['n']:>7}{s['max']:>9}{s['max_task']:>10}"
          f"{s['over50']:>7}{s['over85']:>7}{s['over100']:>10}{s['overmax']:>7}"
          f"   (rel={rel} max={mx}){known}")

hits = [(t, p) for p, s in stat.items() for t in s["top"]]
if hits:
    print("\n[!] 越过 100% reliable_context 的调用样本(最多 10 条):")
    for (tin, tid, day), profile in sorted(hits, key=lambda x: -x[0][0])[:10]:
        print(f"    {tin:>8} tokens  task {tid}  {day}  {profile}")
else:
    print("\n[ok] 没有任何调用越过 100% reliable_context。")

# ---- 2. 终态错误里的超限报错 ----
pat = re.compile(
    r"context|length|token|exceed|too long|maximum|上下文|超(出|过).{0,6}(长度|上限)",
    re.I,
)
ctx_errs = [(t, p, e, d) for t, p, e, d in errs if pat.search(e or "")]
print(f"\n=== 2. tasks.run_error 终态错误:总 {len(errs)} 条,疑似上下文超限 {len(ctx_errs)} 条 ===")
for t, p, e, d in ctx_errs[:10]:
    print(f"  task {str(t)[:8]}  {d}  [{p}]  {(e or '')[:160]}")
if not ctx_errs and errs:
    print("  [ok] 无一条匹配 context/length/超限类关键词。")

# ---- 3. 折叠实际触发量 ----
print("\n=== 3. context_fold 触发次数(85% 线被踩的实况)===")
if folds:
    for profile, n, d1, d2 in folds:
        print(f"  {profile}: {n} 次({d1} ~ {d2})")
else:
    print("  0 次 —— 85% 折叠线从未被踩到。")
