feat: AI job tracking, range support, auto-prompt, and resume
All checks were successful
Release / Test backend (push) Successful in 48s
Release / Check ui (push) Successful in 55s
Release / Docker / caddy (push) Successful in 38s
Release / Docker / backend (push) Successful in 3m21s
Release / Docker / runner (push) Successful in 2m41s
Release / Upload source maps (push) Successful in 3m44s
Release / Docker / ui (push) Successful in 2m42s
Release / Gitea Release (push) Successful in 1m22s
All checks were successful
Release / Test backend (push) Successful in 48s
Release / Check ui (push) Successful in 55s
Release / Docker / caddy (push) Successful in 38s
Release / Docker / backend (push) Successful in 3m21s
Release / Docker / runner (push) Successful in 2m41s
Release / Upload source maps (push) Successful in 3m44s
Release / Docker / ui (push) Successful in 2m42s
Release / Gitea Release (push) Successful in 1m22s
- New `ai_jobs` PocketBase collection tracks all long-running AI tasks (batch-covers, chapter-names) with status, progress, and cancellation - `handlers_aijobs.go`: GET/cancel endpoints for ai_jobs; centralised cancel registry (moved from handlers_catalogue) - Batch-covers and chapter-names SSE handlers now create/resume ai_job records, support from_item/to_item ranges, and resume from items_done on restart via job_id - New `POST /api/admin/image-gen/auto-prompt`: generates an image prompt from book description (cover) or chapter title (chapter) via LLM - image-gen page: "Auto-prompt" button calls auto-prompt API when a slug is selected; falls back gracefully if TextGen not configured - text-gen chapter-names: from/to chapter range inputs + job ID display - catalogue-tools batch-covers: from/to item range + resume job ID input - pb-init-v3.sh: adds ai_jobs collection (idempotent) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -80,6 +80,9 @@
|
||||
let chAC = makeBookAC();
|
||||
let chSlug = $state('');
|
||||
let chPattern = $state(saved.chPattern ?? 'Chapter {n}: {scene}');
|
||||
let chFromChapter = $state(0);
|
||||
let chToChapter = $state(0);
|
||||
let chJobID = $state('');
|
||||
let chGenerating = $state(false);
|
||||
let chError = $state('');
|
||||
|
||||
@@ -122,6 +125,7 @@
|
||||
chBatchWarnings = [];
|
||||
chApplySuccess = false;
|
||||
chApplyError = '';
|
||||
chJobID = '';
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/admin/text-gen/chapter-names', {
|
||||
@@ -130,7 +134,9 @@
|
||||
body: JSON.stringify({
|
||||
slug: chSlug.trim(),
|
||||
pattern: chPattern.trim(),
|
||||
model: selectedModel
|
||||
model: selectedModel,
|
||||
from_chapter: chFromChapter || undefined,
|
||||
to_chapter: chToChapter || undefined
|
||||
})
|
||||
});
|
||||
|
||||
@@ -161,6 +167,7 @@
|
||||
if (!payload) continue;
|
||||
|
||||
let evt: {
|
||||
job_id?: string;
|
||||
batch?: number;
|
||||
total_batches?: number;
|
||||
chapters_done?: number;
|
||||
@@ -176,6 +183,8 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
if (evt.job_id) chJobID = evt.job_id;
|
||||
|
||||
if (evt.done) {
|
||||
chBatchProgress = `Done — ${evt.total_chapters ?? chProposals.length} chapters`;
|
||||
chGenerating = false;
|
||||
@@ -579,6 +588,27 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Range (optional) -->
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="space-y-1">
|
||||
<label class="text-xs font-medium text-(--color-muted) uppercase tracking-wide" for="ch-from">
|
||||
From chapter <span class="font-normal">(0=all)</span>
|
||||
</label>
|
||||
<input id="ch-from" type="number" bind:value={chFromChapter} min="0"
|
||||
class="w-full bg-(--color-surface-2) border border-(--color-border) rounded-lg px-3 py-2 text-(--color-text) text-sm focus:outline-none focus:ring-2 focus:ring-(--color-brand)" />
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<label class="text-xs font-medium text-(--color-muted) uppercase tracking-wide" for="ch-to">
|
||||
To chapter <span class="font-normal">(0=all)</span>
|
||||
</label>
|
||||
<input id="ch-to" type="number" bind:value={chToChapter} min="0"
|
||||
class="w-full bg-(--color-surface-2) border border-(--color-border) rounded-lg px-3 py-2 text-(--color-text) text-sm focus:outline-none focus:ring-2 focus:ring-(--color-brand)" />
|
||||
</div>
|
||||
</div>
|
||||
{#if chJobID}
|
||||
<p class="text-xs text-(--color-muted)">Job: <span class="font-mono">{chJobID}</span></p>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
onclick={generateChapterNames}
|
||||
disabled={!chCanGenerate}
|
||||
|
||||
Reference in New Issue
Block a user