| 83 | |
| 84 | |
| 85 | def parse_steps_jsonl(path: Path) -> list[dict]: |
| 86 | rows: list[dict] = [] |
| 87 | if not path.exists(): |
| 88 | return rows |
| 89 | for line in path.read_text(encoding="utf-8").splitlines(): |
| 90 | line = line.strip() |
| 91 | if not line: |
| 92 | continue |
| 93 | try: |
| 94 | rows.append(json.loads(line)) |
| 95 | except json.JSONDecodeError: |
| 96 | continue |
| 97 | for r in rows: |
| 98 | try: |
| 99 | r["step_num"] = int(r.get("step_num", 0)) |
| 100 | except (TypeError, ValueError): |
| 101 | r["step_num"] = 0 |
| 102 | rows.sort(key=lambda r: r["step_num"]) |
| 103 | return rows |
| 104 | |
| 105 | |
| 106 | def build_steps(task_dir: Path) -> tuple[list[dict], str]: |