"""诊断 run_python 失败聚集: python: can't open file '<path>': No such file or directory

捞近 7 天 role=tool & name=run_python & content 含 "can't open file" 的消息,
关联 assistant tool_call 的 arguments,看 script_path 形态;并回看同 task 前文
有没有 write/run_python(code) 生成过该文件,判断是「没写就跑」还是「路径基准错」。
"""
import json
import os
from pathlib import Path

env = Path(__file__).resolve().parent.parent / ".env"
for line in 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"])

with engine.connect() as conn:
    rows = conn.execute(
        text(
            "select m.task_id, t.user_id, m.idx, m.created_at, "
            "       m.payload->>'tool_call_id' as tcid, "
            "       m.payload->>'content' as content "
            "from messages m join tasks t on t.task_id = m.task_id "
            "where m.created_at >= now() - interval '7 days' "
            "  and m.payload->>'role' = 'tool' "
            "  and m.payload->>'name' = 'run_python' "
            "  and m.payload->>'content' like '%can''t open file%' "
            "order by m.created_at"
        )
    ).fetchall()
    print(f"[hits] {len(rows)} tool-result messages\n")

    for task_id, user_id, idx, created, tcid, content in rows:
        tid8 = str(task_id)[:8]
        # 找对应 assistant 调用的 arguments
        call_row = conn.execute(
            text(
                "select payload from messages "
                "where task_id=:t and payload->>'role'='assistant' and idx < :i "
                "order by idx desc limit 20"
            ),
            {"t": task_id, "i": idx},
        ).fetchall()
        args_repr = "?"
        for (payload,) in call_row:
            for tc in payload.get("tool_calls") or []:
                if tc.get("id") == tcid:
                    args_repr = (tc.get("function") or {}).get("arguments") or "?"
                    break
            if args_repr != "?":
                break
        # 提取 script_path
        sp = None
        try:
            sp = json.loads(args_repr).get("script_path")
        except Exception:
            pass
        # 回看同 task 前文: 有没有 write 过这个文件 (basename 匹配)
        wrote = "?"
        if sp:
            base = sp.replace("\\", "/").split("/")[-1]
            w = conn.execute(
                text(
                    "select count(*) from messages "
                    "where task_id=:t and idx < :i "
                    "  and payload->>'role'='assistant' "
                    "  and payload::text like :pat"
                ),
                {"t": task_id, "i": idx, "pat": f"%{base}%"},
            ).scalar()
            wrote = f"prior-mentions={w}"
        first_line = (content or "").strip().splitlines()
        err_line = next((ln for ln in first_line if "can't open file" in ln), "")
        print(f"[{tid8}] user={str(user_id)[:8]} idx={idx} {str(created)[:19]}")
        print(f"  args: {args_repr[:220]}")
        print(f"  err : {err_line[:220]}")
        print(f"  ctx : {wrote}")
        print()
