feat(gpu): re-process trigger to apply new crop detectors to the existing library (#1202)
CI / frontend-build (push) Successful in 19s
CI / backend-lint-and-test (push) Successful in 27s
CI / integration (push) Successful in 3m25s
CI / lint (push) Successful in 3s

The siglip/ccip backfills skip images that already have current-version regions,
so adding crop detectors only affected NEW images — the back-catalogue would
never be re-cropped. Add a reprocess trigger that resets every done/error job of
a task back to pending, so the agent re-runs the FULL pipeline (figure detection
+ CCIP + concept/panel crops) over the whole library under the current detectors.

- reprocess_gpu_jobs(task='ccip') task + POST /api/gpu/reprocess.
- gpu store reprocess() + GpuAgentCard "Re-process library (re-detect + re-crop)"
  button with a confirm (it's heavy).
- Test: a done job resets to pending (attempts cleared).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
This commit is contained in:
2026-06-30 16:09:37 -04:00
parent ce5db5caaf
commit 80f8eb4756
5 changed files with 94 additions and 1 deletions
+18
View File
@@ -91,6 +91,24 @@ async def test_enqueue_embed_backfill_selects_stale_and_unembedded(db):
assert current.id not in queued
@pytest.mark.asyncio
async def test_reprocess_resets_done_jobs_to_pending(db):
# Re-process (#1202): done/error jobs of a task go back to pending so the
# agent re-runs the whole library under the current pipeline.
from backend.app.tasks.ml import reprocess_gpu_jobs
img = await _img(db, "r1" * 32)
job = await GpuJobService(db).enqueue(img.id, "ccip")
job.status = "done"
job.attempts = 2
await db.commit()
assert reprocess_gpu_jobs("ccip") >= 1
await db.refresh(job)
assert job.status == "pending"
assert job.attempts == 0
@pytest.mark.asyncio
async def test_enqueue_dedupes_same_pair(db):
img = await _img(db, "a" * 64)