dippoo commited on
Commit
79598c0
·
1 Parent(s): d812254

Add pod generation progress polling with live status in UI

Browse files
Files changed (1) hide show
  1. src/content_engine/api/ui.html +41 -1
src/content_engine/api/ui.html CHANGED
@@ -2387,8 +2387,9 @@ async function doGenerate() {
2387
  const data = await res.json();
2388
  if (!res.ok) throw new Error(data.detail || 'Pod not running - start it first');
2389
 
 
2390
  toast('Generating on RunPod GPU...', 'info');
2391
- await pollForNewImage(startTime);
2392
  return;
2393
  }
2394
 
@@ -2440,6 +2441,45 @@ async function doGenerate() {
2440
  }
2441
  }
2442
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2443
  async function pollForNewImage(startTime) {
2444
  for (let i = 0; i < 60; i++) {
2445
  await new Promise(r => setTimeout(r, 3000));
 
2387
  const data = await res.json();
2388
  if (!res.ok) throw new Error(data.detail || 'Pod not running - start it first');
2389
 
2390
+ const podJobId = data.job_id;
2391
  toast('Generating on RunPod GPU...', 'info');
2392
+ await pollPodJob(podJobId, startTime);
2393
  return;
2394
  }
2395
 
 
2441
  }
2442
  }
2443
 
2444
+ async function pollPodJob(jobId, startTime) {
2445
+ const preview = document.getElementById('preview-body');
2446
+ for (let i = 0; i < 180; i++) { // 180 × 5s = 15 min max
2447
+ await new Promise(r => setTimeout(r, 5000));
2448
+ try {
2449
+ const res = await fetch(API + `/api/pod/jobs/${jobId}`);
2450
+ if (!res.ok) continue;
2451
+ const job = await res.json();
2452
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);
2453
+ const progressMsg = job.progress_msg || `${elapsed}s elapsed...`;
2454
+ preview.innerHTML = `<div class="preview-placeholder"><p>Generating on RunPod GPU...</p><p style="font-size:12px;color:var(--text-secondary)">${progressMsg}</p></div>`;
2455
+
2456
+ if (job.status === 'completed' && job.output_path) {
2457
+ document.getElementById('gen-time').textContent = `${elapsed}s`;
2458
+ // Fetch latest image from gallery
2459
+ const imgRes = await fetch(API + '/api/images?limit=1');
2460
+ const images = await imgRes.json();
2461
+ if (images.length > 0) {
2462
+ showPreviewImage(images[0]);
2463
+ } else {
2464
+ preview.innerHTML = `<div class="preview-placeholder"><p>Image saved to: ${job.output_path}</p></div>`;
2465
+ }
2466
+ toast('Image generated!', 'success');
2467
+ return;
2468
+ }
2469
+ if (job.status === 'failed') {
2470
+ throw new Error(job.error || 'Generation failed');
2471
+ }
2472
+ } catch(e) {
2473
+ if (e.message && e.message !== 'Failed to fetch') {
2474
+ preview.innerHTML = `<div class="preview-placeholder"><p style="color:var(--error)">Error: ${e.message}</p></div>`;
2475
+ toast(e.message, 'error');
2476
+ return;
2477
+ }
2478
+ }
2479
+ }
2480
+ preview.innerHTML = `<div class="preview-placeholder"><p>Timed out waiting for image (15 min)</p></div>`;
2481
+ }
2482
+
2483
  async function pollForNewImage(startTime) {
2484
  for (let i = 0; i < 60; i++) {
2485
  await new Promise(r => setTimeout(r, 3000));