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

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
@@ -71,6 +71,16 @@
images get these automatically; this catches the back-catalogue.
</p>
<v-btn
class="mt-3" color="warning" variant="tonal" rounded="pill" size="small"
prepend-icon="mdi-backup-restore" :loading="reprocessing" @click="onReprocess"
>Re-process library (re-detect + re-crop)</v-btn>
<p class="fc-muted text-caption mt-2 mb-0">
Re-runs the FULL pipeline (figure detection + CCIP + concept/panel crops) on
<b>every</b> image use after changing crop detectors so the back-catalogue
gets re-cropped, not just new images. Heavy: re-processes the whole library.
</p>
<!-- Match strictness -->
<div class="fc-section-h mt-5 mb-1">Character-match strictness</div>
<div v-if="ml.settings" class="d-flex align-center" style="gap:12px">
@@ -157,6 +167,7 @@ const masked = ref(true)
const rotating = ref(false)
const backfilling = ref(false)
const backfillingSiglip = ref(false)
const reprocessing = ref(false)
const threshold = ref(0.85)
const savingThreshold = ref(false)
const autoApply = ref(true)
@@ -307,6 +318,20 @@ async function onBackfillSiglip() {
backfillingSiglip.value = false
}
}
async function onReprocess() {
if (!window.confirm('Re-process the ENTIRE library (re-detect + re-crop every image)? This is heavy and runs on the GPU agent.')) return
reprocessing.value = true
try {
await store.reprocess('ccip')
toast({ text: 'Library queued for re-processing — run the agent to drain it', type: 'success' })
await refreshQueue()
} catch (e) {
toast({ text: `Could not start re-process: ${e.message}`, type: 'error' })
} finally {
reprocessing.value = false
}
}
</script>
<style scoped>
+7 -1
View File
@@ -29,5 +29,11 @@ export const useGpuStore = defineStore('gpu', () => {
return await api.post('/api/gpu/backfill', { body: { task } })
}
return { token, rotateToken, status, backfill }
// Reset every done/error `task` job to pending → re-run the WHOLE library
// under the current pipeline (e.g. after adding crop detectors).
async function reprocess(task = 'ccip') {
return await api.post('/api/gpu/reprocess', { body: { task } })
}
return { token, rotateToken, status, backfill, reprocess }
})