"""Dump the task_progress tool-call sequence for a task (by id prefix). ASCII-only.""" import json import os import sys 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"]) prefix = sys.argv[1] if len(sys.argv) > 1 else "d1285247" with engine.connect() as conn: row = conn.execute( text("select task_id,name,status,run_status from tasks where task_id::text like :p"), {"p": prefix + "%"}, ).fetchone() if not row: print("[NO TASK]", prefix) sys.exit(1) tid = row[0] print(f"[TASK] {tid} name={row[1]!r} status={row[2]} run={row[3]}") msgs = conn.execute( text("select idx,payload from messages where task_id=:t order by idx"), {"t": tid}, ).fetchall() print(f"[MESSAGES] {len(msgs)}") n = 0 for idx, p in msgs: for tc in p.get("tool_calls") or []: fn = tc.get("function") or {} if fn.get("name") != "task_progress": continue n += 1 try: args = json.loads(fn.get("arguments") or "{}") except Exception as e: print(f" [{idx}] PARSE-ERR: {e} raw={fn.get('arguments')!r}") continue act = args.get("action") if act == "set_plan": steps = args.get("steps") or [] print(f" [{idx}] set_plan ({len(steps)} steps):") for st in steps: print(f" {st.get('id')!r:8} {st.get('status'):11} {st.get('title')!r}") elif act == "update_step": st = args.get("step") or {} print(f" [{idx}] update_step id={st.get('id')!r} status={st.get('status')!r} title={st.get('title')!r}") else: print(f" [{idx}] {act} {json.dumps(args, ensure_ascii=False)}") print(f"[task_progress calls] {n}")