From b0fb10706e89c3bd442ba74f5384d03c23a288f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zo=C3=AB?= Date: Sat, 30 May 2026 21:01:34 -0700 Subject: [PATCH] fix: use filter API for bucket scanning, bucket_id is view-local not on task object --- dispatcher/dispatcher.py | 52 ++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/dispatcher/dispatcher.py b/dispatcher/dispatcher.py index 5551b15..488ed62 100644 --- a/dispatcher/dispatcher.py +++ b/dispatcher/dispatcher.py @@ -156,23 +156,32 @@ def vikunja_post(vikunja_token: str, path: str, body: dict) -> dict: return resp.json() -def list_todo_tasks(vikunja_token: str, project_id: int, todo_id: int) -> list[dict]: - """Return all undone tasks in the Todo bucket with agent labels.""" +def list_tasks_in_bucket(vikunja_token: str, project_id: int, bucket_id: int) -> list[dict]: + """Return all undone tasks in a specific bucket using the filter API.""" tasks = [] page = 1 while True: - batch = vikunja_get(vikunja_token, f"projects/{project_id}/tasks", page=page, per_page=50) + batch = vikunja_get( + vikunja_token, + f"projects/{project_id}/tasks", + page=page, + per_page=50, + filter=f"bucket_id = {bucket_id}", + ) if not batch: break tasks.extend(batch) if len(batch) < 50: break page += 1 + return [t for t in tasks if not t.get("done")] + + +def list_todo_tasks(vikunja_token: str, project_id: int, todo_id: int) -> list[dict]: + """Return all undone tasks in the Todo bucket that have agent labels.""" return [ - t for t in tasks - if not t.get("done") - and t.get("labels") - and t.get("bucket_id") == todo_id + t for t in list_tasks_in_bucket(vikunja_token, project_id, todo_id) + if t.get("labels") ] @@ -297,18 +306,7 @@ def watchdog_stale_tasks( - attempt count < MAX_TASK_RETRIES → move back to Todo - attempt count >= MAX_TASK_RETRIES → move to Backlog + comment """ - page = 1 - tasks = [] - while True: - batch = vikunja_get(vikunja_token, f"projects/{project_id}/tasks", page=page, per_page=50) - if not batch: - break - tasks.extend(batch) - if len(batch) < 50: - break - page += 1 - - stale = [t for t in tasks if not t.get("done") and t.get("bucket_id") == in_progress_id] + stale = list_tasks_in_bucket(vikunja_token, project_id, in_progress_id) log.info("Watchdog: checking %d InProgress tasks", len(stale)) for task in stale: @@ -467,21 +465,7 @@ def orchestrate_review_tasks( Scan the Review bucket. For each task that has a non-pm/non-reviewer agent label and no review-pm job yet, spawn a PM agent to create review sub-tasks. """ - page = 1 - tasks = [] - while True: - batch = vikunja_get(vikunja_token, f"projects/{project_id}/tasks", page=page, per_page=50) - if not batch: - break - tasks.extend(batch) - if len(batch) < 50: - break - page += 1 - - review_tasks = [ - t for t in tasks - if not t.get("done") and t.get("bucket_id") == in_review_id - ] + review_tasks = list_tasks_in_bucket(vikunja_token, project_id, in_review_id) log.info("Review orchestration: checking %d tasks in Review bucket", len(review_tasks)) for task in review_tasks: