| 62 | |
| 63 | |
| 64 | def _list_tasks(qdir: Path) -> List[TaskItem]: |
| 65 | if not qdir.exists(): |
| 66 | return [] |
| 67 | |
| 68 | tasks: List[TaskItem] = [] |
| 69 | |
| 70 | for p in sorted(qdir.glob("*.json")): |
| 71 | # Ignore hidden and non-task JSON files |
| 72 | if p.name.startswith("."): |
| 73 | continue |
| 74 | if p.name.endswith(".answer.json"): |
| 75 | continue |
| 76 | |
| 77 | task_id = p.stem |
| 78 | answer = qdir / f"{task_id}.answer.json" |
| 79 | has_answer = answer.exists() |
| 80 | |
| 81 | created_at = "" |
| 82 | model = None |
| 83 | try: |
| 84 | data = json.loads(p.read_text(encoding="utf-8")) |
| 85 | created_at = str(data.get("created_at") or "") |
| 86 | model = data.get("model") |
| 87 | except Exception: |
| 88 | pass |
| 89 | |
| 90 | tasks.append(TaskItem(id=task_id, created_at=created_at, model=model, has_answer=has_answer)) |
| 91 | |
| 92 | # Show only pending |
| 93 | tasks = [t for t in tasks if not t.has_answer] |
| 94 | return tasks |
| 95 | |
| 96 | |
| 97 | def _read_task(qdir: Path, task_id: str) -> Optional[Dict]: |