Skip to content

Fix illustration pipeline: poll background job token to display generated images in UI#158

Merged
CyberSecDef merged 3 commits into
mainfrom
copilot/fix-images-not-generating
Apr 8, 2026
Merged

Fix illustration pipeline: poll background job token to display generated images in UI#158
CyberSecDef merged 3 commits into
mainfrom
copilot/fix-images-not-generating

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

After clicking "Generate Illustrations", the backend launches image generation in a background thread and immediately returns {"illustration_token": "..."}. The frontend's success callback was reading resp.illustrations directly from that response (which is always empty), causing the UI to always show "No illustrations were generated."

Changes

  • static/js/script.js: Added _pollIllustrationJob(illustToken, retries) function that:

    • Polls /progress/<illustration_token> every 3 seconds until the job reaches done or error status
    • Displays live progress text in the button (e.g. "Generating 2 image(s)… (1/2)") while the job runs
    • On completion, fetches /progress/<illustration_token>/full to retrieve the illustrations array and passes it to renderIllustrations()
    • Limits network error retries to 10 before surfacing an error message to the user
    • Updated the button click handler to use the new polling flow instead of reading illustrations from the immediate response
  • templates/index.html: Added <span id="illustrations-spinner-label"> inside the Generate button to display live status text during polling

Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 22:29
Copilot AI linked an issue Apr 8, 2026 that may be closed by this pull request
…1-mini to gpt-image-1

Agent-Logs-Url: https://github.com/CyberSecDef/NovelForge/sessions/0f18f183-a633-420c-a80f-24ad8e7364a1

Co-authored-by: CyberSecDef <17597068+CyberSecDef@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 22:39
Copilot AI changed the title [WIP] Fix images not generating in illustration pipeline Fix illustration pipeline: correct invalid IMAGE_MODEL default Apr 8, 2026
Copilot AI requested a review from CyberSecDef April 8, 2026 22:40
Copy link
Copy Markdown
Owner

@CyberSecDef CyberSecDef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem was definitively not the image_model, which is set in the environment properly. the images ARE being generated and stored in the exports folder properly. the response from the server after generation is:

{"illustration_token":"18fea0bb-730f-4122-a648-3cccf924dca6"}

but there is no data there to update the UI with the images. I am guessing that after generating the images, there needs to be another step to load the image from the exports folder and update the UI to have those two images displayed.

Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 22:52
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 8, 2026

the problem was definitively not the image_model, which is set in the environment properly. the images ARE being generated and stored in the exports folder properly. the response from the server af...

You're right — the real bug was in the frontend. The backend's /generate_illustrations endpoint returns {"illustration_token": "..."} immediately and runs image generation in a background thread, but the JS success callback was reading resp.illustrations directly from that response (which is always empty).

Fixed in commit 39f8bdd:

  • Added a _pollIllustrationJob() function in script.js that polls /progress/<illustration_token> every 3 seconds until the job is done or errors out
  • When done, it fetches /progress/<illustration_token>/full to get the actual illustrations array and passes it to renderIllustrations()
  • The button shows live progress text (e.g. "Generating 2 image(s)… (1/2)") while the job runs
  • Network errors retry up to 10 times before showing an error
  • Also added an illustrations-spinner-label span in the button HTML to display the live status text

Copilot AI changed the title Fix illustration pipeline: correct invalid IMAGE_MODEL default Fix illustration pipeline: poll background job token to display generated images in UI Apr 8, 2026
Copilot AI requested a review from CyberSecDef April 8, 2026 22:53
@CyberSecDef CyberSecDef marked this pull request as ready for review April 8, 2026 23:01
Copilot AI review requested due to automatic review settings April 8, 2026 23:01
@CyberSecDef CyberSecDef merged commit 93e0f8f into main Apr 8, 2026
10 checks passed
@CyberSecDef CyberSecDef deleted the copilot/fix-images-not-generating branch April 8, 2026 23:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the illustration-generation UI flow by treating /generate_illustrations as an async job launcher (returns an illustration_token) and polling the existing /progress/<token> endpoints until results are ready, then rendering the generated images.

Changes:

  • Added a frontend polling loop to wait for the illustration background job to reach done/error, updating in-button status text during execution.
  • On completion, fetches /progress/<illustration_token>/full to retrieve the illustrations array and renders it.
  • Added a dedicated span in the Generate Illustrations button to display live polling status text.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
static/js/script.js Implements polling of /progress/<illustration_token> and updates the illustration rendering flow to use the background-job token.
templates/index.html Adds a spinner label element inside the Generate Illustrations button for live status text during polling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread static/js/script.js
Comment on lines +1366 to +1369
$.ajax({
url: "/progress/" + illustToken,
method: "GET",
success: function (data) {
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The polling GET requests don’t set a timeout. If a /progress/ request hangs (e.g., stalled connection), neither the success nor error callback will fire, so polling stops and the spinner/export buttons never recover. Add a reasonable timeout for the lightweight poll (and handle timeout in the error path) so the UI can continue retrying or fail gracefully.

Copilot uses AI. Check for mistakes.
Comment thread static/js/script.js
Comment on lines 1434 to 1439
$.ajax({
url: "/generate_illustrations",
method: "POST",
contentType: "application/json",
data: JSON.stringify({ token: _progressToken }),
timeout: 600000, // 10 min timeout for image generations
success: function (resp) {
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial POST to /generate_illustrations no longer has any timeout. That route should return quickly with an illustration_token; without a timeout a stalled request can leave the UI stuck in “Starting…”. Consider adding a short timeout (and treating timeouts like other transient errors) since the long-running work is now done via polling.

Copilot uses AI. Check for mistakes.
Comment thread static/js/script.js
Comment on lines +1409 to +1422
error: function () {
// Retry on transient network errors, up to 10 attempts.
if (retries < 10) {
setTimeout(function () {
_pollIllustrationJob(illustToken, retries + 1);
}, 5000);
} else {
showAlert(
"Lost connection to the server while waiting for illustrations. Please check your connection and try again."
);
$("#illustrations-spinner").addClass("d-none");
$("#illustrations-spinner-label").addClass("d-none").text("");
_enableExportButtons();
}
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The poll error handler retries all HTTP failures up to 10 times but doesn’t inspect the response. For non-transient errors like 404 {"error":"Unknown token"} (e.g., server restart/eviction), it should stop retrying and surface the server-provided error to the user instead of reporting a generic connectivity issue after 10 attempts.

Copilot uses AI. Check for mistakes.
Comment thread static/js/script.js
Comment on lines +1372 to +1384
$.ajax({
url: "/progress/" + illustToken + "/full",
method: "GET",
success: function (full) {
renderIllustrations(full.illustrations || []);
},
error: function () {
renderIllustrations([]);
},
complete: function () {
$("#illustrations-spinner").addClass("d-none");
$("#illustrations-spinner-label").addClass("d-none").text("");
_enableExportButtons();
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If fetching /progress//full fails, the code renders an empty gallery without any alert, which can mislead users into thinking “no illustrations were generated” rather than “results couldn’t be retrieved”. Consider showing an error message (and/or keeping the existing gallery) when the full payload request fails.

Copilot uses AI. Check for mistakes.
Comment thread static/js/script.js

$("#btn-generate-illustrations").on("click", function () {
clearAlerts();
var $btn = $(this);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var $btn = $(this); is unused in this click handler. Removing it avoids dead code and keeps the handler easier to maintain.

Suggested change
var $btn = $(this);

Copilot uses AI. Check for mistakes.
Comment thread templates/index.html
<h6 class="text-muted mb-2">Illustrations</h6>
<button class="btn btn-outline-primary" id="btn-generate-illustrations">
<span class="spinner-border spinner-border-sm d-none me-2" id="illustrations-spinner"></span>
<span id="illustrations-spinner-label" class="d-none me-1"></span>
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This label is updated live during polling but lacks the aria-live pattern used elsewhere in this template (e.g., #progress-label). Adding aria-live="polite" (and optionally role="status") will make progress updates accessible to screen readers.

Suggested change
<span id="illustrations-spinner-label" class="d-none me-1"></span>
<span id="illustrations-spinner-label" class="d-none me-1" aria-live="polite" role="status"></span>

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Images Not Generating (Illustration Pipeline Failure)

3 participants