Skip to content

Conversation

patel-ayushi
Copy link

@patel-ayushi patel-ayushi commented Aug 10, 2025

Description

Implemented a comprehensive report bundle generation system that creates downloadable ZIP archives containing detailed analytics and artifacts from image generation sessions across all DreamLayer tabs (Txt2Img, Img2Img, Extras).
Key Features: One-click ZIP generation with results.csv, config.json, organized image grids, and documentation. Cross-tab data persistence using Zustand with localStorage ensures data accumulates across tab switches and page refreshes. Real-time dashboard displays total images, individual counts by type, and dynamic generation badges (Txt2Img, Img2Img, Extras, or Multiple). Fresh start mechanism clears old data on service restart, while session automatically clears after report download. Includes comprehensive backend validation, frontend synchronization, and deterministic file paths for consistent reporting workflow.

Changes Made

Backend Changes

  • Created report_generator.py - Core report generation logic with CSV creation, image collection, and ZIP bundling
  • Modified dream_layer.py - Added new API endpoints: /api/gallery-data (GET/POST), /api/reports/generate, /api/reports/download, /api/reports/status
  • Updated start_dream_layer.sh - Added persistent data clearing on restart for fresh starts

Frontend Changes

  • Created ReportGenerator.tsx - Main reporting UI with real-time status, cross-tab data display, and download functionality
  • Created gallerySync.ts - Centralized sync utility for backend-frontend data synchronization and fresh start detection
  • Modified store files - Added persist middleware to useTxt2ImgGalleryStore.ts, useImg2ImgGalleryStore.ts, and created useExtrasGalleryStore.ts
  • Updated generation pages - Modified Txt2ImgPage.tsx, Img2ImgPage.tsx, and ExtrasPage.tsx to auto-sync data to backend after image generation

Data Flow Changes

  • Cross-tab persistence - Images from any tab now accumulate in a shared backend state
  • Real-time synchronization - Frontend stores automatically sync with backend after each generation
  • Fresh start mechanism - Service restarts now clear all persistent data (backend files + frontend localStorage)
  • Session management - Report download triggers complete data clearing for new workflow sessions

Evidence Required ✅

UI Screenshot

Screenshot 2025-08-10 at 12 15 01 AM Screenshot 2025-08-10 at 12 14 35 AM Screenshot 2025-08-10 at 12 14 14 AM Screenshot 2025-08-10 at 12 14 08 AM Screenshot 2025-08-10 at 12 14 00 AM Screenshot 2025-08-10 at 12 13 48 AM Screenshot 2025-08-10 at 12 13 38 AM Screenshot 2025-08-10 at 12 13 25 AM Screenshot 2025-08-10 at 12 12 49 AM

Logs

[img2txt_server.log](https://github.com/user-attachments/files/21703591/img2txt_server.log)
[report_bundle.log](https://github.com/user-attachments/files/21703592/report_bundle.log)
[run_registry.log](https://github.com/user-attachments/files/21703593/run_registry.log)


## Checklist
- [ X] UI screenshot provided
- [X ] Generated image provided  
- [ X] Logs provided
- [ X] Tests added (optional)
- [ X] Code follows project style
- [ X] Self-review completed

## Summary by Sourcery

Implement comprehensive report bundle generation with new backend logic and API endpoints, frontend Reports UI, cross-tab data persistence, and extensive testing

New Features:
- Add `report_generator.py` module for assembling ZIP bundles containing results.csv, config.json, image grids, and README
- Introduce backend API endpoints for updating gallery data, checking report status, generating, downloading, and validating report bundles
- Create a Reports tab and `ReportGenerator.tsx` component with real-time dashboard, progress tracking, and one-click report generation/download
- Implement `GallerySync` utility to synchronize gallery state between frontend stores and backend automatically

Enhancements:
- Persist gallery state across tabs and reloads using Zustand `persist` middleware for Txt2Img, Img2Img, and Extras stores
- Add fresh start logic to clear stale data on service restart and after report download

Tests:
- Add comprehensive backend test suite for ReportGenerator and API endpoints

Chores:
- Add Reports tab to navigation and update startup script to clear persistent gallery data

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Comprehensive report generation UI and backend, with bundle creation, validation, and download.
  * Added "Reports" tab and Report Generator page in the frontend.
  * Gallery synchronization across txt2img, img2img, and extras (auto-sync, add-and-sync, clear/refresh).

* **Bug Fixes**
  * Improved gallery state consistency after backend restarts/clean starts.

* **Tests**
  * Multiple unit/integration and standalone end-to-end test scripts for gallery sync and report workflows.

* **Chores**
  * Clear persistent gallery data on startup; added demo/test image generators.

* **Documentation**
  * New debug page for frontend state inspection and API testing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Aug 10, 2025

Reviewer's Guide

This PR implements a full report bundle generation workflow by introducing a backend ReportGenerator with new Flask endpoints, integrating cross-tab state persistence and real-time synchronization in the frontend, and adding a one-click ZIP generator UI with detailed analytics and demo/test coverage.

Sequence diagram for report bundle generation and download

sequenceDiagram
    actor User
    participant Frontend
    participant Backend
    participant ReportGenerator
    User->>Frontend: Click 'Generate Report Bundle'
    Frontend->>Backend: POST /api/gallery-data (sync images)
    Backend->>ReportGenerator: Store gallery data
    Frontend->>Backend: POST /api/reports/generate
    Backend->>ReportGenerator: create_report_bundle()
    ReportGenerator->>Backend: Return report metadata
    Backend->>Frontend: Respond with report info
    User->>Frontend: Click 'Download Report Bundle'
    Frontend->>Backend: GET /api/reports/download/<filename>
    Backend->>Frontend: Send ZIP file
    Frontend->>Backend: POST /api/gallery-data (clear data)
    Backend->>ReportGenerator: Clear gallery data
    Frontend->>User: Show download and reset UI
Loading

Class diagram for new and updated gallery stores and ReportGenerator

classDiagram
    class ReportGenerator {
      +fetch_gallery_data()
      +create_csv_records()
      +write_csv()
      +generate_config_json()
      +generate_readme()
      +copy_images_to_bundle()
      +create_report_bundle()
      +_validate_csv_paths_in_zip()
    }
    class ImageRecord {
      +id: str
      +filename: str
      +relative_path: str
      +prompt: str
      +negative_prompt: str
      +model_name: str
      +sampler_name: str
      +steps: int
      +cfg_scale: float
      +width: int
      +height: int
      +seed: int
      +timestamp: str
      +generation_type: str
      +batch_index: int
      +denoising_strength: float
      +input_image_path: str
      +lora_models: str
      +controlnet_info: str
      +file_size_bytes: int
      +get_required_columns()
      +validate_csv_schema(csv_path)
    }
    class useTxt2ImgGalleryStore {
      +images: ImageResult[]
      +addImages(newImages)
      +clearImages()
      +removeImage(id)
      +setLoading(loading)
    }
    class useImg2ImgGalleryStore {
      +images: ImageResult[]
      +addImages(newImages)
      +clearImages()
      +removeImage(id)
      +setLoading(loading)
    }
    class useExtrasGalleryStore {
      +images: ImageResult[]
      +addImages(newImages)
      +clearImages()
      +removeImage(id)
      +setLoading(loading)
    }
    ReportGenerator --> ImageRecord
    useTxt2ImgGalleryStore --|> ImageResult
    useImg2ImgGalleryStore --|> ImageResult
    useExtrasGalleryStore --|> ImageResult
Loading

Class diagram for GallerySync utility

classDiagram
    class GallerySync {
      +syncToBackend()
      +syncFromBackend()
      +addImageAndSync(type, images)
      +clearAll()
      +ensureFreshStart()
    }
    GallerySync --> useTxt2ImgGalleryStore
    GallerySync --> useImg2ImgGalleryStore
    GallerySync --> useExtrasGalleryStore
Loading

File-Level Changes

Change Details Files
Introduced backend report generation logic and API endpoints
  • Added report_generator.py with ImageRecord schema and ZIP bundling workflow
  • Exposed /api/gallery-data, /api/reports/status, /api/reports/generate, /api/reports/download, /api/reports/validate-csv
  • Cleared persistent gallery data on service restart in start_dream_layer.sh
dream_layer_backend/report_generator.py
dream_layer_backend/dream_layer.py
start_dream_layer.sh
Added frontend ReportGenerator UI and navigation
  • Created ReportGenerator.tsx component with dashboard, progress and download controls
  • Registered Reports tab in TabsNav and routed to ReportGenerator in Index.tsx
  • Implemented update, generate, download, and clear-session logic calling new backend endpoints
dream_layer_frontend/src/components/ReportGenerator.tsx
dream_layer_frontend/src/components/Navigation/TabsNav.tsx
dream_layer_frontend/src/pages/Index.tsx
Enabled cross-tab persistence and backend sync
  • Applied Zustand persist middleware to txt2img, img2img and extras gallery stores
  • Built GallerySync utility for centralized state sync to/from backend
  • Updated generation pages to sync stored images on mount and after each generation
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx
dream_layer_frontend/src/features/Extras/ExtrasPage.tsx
dream_layer_frontend/src/utils/gallerySync.ts
Optimized workflows for faster generation
  • Forced batch_size=1 and limited steps to 15 in txt2img_workflow.py and img2img_workflow.py
  • Pinned model_name to a fast variant for both workflows
dream_layer_backend/txt2img_workflow.py
dream_layer_backend/img2img_workflow.py
Expanded tests and demo scripts
  • Added comprehensive test_report_system.py covering ReportGenerator methods and API flows
  • Introduced standalone API tests, demo and image-generation scripts
  • Included integration and frontend sync simulation tests
dream_layer_backend/test_report_system.py
dream_layer_backend/test_api_standalone.py
dream_layer_backend/demo_report_workflow.py
dream_layer_backend/create_test_images.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds end-to-end report generation and gallery sync: backend report generator and API endpoints, frontend sync utilities and UI (Reports tab + ReportGenerator), persistent gallery stores, multiple test/demo scripts, and startup logic to reset gallery data.

Changes

Cohort / File(s) Change Summary
Backend report core
dream_layer_backend/report_generator.py
New ReportGenerator and ImageRecord: fetch gallery data, create CSV records, copy images, generate config/README, assemble ZIP report bundle, validate CSV paths, and return bundle metadata.
Backend API & state
dream_layer_backend/dream_layer.py,
dream_layer_backend/temp_gallery_data.json
New Flask endpoints: POST/GET /api/gallery-data, GET /api/reports/status, POST /api/reports/generate, GET /api/reports/download/<filename>, POST /api/reports/validate-csv. Adds temp gallery JSON initialization.
Frontend UI — Reports
dream_layer_frontend/src/components/ReportGenerator.tsx,
dream_layer_frontend/src/components/Navigation/TabsNav.tsx,
dream_layer_frontend/src/pages/Index.tsx
Adds Reports tab and ReportGenerator component to trigger generation, show progress/results, and download report bundle.
Frontend gallery sync utility
dream_layer_frontend/src/utils/gallerySync.ts
New GallerySync class to sync frontend galleries (txt2img/img2img/extras) to/from backend, add images with delayed sync, clear state, and ensure fresh start.
Frontend stores (persistence + extras)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts,
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts,
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts
Add/modify Zustand stores to use persist for txt2img/img2img and introduce a new extras store; persist only serializable parts (images/coreSettings).
Frontend pages integration
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx,
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx,
dream_layer_frontend/src/features/Extras/ExtrasPage.tsx
Replace direct store updates with GallerySync.addImageAndSync(...); syncFromBackend on mount to load backend state.
Type import update
dream_layer_frontend/src/utils/imageTransfer.ts
Adjusted ImageResult import source to match type refactor.
Backend workflow parameter changes
dream_layer_backend/txt2img_workflow.py,
dream_layer_backend/img2img_workflow.py
Force batch_size=1, cap steps ≤15, and force/use a specific fast model when flagged; adds log notices for forced model selection.
Startup script
start_dream_layer.sh
Clear dream_layer_backend/temp_gallery_data.json at startup to reset gallery state.
Frontend debug page
debug_frontend_state.html
New manual debug HTML to POST sample gallery data, request report generation, and check backend state with logs.
Test & demo scripts
dream_layer_backend/test_report_system.py,
dream_layer_backend/test_frontend_sync.py,
dream_layer_backend/test_api_standalone.py,
dream_layer_backend/demo_report_workflow.py,
dream_layer_backend/create_test_images.py,
dream_layer_backend/update_gallery_with_real_images.py,
complete_workflow_test.py
New unit/integration tests, standalone API tests, demo workflows, image generators, and end-to-end simulation scripts to validate gallery sync and report generation endpoints and bundle contents.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Frontend
    participant GallerySync
    participant BackendAPI
    participant ReportGenerator

    Frontend->>GallerySync: addImageAndSync(type, images)
    GallerySync->>BackendAPI: POST /api/gallery-data
    BackendAPI-->>GallerySync: 200 OK

    Frontend->>BackendAPI: POST /api/reports/generate {filename?}
    BackendAPI->>ReportGenerator: create_report_bundle(gallery_data)
    ReportGenerator-->>BackendAPI: {report_path, stats, validations}
    BackendAPI-->>Frontend: {status, report info}
    Frontend->>BackendAPI: GET /api/reports/download/<filename>
    BackendAPI-->>Frontend: ZIP file
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • darcy3000

Poem

"I hopped through folders, nose a-gleam,
CSVs and ZIPs — a syncer's dream.
Frontend hums and backend sings,
Reports packed tight with little wings.
A rabbit cheers: the pipeline's neat — go press that 'Generate' and eat a carrot treat! 🥕🐇"

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @patel-ayushi - I've reviewed your changes and they look great!

Blocking issues:

  • function health_check is defined inside a function but never used (link)
  • function update_gallery_data is defined inside a function but never used (link)
  • function generate_report is defined inside a function but never used (link)
  • function validate_csv_schema is defined inside a function but never used (link)
  • time.sleep() call; did you mean to leave this in? (link)
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `dream_layer_backend/dream_layer.py:625` </location>
<code_context>
+                "message": "No data provided"
+            }), 400
+        
+        # Store gallery data temporarily for report generation
+        # In a production system, this would be stored in a database
+        gallery_file = os.path.join(os.path.dirname(__file__), 'temp_gallery_data.json')
+        with open(gallery_file, 'w', encoding='utf-8') as f:
+            json.dump(data, f, indent=2, ensure_ascii=False)
+        
</code_context>

<issue_to_address>
Storing gallery data in a file may lead to concurrency issues.

Without file locking or atomic writes, simultaneous requests may cause data corruption. Please implement file locks or consider a more reliable storage solution for concurrent access.
</issue_to_address>

### Comment 2
<location> `dream_layer_backend/txt2img_workflow.py:40` </location>
<code_context>
     height = max(64, min(2048, int(data.get('height', 512))))
-    batch_size = max(1, min(8, int(data.get('batch_size', 1))))
-    steps = max(1, min(150, int(data.get('steps', 20))))
+    batch_size = 1  # Force batch_size to 1 for faster generation
+    steps = min(15, max(1, int(data.get('steps', 15))))  # Max 15 steps for speed
     cfg_scale = max(1.0, min(20.0, float(data.get('cfg_scale', 7.0))))
     denoising_strength = max(
</code_context>

<issue_to_address>
Forcing batch_size and steps may reduce flexibility for users.

If these constraints are intended for a specific mode, make them configurable or document the restriction to prevent user confusion.
</issue_to_address>

### Comment 3
<location> `dream_layer_backend/img2img_workflow.py:77` </location>
<code_context>
     height = max(64, min(2048, int(data.get('height', 512))))
-    batch_size = max(1, min(8, int(data.get('batch_size', 1))))
-    steps = max(1, min(150, int(data.get('steps', 20))))
+    batch_size = 1  # Force batch_size to 1 for faster generation
+    steps = min(15, max(1, int(data.get('steps', 15))))  # Max 15 steps for speed
     cfg_scale = max(1.0, min(20.0, float(data.get('cfg_scale', 7.0))))
     denoising_strength = max(
         0.0, min(1.0, float(data.get('denoising_strength', 0.75))))
     input_image = data.get('input_image', '')
-    model_name = data.get('model_name', 'v1-6-pruned-emaonly-fp16.safetensors')
+    model_name = "v15PrunedEmaonly_v15PrunedEmaonly.safetensors"  # Force fast model
+    print(f"Forcing model: {model_name} for faster generation")
     sampler_name = data.get('sampler_name', 'euler')
     scheduler = data.get('scheduler', 'normal')
</code_context>

<issue_to_address>
Forcing batch_size and model_name reduces user configurability.

Please consider allowing users to configure batch_size and model_name, or make the forced values opt-in, to avoid unexpected behavior.
</issue_to_address>

### Comment 4
<location> `dream_layer_frontend/src/utils/gallerySync.ts:122` </location>
<code_context>
+    }
+
+    // Wait a bit for state to update, then sync to backend
+    setTimeout(async () => {
+      await this.syncToBackend();
+    }, 100);
+  }
+
</code_context>

<issue_to_address>
Using setTimeout for state synchronization may introduce race conditions.

Using a fixed delay does not guarantee the state is updated before syncing. Instead, trigger the backend sync in response to the actual state change, such as via a callback or subscription.

Suggested implementation:

```typescript
    }

    // Subscribe to gallery store changes and sync to backend
    switch (galleryType) {
      case 'txt2img':
        useTxt2ImgGalleryStore.subscribe(() => {
          this.syncToBackend();
        });
        break;
      case 'img2img':
        useImg2ImgGalleryStore.subscribe(() => {
          this.syncToBackend();
        });
        break;
      case 'extras':
        useExtrasGalleryStore.subscribe(() => {
          this.syncToBackend();
        });
        break;
    }
  }

```

- If the subscription should only be registered once (not every time this function runs), consider moving the subscription logic to an initialization function or constructor.
- If you want to sync only on specific state changes (e.g., when images are added), you may need to compare previous and next state in the subscription callback.
- Ensure that `useTxt2ImgGalleryStore`, `useImg2ImgGalleryStore`, and `useExtrasGalleryStore` are Zustand stores and expose a `.subscribe` method.
</issue_to_address>

## Security Issues

### Issue 1
<location> `dream_layer_backend/test_api_standalone.py:30` </location>

<issue_to_address>
**security (python.lang.maintainability.useless-inner-function):** function `health_check` is defined inside a function but never used

*Source: opengrep*
</issue_to_address>

### Issue 2
<location> `dream_layer_backend/test_api_standalone.py:34` </location>

<issue_to_address>
**security (python.lang.maintainability.useless-inner-function):** function `update_gallery_data` is defined inside a function but never used

*Source: opengrep*
</issue_to_address>

### Issue 3
<location> `dream_layer_backend/test_api_standalone.py:60` </location>

<issue_to_address>
**security (python.lang.maintainability.useless-inner-function):** function `generate_report` is defined inside a function but never used

*Source: opengrep*
</issue_to_address>

### Issue 4
<location> `dream_layer_backend/test_api_standalone.py:97` </location>

<issue_to_address>
**security (python.lang.maintainability.useless-inner-function):** function `validate_csv_schema` is defined inside a function but never used

*Source: opengrep*
</issue_to_address>

### Issue 5
<location> `dream_layer_backend/test_api_standalone.py:144` </location>

<issue_to_address>
**security (python.lang.best-practice.arbitrary-sleep):** time.sleep() call; did you mean to leave this in?

*Source: opengrep*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 39

🔭 Outside diff range comments (2)
dream_layer_frontend/src/utils/imageTransfer.ts (1)

2-13: Optimize transferImages lookup and confirm id presence

  • Verified that ImageResult in src/types/generationSettings.ts has an id: string.
  • To reduce the filter’s complexity from O(n·m) to O(n + m) when ids is large, convert ids to a Set before filtering.

File: src/utils/imageTransfer.ts

 export const transferImages = (
   srcStore: { images: ImageResult[] },
   dstStore: { addImages: (images: ImageResult[]) => void },
   ids: string[]
 ) => {
-  const imagesToTransfer = srcStore.images.filter(img => ids.includes(img.id));
+  const idSet = new Set(ids);
+  const imagesToTransfer = srcStore.images.filter(img => idSet.has(img.id));
   if (imagesToTransfer.length > 0) {
     dstStore.addImages(imagesToTransfer);
   }
 };
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (1)

190-205: Wrap awaited sync in try/finally inside onload; otherwise errors are uncaught and UI may not reset

Errors thrown in testImage.onload = async () => { await ... } won’t be caught by the outer try/catch. Ensure loading state resets even if sync fails.

-testImage.onload = async () => {
-  console.log('Test image loaded successfully:', firstImageUrl);
-  const images = data.comfy_response.generated_images.map((img: any) => ({
-    id: `${Date.now()}-${Math.random()}`,
-    url: img.url,
-    prompt: requestData.prompt,
-    negativePrompt: requestData.negative_prompt,
-    timestamp: Date.now(),
-    settings: requestData
-  }));
-  
-  console.log('Adding images to store:', images);
-  
-  // Use centralized sync to add images and sync to backend
-  await GallerySync.addImageAndSync('img2img', images);
-  
-  setLoading(false);
-  setIsGenerating(false);
-};
+testImage.onload = async () => {
+  console.log('Test image loaded successfully:', firstImageUrl);
+  const images = data.comfy_response.generated_images.map((img: any) => ({
+    id: `${Date.now()}-${Math.random()}`,
+    url: img.url,
+    prompt: requestData.prompt,
+    negativePrompt: requestData.negative_prompt,
+    timestamp: Date.now(),
+    settings: requestData
+  }));
+  console.log('Adding images to store:', images);
+  try {
+    await GallerySync.addImageAndSync('img2img', images);
+  } catch (err) {
+    console.error('Failed to sync generated images to backend:', err);
+  } finally {
+    setLoading(false);
+    setIsGenerating(false);
+  }
+};
🧹 Nitpick comments (36)
dream_layer_backend/create_test_images.py (4)

8-8: Remove unused import

shutil is imported but never used.

-import shutil

29-31: Backward-compatibility for Pillow versions lacking textbbox (optional)

Some environments may run older Pillow versions without textbbox. Provide a small fallback to textsize to avoid crashes.

-    bbox = draw.textbbox((0, 0), text, font=font)
-    text_width = bbox[2] - bbox[0]
-    text_height = bbox[3] - bbox[1]
+    try:
+        bbox = draw.textbbox((0, 0), text, font=font)
+        text_width = bbox[2] - bbox[0]
+        text_height = bbox[3] - bbox[1]
+    except AttributeError:
+        # Fallback for older Pillow
+        text_width, text_height = draw.textsize(text, font=font)

15-17: Deterministic test assets (optional)

For reproducible tests, consider seeding random or deriving colors deterministically from filename/text.

-    bg_color = random.choice(colors)
+    # For reproducibility in tests, seed before calling or derive a stable color
+    bg_color = random.choice(colors)

171-171: Remove extraneous f-string

No placeholders; plain string is cleaner.

-    print(f"📄 Gallery data saved to: temp_gallery_data.json")
+    print("📄 Gallery data saved to: temp_gallery_data.json")
dream_layer_backend/temp_gallery_data.json (1)

1-5: Seed structure LGTM; avoid committing runtime mutations

The empty arrays for txt2img/img2img/extras match the backend’s expected shape.

Operational tip:

  • Ensure this file is treated as a seed. Consider guarding against accidental commits of runtime mutations (e.g., add a pre-commit hook or mark as assume-unchanged).
  • Medium-term: file-based shared state can suffer from concurrent writes; an in-memory cache with periodic flush, or a lightweight DB (SQLite) with atomic writes would be more robust. Happy to draft a migration plan if useful.
dream_layer_frontend/src/components/Navigation/TabsNav.tsx (1)

1-1: Minor nit: add a space after the comma for readability

HardDrive,FolderArchiveHardDrive, FolderArchive

-import { FileText, ImageIcon, Settings, GalleryHorizontal, HardDrive,FolderArchive, History, Download, MessageSquare } from "lucide-react";
+import { FileText, ImageIcon, Settings, GalleryHorizontal, HardDrive, FolderArchive, History, Download, MessageSquare } from "lucide-react";

Also verify your lucide-react version includes FolderArchive; if not, pick a supported icon.

dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (2)

19-23: Drop unused store imports unless you plan to observe them

useImg2ImgGalleryStore and useExtrasGalleryStore are only used to select images below and those selections aren’t consumed elsewhere. Remove the imports to avoid unnecessary subscriptions/re-renders, or add an effect to react to changes if that was the intention.

-import { useImg2ImgGalleryStore } from '@/stores/useImg2ImgGalleryStore';
-import { useExtrasGalleryStore } from '@/stores/useExtrasGalleryStore';
+// (remove if not observing other stores here)
 import { Txt2ImgCoreSettings, defaultTxt2ImgSettings } from '@/types/generationSettings';
 import { GallerySync } from '@/utils/gallerySync';

44-46: Remove unused selectors or wire them into an autosync effect

txt2imgImages, img2imgImages, and extrasImages aren’t read later. Keep only what’s used, or add an effect to auto-sync when any gallery changes.

-const txt2imgImages = useTxt2ImgGalleryStore(state => state.images);
-const img2imgImages = useImg2ImgGalleryStore(state => state.images);
-const extrasImages = useExtrasGalleryStore(state => state.images);
+// Remove unless used for a watcher effect

Optional watcher pattern:

useEffect(() => {
  const id = setTimeout(() => GallerySync.syncToBackend(), 200);
  return () => clearTimeout(id);
}, [useTxt2ImgGalleryStore.getState().images]); // or derive a stable selector pattern
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (2)

15-17: Remove unused cross-store imports unless you will observe them

These imports exist only to select images that aren’t used later. Removing them will reduce needless subscriptions and re-renders.

-import { useTxt2ImgGalleryStore } from '@/stores/useTxt2ImgGalleryStore';
-import { useExtrasGalleryStore } from '@/stores/useExtrasGalleryStore';
+// (remove if not observing other stores here)

66-69: Drop unused image selectors or add a watcher effect

These selections aren’t used later; either remove them or add an autosync effect triggered by gallery changes.

-const txt2imgImages = useTxt2ImgGalleryStore(state => state.images);
-const img2imgImages = useImg2ImgGalleryStore(state => state.images);
-const extrasImages = useExtrasGalleryStore(state => state.images);
+// Remove unless you plan to observe and react to cross-store changes here
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (2)

14-34: Align clearImages/isLoading semantics across stores

Here clearImages resets isLoading to false, while img2img preserves it. Pick one convention across stores to reduce surprising behavior during cross-tab sync.


14-34: DRY opportunity: extract a tiny gallery store factory

Txt2Img and Extras stores are near-identical. Consider a helper like createSimpleGalleryStore(nameKey) to reduce duplication and ensure future changes propagate consistently.

dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)

43-46: Align clearImages/isLoading behavior with other stores

This store preserves isLoading in clearImages, while txt2img/extras reset it to false. Align for consistent UX, or document the difference.

-  clearImages: () => set((state) => ({
-    images: [],
-    isLoading: state.isLoading // Preserve the current loading state
-  })),
+  clearImages: () => set({ images: [], isLoading: false }),
dream_layer_backend/update_gallery_with_real_images.py (2)

6-6: Remove unused import

json is imported but never used.

-import json

121-124: Fix f-string without placeholders

Remove the unnecessary f prefix.

-    print(f"📊 Created gallery data:")
+    print("📊 Created gallery data:")
dream_layer_frontend/src/components/ReportGenerator.tsx (2)

161-168: Avoid orphaned timers; clear timeouts on unmount

The setTimeout calls re-fetch without cleanup. Store handles and clear them in the return cleanup to prevent stray updates after unmount or rapid tab switches.

useEffect(() => {
-  if (frontendTotalImages > 0 && frontendTotalImages !== backendImageCount) {
-    console.log(`🔄 Frontend count (${frontendTotalImages}) differs from backend (${backendImageCount}), refreshing...`);
-    setTimeout(() => {
-      fetchBackendImageCount(true); // Skip loading state for refresh
-    }, 1000); // Give time for sync to complete
-  }
+  let t: number | undefined;
+  if (frontendTotalImages > 0 && frontendTotalImages !== backendImageCount) {
+    console.log(`🔄 Frontend count (${frontendTotalImages}) differs from backend (${backendImageCount}), refreshing...`);
+    t = window.setTimeout(() => {
+      fetchBackendImageCount(true);
+    }, 1000);
+  }
+  return () => { if (t) clearTimeout(t); };
}, [frontendTotalImages, backendImageCount]);

useEffect(() => {
-  if (txt2imgImages.length > 0 || img2imgImages.length > 0 || extrasImages.length > 0) {
-    console.log(`🔄 Store change detected: txt2img=${txt2imgImages.length}, img2img=${img2imgImages.length}, extras=${extrasImages.length}`);
-    setTimeout(() => {
-      fetchBackendImageCount(true);
-    }, 1500); // Slightly longer delay for cross-tab scenarios
-  }
+  let t: number | undefined;
+  if (txt2imgImages.length > 0 || img2imgImages.length > 0 || extrasImages.length > 0) {
+    console.log(`🔄 Store change detected: txt2img=${txt2imgImages.length}, img2img=${img2imgImages.length}, extras=${extrasImages.length}`);
+    t = window.setTimeout(() => {
+      fetchBackendImageCount(true);
+    }, 1500);
+  }
+  return () => { if (t) clearTimeout(t); };
}, [txt2imgImages.length, img2imgImages.length, extrasImages.length]);

Also applies to: 171-178


269-293: Clear-all silently ignores backend errors

GallerySync.clearAll() posts to clear backend but doesn't check response.ok. Consider checking and surfacing a warning to the user if backend clear fails, to avoid UI-backend drift.

dream_layer_backend/test_frontend_sync.py (2)

7-7: Remove unused import

json isn't used in this script.

-import json

17-23: Stabilize generated IDs and timestamp format

Using a float timestamp in IDs can introduce . characters; also prefer ISO strings for timestamps to match backend expectations elsewhere.

-                "id": f"frontend_sim_{datetime.now().timestamp()}",
+                "id": f"frontend_sim_{int(datetime.now().timestamp())}",
...
-                "timestamp": datetime.now(timezone.utc).isoformat(),
+                "timestamp": datetime.now(timezone.utc).isoformat(),

Note: If backend expects negative_prompt, align the field name.

Is negativePrompt accepted by the backend schema, or should we send negative_prompt? I can update this test accordingly.

dream_layer_frontend/src/utils/gallerySync.ts (2)

34-41: Add fetch timeouts with AbortController for robustness

In browsers, fetch has no built-in timeout. Add AbortController to avoid hanging UIs when backend is down.

const withTimeout = async <T>(p: Promise<T>, ms = 10000): Promise<T> => {
  const ctrl = new AbortController();
  const id = setTimeout(() => ctrl.abort(), ms);
  try {
    // @ts-ignore
    return await p(ctrl.signal);
  } finally {
    clearTimeout(id);
  }
};

// Usage:
const post = (url: string, body: any) =>
  withTimeout(fetch(url, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(body), signal: (new AbortController()).signal }));

// Apply similarly to GETs.

Alternatively, wrap each fetch with a per-call AbortController and setTimeout.

Also applies to: 60-63, 137-147, 159-162


9-9: Consider env-based configuration for BACKEND_URL

Hardcoding localhost is brittle. Prefer Vite/Next env vars and default fallback.

-  private static readonly BACKEND_URL = 'http://localhost:5002';
+  private static readonly BACKEND_URL =
+    (import.meta as any).env?.VITE_BACKEND_URL ?? 'http://localhost:5002';
debug_frontend_state.html (2)

36-41: Unify timestamp format and include filename to better match backend schema

Use ISO timestamp (string) and include a filename field. This aligns with other tests and improves downstream consistency.

                         id: `debug_test_${Date.now()}`,
-                        url: "http://localhost:5001/api/images/test.png",
+                        filename: "test.png",
+                        url: "http://localhost:5001/api/images/test.png",
                         prompt: "debug test image",
                         negativePrompt: "blurry",
-                        timestamp: Date.now(),
+                        timestamp: new Date().toISOString(),

63-66: Guard JSON parsing on non-2xx responses

If the server returns HTML/error, response.json() will throw. Check ok first.

-                const result = await response.json();
-                log(`✅ Gallery sync result: ${JSON.stringify(result)}`);
+                if (response.ok) {
+                  const result = await response.json();
+                  log(`✅ Gallery sync result: ${JSON.stringify(result)}`);
+                } else {
+                  const text = await response.text();
+                  log(`❌ Gallery sync failed: ${response.status} ${text}`);
+                }
complete_workflow_test.py (2)

8-8: Remove unused import timezone

timezone is not used.

-from datetime import datetime, timezone
+from datetime import datetime

20-37: Consider setting filename explicitly to avoid relying on URL parsing

create_csv_records falls back to extracting filename from URL; providing filename is more robust.

Would you like me to patch this to include a filename field derived from the URL for determinism?

dream_layer_backend/dream_layer.py (1)

738-766: Align with PR objective: auto-clear session after download

PR states session data auto-clears after report download. This endpoint doesn’t clear temp_gallery_data.json. Consider clearing after response using after_this_request.

Example pattern:

from flask import after_this_request

@after_this_request
def _clear_session(response):
    try:
        gallery_file = os.path.join(os.path.dirname(__file__), 'temp_gallery_data.json')
        if os.path.exists(gallery_file):
            os.remove(gallery_file)
    except Exception:
        pass
    return response

Would you like me to wire this in and update frontend to re-sync after clear?

dream_layer_backend/test_report_system.py (3)

7-20: Trim unused imports to keep tests clean

Remove unused: json, time, threading, Path, Dict, Any, patch, MagicMock.

-import json
 import tempfile
 import shutil
 import zipfile
 import csv
-import time
 import requests
-import threading
-from pathlib import Path
-from typing import Dict, Any
 import unittest
-from unittest.mock import patch, MagicMock

329-334: Use a single with for multiple context managers

Simplifies nested contexts and satisfies linter SIM117.

-        with zipfile.ZipFile(result['report_path'], 'r') as zipf:
-            with zipf.open('results.csv') as csv_file:
-                with open(csv_path, 'wb') as f:
-                    f.write(csv_file.read())
+        with zipfile.ZipFile(result['report_path'], 'r') as zipf, \
+             zipf.open('results.csv') as csv_file, \
+             open(csv_path, 'wb') as f:
+            f.write(csv_file.read())

507-509: Remove f-prefix on constant string

Minor style fix flagged by linter (F541).

-        print(f"✅ Manual test completed successfully!")
+        print("✅ Manual test completed successfully!")
dream_layer_backend/report_generator.py (4)

8-8: Remove unused import Path

Not used in this module.

-from pathlib import Path

395-401: Rename unused dirs loop var to _dirs

Minor cleanup per linter B007.

-            with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
-                for root, dirs, files in os.walk(temp_dir):
+            with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
+                for root, _dirs, files in os.walk(temp_dir):

317-348: Optional: Include input images in bundle when present

You populate input_image_path for img2img but don’t copy input images. Consider decoding base64 settings['input_image'] and writing to grids/input_images/ to improve bundle completeness. This requires passing original gallery data or enriching records; happy to draft a design.

Shall I propose an approach that preserves provenance with minimal CSV bloat?


75-84: Coupling and side effects caution

Calling get_directories() in __init__ pulls settings and touches the filesystem. That’s fine operationally but can surprise consumers (tests/demos). Consider lazy evaluation or injecting paths for testability. The tests already subclass to override paths; documenting this would help.

dream_layer_backend/demo_report_workflow.py (3)

13-15: Remove unused imports

datetime and Path are unused.

-from datetime import datetime
-from pathlib import Path

337-341: Combine nested with statements

Cleaner and satisfies SIM117.

-            with zipfile.ZipFile(result['report_path'], 'r') as zipf:
-                with zipf.open('results.csv') as csv_file:
-                    with open(csv_path, 'wb') as f:
-                        f.write(csv_file.read())
+            with zipfile.ZipFile(result['report_path'], 'r') as zipf, \
+                 zipf.open('results.csv') as csv_file, \
+                 open(csv_path, 'wb') as f:
+                f.write(csv_file.read())

229-233: Remove f prefix from constant strings

Several print calls use f-strings without placeholders; remove f for clarity and to satisfy F541.

I can run an autofix pass (Ruff/Black) against this file if desired.

Also applies to: 241-246, 266-271, 278-281, 297-301, 303-306, 307-317, 311-317, 319-324, 363-366, 371-381, 383-383

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1911cd3 and d7d1fa7.

⛔ Files ignored due to path filters (4)
  • dream_layer_backend/reports/cross_tab_accumulation_test.zip is excluded by !**/*.zip
  • dream_layer_backend/reports/cross_tab_demo_complete.zip is excluded by !**/*.zip
  • dream_layer_backend/reports/dreamlayer_report_20250810T040213.zip is excluded by !**/*.zip
  • dream_layer_backend/reports/dreamlayer_report_20250810T041217.zip is excluded by !**/*.zip
📒 Files selected for processing (25)
  • complete_workflow_test.py (1 hunks)
  • debug_frontend_state.html (1 hunks)
  • dream_layer_backend/create_test_images.py (1 hunks)
  • dream_layer_backend/demo_report_workflow.py (1 hunks)
  • dream_layer_backend/dream_layer.py (1 hunks)
  • dream_layer_backend/img2img_workflow.py (1 hunks)
  • dream_layer_backend/report_generator.py (1 hunks)
  • dream_layer_backend/temp_gallery_data.json (1 hunks)
  • dream_layer_backend/test_api_standalone.py (1 hunks)
  • dream_layer_backend/test_frontend_sync.py (1 hunks)
  • dream_layer_backend/test_report_system.py (1 hunks)
  • dream_layer_backend/txt2img_workflow.py (2 hunks)
  • dream_layer_backend/update_gallery_with_real_images.py (1 hunks)
  • dream_layer_frontend/src/components/Navigation/TabsNav.tsx (1 hunks)
  • dream_layer_frontend/src/components/ReportGenerator.tsx (1 hunks)
  • dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (3 hunks)
  • dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (4 hunks)
  • dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (3 hunks)
  • dream_layer_frontend/src/pages/Index.tsx (2 hunks)
  • dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1 hunks)
  • dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (3 hunks)
  • dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (2 hunks)
  • dream_layer_frontend/src/utils/gallerySync.ts (1 hunks)
  • dream_layer_frontend/src/utils/imageTransfer.ts (1 hunks)
  • start_dream_layer.sh (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: divyaprakash0426
PR: DreamLayer-AI/DreamLayer#40
File: docker/Dockerfile.backend.dev:4-6
Timestamp: 2025-07-16T18:40:41.273Z
Learning: The DreamLayer project follows an iterative approach to Docker development, where basic Docker setup is established first, and missing dependencies (like PyYAML) are addressed in subsequent iterations when related services (like ComfyUI) are added to the Docker files.
📚 Learning: 2025-07-16T18:40:41.273Z
Learnt from: divyaprakash0426
PR: DreamLayer-AI/DreamLayer#40
File: docker/Dockerfile.backend.dev:4-6
Timestamp: 2025-07-16T18:40:41.273Z
Learning: The DreamLayer project follows an iterative approach to Docker development, where basic Docker setup is established first, and missing dependencies (like PyYAML) are addressed in subsequent iterations when related services (like ComfyUI) are added to the Docker files.

Applied to files:

  • start_dream_layer.sh
📚 Learning: 2025-07-16T05:27:07.946Z
Learnt from: divyaprakash0426
PR: DreamLayer-AI/DreamLayer#34
File: ComfyUI/custom_nodes/luma_photon_node/luma_photon_node.py:224-224
Timestamp: 2025-07-16T05:27:07.946Z
Learning: In the LumaPhotonDepth2Img node (ComfyUI/custom_nodes/luma_photon_node/luma_photon_node.py), the weight transformation `1.0 - image_weight` is intentional and functions as designed, despite the tooltip indicating higher values should preserve the image more.

Applied to files:

  • dream_layer_backend/txt2img_workflow.py
  • dream_layer_backend/img2img_workflow.py
📚 Learning: 2025-07-14T22:55:51.063Z
Learnt from: rockerBOO
PR: DreamLayer-AI/DreamLayer#28
File: dream_layer_frontend/src/components/WorkflowCustomNode.tsx:88-106
Timestamp: 2025-07-14T22:55:51.063Z
Learning: In the DreamLayer frontend codebase, the team prefers to rely on TypeScript's type system for data validation rather than adding defensive programming checks, when the types are well-defined and data flow is controlled.

Applied to files:

  • debug_frontend_state.html
📚 Learning: 2025-08-06T18:59:31.412Z
Learnt from: rachanavarsha
PR: DreamLayer-AI/DreamLayer#80
File: report_bundler/bundler.py:7-7
Timestamp: 2025-08-06T18:59:31.412Z
Learning: In report_bundler/bundler.py, the REQUIRED_COLUMNS set intentionally contains only essential fields (image_path, sampler, steps, cfg, preset, seed) needed for bundling logic. Additional columns like width, height, grid_label, and notes are treated as optional metadata.

Applied to files:

  • dream_layer_backend/report_generator.py
🧬 Code Graph Analysis (7)
start_dream_layer.sh (1)
start_dream_layer_linux.sh (1)
  • print_success (22-24)
dream_layer_frontend/src/pages/Index.tsx (2)
dream_layer_backend/report_generator.py (1)
  • ReportGenerator (75-456)
dream_layer_frontend/src/components/ReportGenerator.tsx (1)
  • ReportGenerator (36-491)
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (4)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)
  • useTxt2ImgGalleryStore (14-34)
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)
  • useImg2ImgGalleryStore (32-128)
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)
  • useExtrasGalleryStore (14-34)
dream_layer_frontend/src/utils/gallerySync.ts (1)
  • GallerySync (8-185)
dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (4)
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)
  • useExtrasGalleryStore (14-34)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)
  • useTxt2ImgGalleryStore (14-34)
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)
  • useImg2ImgGalleryStore (32-128)
dream_layer_frontend/src/utils/gallerySync.ts (1)
  • GallerySync (8-185)
dream_layer_backend/update_gallery_with_real_images.py (1)
dream_layer_backend/create_test_images.py (1)
  • main (44-174)
dream_layer_frontend/src/utils/gallerySync.ts (3)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)
  • useTxt2ImgGalleryStore (14-34)
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)
  • useImg2ImgGalleryStore (32-128)
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)
  • useExtrasGalleryStore (14-34)
dream_layer_backend/dream_layer.py (4)
dream_layer_backend/test_api_standalone.py (3)
  • update_gallery_data (35-58)
  • generate_report (61-95)
  • validate_csv_schema (98-122)
dream_layer_backend/report_generator.py (5)
  • ReportGenerator (75-456)
  • fetch_gallery_data (85-100)
  • create_report_bundle (350-429)
  • validate_csv_schema (48-73)
  • ImageRecord (15-73)
dream_layer_frontend/src/components/ReportGenerator.tsx (1)
  • ReportGenerator (36-491)
dream_layer_backend/demo_report_workflow.py (1)
  • fetch_gallery_data (183-184)
🪛 Ruff (0.12.2)
dream_layer_backend/create_test_images.py

8-8: shutil imported but unused

Remove unused import: shutil

(F401)


25-25: Do not use bare except

(E722)


171-171: f-string without any placeholders

Remove extraneous f prefix

(F541)

dream_layer_backend/img2img_workflow.py

80-80: Local variable denoising_strength is assigned to but never used

Remove assignment to unused variable denoising_strength

(F841)

dream_layer_backend/update_gallery_with_real_images.py

6-6: json imported but unused

Remove unused import: json

(F401)


121-121: f-string without any placeholders

Remove extraneous f prefix

(F541)

dream_layer_backend/test_frontend_sync.py

7-7: json imported but unused

Remove unused import: json

(F401)

complete_workflow_test.py

8-8: datetime.timezone imported but unused

Remove unused import: datetime.timezone

(F401)

dream_layer_backend/test_api_standalone.py

11-11: shutil imported but unused

Remove unused import: shutil

(F401)


15-15: flask.Flask imported but unused

Remove unused import: flask.Flask

(F401)


23-23: Redefinition of unused Flask from line 15

Remove definition: Flask

(F811)


150-150: Do not use bare except

(E722)

dream_layer_backend/demo_report_workflow.py

13-13: datetime.datetime imported but unused

Remove unused import: datetime.datetime

(F401)


14-14: pathlib.Path imported but unused

Remove unused import: pathlib.Path

(F401)


229-229: f-string without any placeholders

Remove extraneous f prefix

(F541)


241-241: f-string without any placeholders

Remove extraneous f prefix

(F541)


266-266: f-string without any placeholders

Remove extraneous f prefix

(F541)


278-278: f-string without any placeholders

Remove extraneous f prefix

(F541)


297-297: f-string without any placeholders

Remove extraneous f prefix

(F541)


303-303: f-string without any placeholders

Remove extraneous f prefix

(F541)


307-307: f-string without any placeholders

Remove extraneous f prefix

(F541)


311-311: f-string without any placeholders

Remove extraneous f prefix

(F541)


319-319: f-string without any placeholders

Remove extraneous f prefix

(F541)


335-335: f-string without any placeholders

Remove extraneous f prefix

(F541)


337-338: Use a single with statement with multiple contexts instead of nested with statements

(SIM117)


363-363: f-string without any placeholders

Remove extraneous f prefix

(F541)


365-365: f-string without any placeholders

Remove extraneous f prefix

(F541)


372-372: f-string without any placeholders

Remove extraneous f prefix

(F541)


374-374: f-string without any placeholders

Remove extraneous f prefix

(F541)


375-375: f-string without any placeholders

Remove extraneous f prefix

(F541)


376-376: f-string without any placeholders

Remove extraneous f prefix

(F541)


377-377: f-string without any placeholders

Remove extraneous f prefix

(F541)


378-378: f-string without any placeholders

Remove extraneous f prefix

(F541)


379-379: f-string without any placeholders

Remove extraneous f prefix

(F541)


381-381: f-string without any placeholders

Remove extraneous f prefix

(F541)


383-383: f-string without any placeholders

Remove extraneous f prefix

(F541)

dream_layer_backend/test_report_system.py

8-8: json imported but unused

Remove unused import: json

(F401)


13-13: time imported but unused

Remove unused import: time

(F401)


15-15: threading imported but unused

Remove unused import: threading

(F401)


16-16: pathlib.Path imported but unused

Remove unused import: pathlib.Path

(F401)


17-17: typing.Dict imported but unused

Remove unused import

(F401)


17-17: typing.Any imported but unused

Remove unused import

(F401)


19-19: unittest.mock.patch imported but unused

Remove unused import

(F401)


19-19: unittest.mock.MagicMock imported but unused

Remove unused import

(F401)


329-330: Use a single with statement with multiple contexts instead of nested with statements

(SIM117)


350-350: Do not use bare except

(E722)


507-507: f-string without any placeholders

Remove extraneous f prefix

(F541)

dream_layer_backend/report_generator.py

8-8: pathlib.Path imported but unused

Remove unused import: pathlib.Path

(F401)


253-256: Use ternary operator checkpoints = response.json() if response.status_code == 200 else [] instead of if-else-block

Replace if-else-block with checkpoints = response.json() if response.status_code == 200 else []

(SIM108)


257-257: Do not use bare except

(E722)


396-396: Loop control variable dirs not used within loop body

Rename unused dirs to _dirs

(B007)

🔇 Additional comments (13)
dream_layer_backend/create_test_images.py (1)

72-73: Verify image URLs match the serving backend

Ensure these URLs map to where your backend serves static images. In this PR, servers run on multiple ports; confirm that /api/images/* on the referenced ports actually serves dream_layer_backend/served_images/*.

Would you like a quick grep script to locate the image-serving endpoints and confirm the correct port/path?

Also applies to: 90-91, 108-109, 128-129, 147-148

start_dream_layer.sh (1)

179-181: Verified fresh-start schema sync & atomic write recommendation

Confirmed that the reset JSON

{"txt2img": [], "img2img": [], "extras": []}

matches the backend’s expected keys (seen in dream_layer.py, report_generator.py, temp_gallery_data.json, etc.).

• For safer writes, consider atomically replacing the file:

tmp=$(mktemp)  
printf '%s\n' '{"txt2img": [], "img2img": [], "extras": []}' > "$tmp" && mv "$tmp" dream_layer_backend/temp_gallery_data.json

• No other startup scripts (e.g. start_dream_layer_linux.sh) were found—if you add one, mirror this reset there as well.

dream_layer_frontend/src/pages/Index.tsx (1)

14-14: Import looks good

ReportGenerator integration via direct import is fine.

dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (1)

255-259: Centralized add + backend sync: LGTM

Using GallerySync.addImageAndSync('txt2img', images) keeps stores and backend consistent.

dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (1)

18-18: GallerySync integration import: LGTM

Good to centralize synchronization logic behind a utility.

dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)

14-34: Good use of Zustand persist with selective state

Persisting only images via partialize is correct; avoiding isLoading persistence prevents stale UI states. The prepend semantics in addImages are consistent with gallery UX.

dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)

14-34: LGTM; mirrors txt2img store with correct selective persistence

Implementation is straightforward and correct. Name key is unique; partialize excludes transient isLoading as intended.

dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (2)

42-51: Backend sync on mount looks good

Calling GallerySync.syncFromBackend() on mount is a sensible default to hydrate stores from backend.


171-190: ImageResult.timestamp is correctly typed as a number

The ImageResult interface in both src/types/imageResult.ts and src/types/generationSettings.ts declares timestamp: number, and you’re assigning Date.now() (which returns a number). No change is required here.

dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)

32-128: Selective persistence is implemented correctly

Persisting images and coreSettings (excluding File) aligns with the workflow and avoids serializing non-serializable state.

dream_layer_backend/test_api_standalone.py (1)

229-233: Good: explicit timeouts on report generation request

Nice use of a 30s timeout for a potentially heavy operation.

dream_layer_backend/dream_layer.py (1)

614-635: Confirm impact of strict gallery payload validation

I attempted to locate other callers of /api/gallery-data via Ripgrep, but the search failed to yield any matches. Before enforcing the schema below, please manually verify that all existing clients of this endpoint will include txt2img and img2img as arrays:

-        data = request.json
+        data = request.json
         if not data:
             return jsonify({
                 "status": "error",
                 "message": "No data provided"
             }), 400
+        # Minimal schema check
+        if not isinstance(data, dict) or not all(k in data for k in ('txt2img', 'img2img')):
+            return jsonify({"status": "error", "message": "Invalid gallery schema"}), 400
+        for k in ('txt2img', 'img2img', 'extras'):
+            if k in data and not isinstance(data[k], list):
+                return jsonify({"status": "error", "message": f"'{k}' must be a list"}), 400
dream_layer_backend/report_generator.py (1)

11-13: Make get_directories import robust and avoid circular/package issues

Unqualified from dream_layer import get_directories is fragile. Provide package-qualified import with fallback.

-from dream_layer import get_directories
+try:
+    # When running inside the package
+    from dream_layer_backend.dream_layer import get_directories  # type: ignore
+except Exception:
+    # Fallback for scripts/tests run from this folder
+    from dream_layer import get_directories  # type: ignore
⛔ Skipped due to learnings
Learnt from: divyaprakash0426
PR: DreamLayer-AI/DreamLayer#40
File: docker/Dockerfile.backend.dev:4-6
Timestamp: 2025-07-16T18:40:41.273Z
Learning: The DreamLayer project follows an iterative approach to Docker development, where basic Docker setup is established first, and missing dependencies (like PyYAML) are addressed in subsequent iterations when related services (like ComfyUI) are added to the Docker files.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (1)

314-324: Keep batch/WebSocket images in backend sync too.

Use GallerySync in the image_generated handler to persist images server-side as they stream in.

-      newSocket.on('image_generated', (data) => {
+      newSocket.on('image_generated', async (data) => {
         const newImage = {
           id: `${Date.now()}-${Math.random()}`,
           url: data.image_data.url,
           prompt: data.prompt,
           negativePrompt: coreSettings.negative_prompt,
           timestamp: Date.now(),
           settings: { ...coreSettings }
         };
-        addImages([newImage]);
+        await GallerySync.addImageAndSync('txt2img', [newImage]);
       });
♻️ Duplicate comments (12)
dream_layer_backend/img2img_workflow.py (1)

77-84: Don’t silently force batch/steps/model; gate via env flag, use logger, and wire denoise

Override only when “fast” preset is enabled; otherwise honor user inputs. Replace print with logger and use the already-parsed denoising_strength to fix Ruff F841.

Apply:

-    batch_size = 1  # Force batch_size to 1 for faster generation
-    steps = min(15, max(1, int(data.get('steps', 15))))  # Max 15 steps for speed
+    force_fast = os.getenv('DL_FORCE_FAST_PRESET', '1') == '1'
+    max_steps = int(os.getenv('DL_MAX_STEPS', '15'))
+    batch_size = 1 if force_fast else max(1, int(data.get('batch_size', 1)))
+    steps = (min(max_steps, max(1, int(data.get('steps', max_steps))))
+             if force_fast else max(1, int(data.get('steps', 15))))
-    model_name = "v15PrunedEmaonly_v15PrunedEmaonly.safetensors"  # Force fast model
-    print(f"Forcing model: {model_name} for faster generation")
+    requested = data.get('model_name') or data.get('ckpt_name')
+    default_fast = os.getenv('DL_FAST_MODEL', 'v15PrunedEmaonly_v15PrunedEmaonly.safetensors')
+    model_name = default_fast if force_fast else (requested or default_fast)
+    logger.info("Using model: %s (%s)", model_name, "forced fast" if force_fast else "requested/fallback")

And in core settings (outside this hunk):

-        'denoise': 1.0,
+        'denoise': denoising_strength,
dream_layer_backend/txt2img_workflow.py (1)

49-55: Make fast preset configurable; don’t override user inputs by default

Honor client-provided batch_size/steps unless an env-gated fast mode is on.

-        # Batch parameters with validation (from smallFeatures) - LIMITED TO 1 FOR PERFORMANCE
-        batch_size = 1  # Force batch_size to 1 for faster generation
-        print(f"\nBatch size: {batch_size} (forced to 1 for performance)")
-        
-        # Sampling parameters with validation - LIMITED STEPS FOR FASTER GENERATION
-        steps = min(15, max(1, int(data.get('steps', 15))))  # Max 15 steps for speed
+        force_fast = os.getenv('DL_FORCE_FAST_PRESET', '1') == '1'
+        max_steps = int(os.getenv('DL_MAX_STEPS', '15'))
+        if force_fast:
+            batch_size = 1
+            steps = min(max_steps, max(1, int(data.get('steps', max_steps))))
+            print(f"\nBatch size: {batch_size} (fast preset); steps: {steps} (max {max_steps})")
+        else:
+            batch_size = max(1, int(data.get('batch_size', 1)))
+            steps = max(1, int(data.get('steps', 15)))
dream_layer_backend/dream_layer.py (6)

622-648: Concurrent file writes: use atomic write to avoid corruption

Replace direct write with atomic rename via a temp file.

-        gallery_file = os.path.join(os.path.dirname(__file__), 'temp_gallery_data.json')
-        with open(gallery_file, 'w', encoding='utf-8') as f:
-            json.dump(data, f, indent=2, ensure_ascii=False)
+        gallery_file = os.path.join(os.path.dirname(__file__), 'temp_gallery_data.json')
+        import tempfile
+        dirpath = os.path.dirname(gallery_file)
+        with tempfile.NamedTemporaryFile('w', delete=False, dir=dirpath, encoding='utf-8') as tmp:
+            json.dump(data, tmp, indent=2, ensure_ascii=False)
+            tmp_path = tmp.name
+        os.replace(tmp_path, gallery_file)

649-669: Import robustness: use package-qualified import with fallback

Avoid bare from report_generator import ReportGenerator to prevent package import failures.

-        # Import here to avoid circular imports
-        from report_generator import ReportGenerator
+        # Import here to avoid circular imports
+        try:
+            from dream_layer_backend.report_generator import ReportGenerator
+        except ImportError:
+            from report_generator import ReportGenerator

670-707: Same import robustness for status endpoint

Mirror the qualified import + fallback.

-        # Import here to avoid circular imports
-        from report_generator import ReportGenerator
+        # Import here to avoid circular imports
+        try:
+            from dream_layer_backend.report_generator import ReportGenerator
+        except ImportError:
+            from report_generator import ReportGenerator

708-721: Path traversal via filename; sanitize before use

Validate and sanitize filename before passing to the generator.

-        data = request.json or {}
-        output_filename = data.get('filename')
+        data = request.json or {}
+        output_filename = data.get('filename')
+        if output_filename:
+            if any(sep in output_filename for sep in ('..', '/', '\\')):
+                return jsonify({"status": "error", "message": "Invalid filename"}), 400
+            output_filename = os.path.basename(output_filename)
+            if not output_filename.lower().endswith('.zip'):
+                output_filename += '.zip'

746-780: Harden download: validate first and safe-join inside reports dir

Use safe_join and check before touching the path.

-        reports_dir = os.path.join(os.path.dirname(__file__), 'reports')
-        report_path = os.path.join(reports_dir, filename)
-        
-        if not os.path.exists(report_path):
-            return jsonify({
-                "status": "error",
-                "message": "Report file not found"
-            }), 404
-        
-        # Security check: ensure filename doesn't contain path traversal
-        if '..' in filename or '/' in filename or '\\' in filename:
-            return jsonify({
-                "status": "error",
-                "message": "Invalid filename"
-            }), 400
+        reports_dir = os.path.join(os.path.dirname(__file__), 'reports')
+        # Security check before filesystem access
+        if any(sep in filename for sep in ('..', '/', '\\')):
+            return jsonify({"status": "error", "message": "Invalid filename"}), 400
+        from werkzeug.utils import safe_join
+        report_path = safe_join(reports_dir, filename)
+        if not report_path or not os.path.exists(report_path):
+            return jsonify({"status": "error", "message": "Report file not found"}), 404

781-807: Arbitrary file read in CSV validation; restrict to reports dir

Only allow CSVs within the reports directory.

-        data = request.json
+        data = request.json
         if not data or 'csv_path' not in data:
             return jsonify({
                 "status": "error",
                 "message": "CSV path not provided"
             }), 400
-        
-        csv_path = data['csv_path']
+        reports_dir = os.path.join(os.path.dirname(__file__), 'reports')
+        requested = os.path.basename(data['csv_path'])
+        from werkzeug.utils import safe_join
+        csv_path = safe_join(reports_dir, requested)
+        if not csv_path or not os.path.exists(csv_path):
+            return jsonify({"status": "error", "message": "CSV not found in reports directory"}), 404
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (1)

70-78: Run fresh-start check before first sync and handle errors (mirrors prior guidance).

Wrap initial sync in try/catch and call ensureFreshStart first.

   // Load existing data on component mount
   useEffect(() => {
     const loadExistingData = async () => {
-      console.log('📥 Img2Img: Loading existing gallery data from backend...');
-      await GallerySync.syncFromBackend();
+      try {
+        console.log('📥 Img2Img: Ensuring fresh start and loading gallery data from backend...');
+        await GallerySync.ensureFreshStart();
+        await GallerySync.syncFromBackend();
+      } catch (e) {
+        console.error('Failed to sync galleries on mount (img2img):', e);
+      }
     };
     
     loadExistingData();
   }, []);
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (1)

59-67: Run fresh-start check before first sync and handle errors (as previously requested).

   // Load existing data on component mount
   useEffect(() => {
     const loadExistingData = async () => {
-      console.log('📥 Txt2Img: Loading existing gallery data from backend...');
-      await GallerySync.syncFromBackend();
+      try {
+        console.log('📥 Txt2Img: Ensuring fresh start and loading gallery data...');
+        await GallerySync.ensureFreshStart();
+        await GallerySync.syncFromBackend();
+      } catch (e) {
+        console.error('Failed to sync galleries on mount (txt2img):', e);
+      }
     };
     
     loadExistingData();
   }, []);
dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (2)

39-41: Remove unused selectors to avoid re-renders.

These are unused and subscribe to foreign stores.

-  const txt2imgImages = useTxt2ImgGalleryStore(state => state.images);
-  const img2imgImages = useImg2ImgGalleryStore(state => state.images);

231-247: Fix condition typo and ensure integer dimensions; strengthen IDs.

Use 'resize-to' (matching UI), round dimensions, and add a short random suffix to reduce collisions.

-          id: `extras_${Date.now()}`,
+          id: `extras_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,
@@
-            width: upscaleMethod === 'upscale-to' ? resizeWidth : 512 * upscaleFactor,
-            height: upscaleMethod === 'upscale-to' ? resizeHeight : 512 * upscaleFactor,
+            width: upscaleMethod === 'resize-to' ? Math.round(resizeWidth) : Math.round(512 * upscaleFactor),
+            height: upscaleMethod === 'resize-to' ? Math.round(resizeHeight) : Math.round(512 * upscaleFactor),
🧹 Nitpick comments (7)
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (3)

66-68: Remove unused store selectors to avoid unnecessary re-renders.

These subscriptions trigger re-renders on unrelated updates and aren't used.

-  const txt2imgImages = useTxt2ImgGalleryStore(state => state.images);
-  const img2imgImages = useImg2ImgGalleryStore(state => state.images);
-  const extrasImages = useExtrasGalleryStore(state => state.images);

15-16: If selectors are removed, drop unused imports too.

-import { useTxt2ImgGalleryStore } from '@/stores/useTxt2ImgGalleryStore';
-import { useExtrasGalleryStore } from '@/stores/useExtrasGalleryStore';

138-141: Remove unused FormData creation.

You send JSON; this FormData is dead code and misleading.

-      const formData = new FormData();
-      formData.append('image', inputImage.file);
-
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (2)

52-54: Remove unused store selectors to prevent unrelated re-renders.

These values are never read in this component.

-  const txt2imgImages = useTxt2ImgGalleryStore(state => state.images);
-  const img2imgImages = useImg2ImgGalleryStore(state => state.images);
-  const extrasImages = useExtrasGalleryStore(state => state.images);

20-21: Drop unused imports if removing the selectors.

-import { useImg2ImgGalleryStore } from '@/stores/useImg2ImgGalleryStore';
-import { useExtrasGalleryStore } from '@/stores/useExtrasGalleryStore';
@@
-import { GallerySync } from '@/utils/gallerySync';
+import { GallerySync } from '@/utils/gallerySync';

Also applies to: 23-24

dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (2)

23-27: If selectors are removed, drop now-unused imports.

-import { useTxt2ImgGalleryStore } from '@/stores/useTxt2ImgGalleryStore';
-import { useImg2ImgGalleryStore } from '@/stores/useImg2ImgGalleryStore';
 import { ImageResult } from '@/types/generationSettings';
 import { GallerySync } from '@/utils/gallerySync';

42-50: Add fresh-start check and error handling on mount.

Match other tabs’ startup behavior for consistent persistence semantics.

   // Load existing data on component mount
   useEffect(() => {
     const loadExistingData = async () => {
-      console.log('📥 Extras: Loading existing gallery data from backend...');
-      await GallerySync.syncFromBackend();
+      try {
+        console.log('📥 Extras: Ensuring fresh start and loading gallery data...');
+        await GallerySync.ensureFreshStart();
+        await GallerySync.syncFromBackend();
+      } catch (e) {
+        console.error('Failed to sync galleries on mount (extras):', e);
+      }
     };
     
     loadExistingData();
   }, []);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7d1fa7 and ca9d84f.

📒 Files selected for processing (8)
  • dream_layer_backend/dream_layer.py (1 hunks)
  • dream_layer_backend/img2img_workflow.py (1 hunks)
  • dream_layer_backend/txt2img_workflow.py (2 hunks)
  • dream_layer_frontend/src/components/Navigation/TabsNav.tsx (1 hunks)
  • dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (3 hunks)
  • dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (4 hunks)
  • dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (3 hunks)
  • start_dream_layer.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • start_dream_layer.sh
  • dream_layer_frontend/src/components/Navigation/TabsNav.tsx
🧰 Additional context used
🧬 Code graph analysis (4)
dream_layer_frontend/src/features/Extras/ExtrasPage.tsx (4)
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)
  • useExtrasGalleryStore (14-34)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)
  • useTxt2ImgGalleryStore (14-34)
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)
  • useImg2ImgGalleryStore (32-128)
dream_layer_frontend/src/utils/gallerySync.ts (1)
  • GallerySync (8-185)
dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (4)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)
  • useTxt2ImgGalleryStore (14-34)
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)
  • useImg2ImgGalleryStore (32-128)
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)
  • useExtrasGalleryStore (14-34)
dream_layer_frontend/src/utils/gallerySync.ts (1)
  • GallerySync (8-185)
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (4)
dream_layer_frontend/src/stores/useTxt2ImgGalleryStore.ts (1)
  • useTxt2ImgGalleryStore (14-34)
dream_layer_frontend/src/stores/useImg2ImgGalleryStore.ts (1)
  • useImg2ImgGalleryStore (32-128)
dream_layer_frontend/src/stores/useExtrasGalleryStore.ts (1)
  • useExtrasGalleryStore (14-34)
dream_layer_frontend/src/utils/gallerySync.ts (1)
  • GallerySync (8-185)
dream_layer_backend/dream_layer.py (2)
dream_layer_backend/test_api_standalone.py (3)
  • update_gallery_data (35-58)
  • generate_report (61-95)
  • validate_csv_schema (98-122)
dream_layer_backend/report_generator.py (5)
  • ReportGenerator (75-456)
  • fetch_gallery_data (85-100)
  • create_report_bundle (350-429)
  • validate_csv_schema (48-73)
  • ImageRecord (15-73)
🪛 Ruff (0.12.2)
dream_layer_backend/dream_layer.py

643-643: Do not catch blind exception: Exception

(BLE001)


646-646: Use explicit conversion flag

Replace with conversion flag

(RUF010)


661-661: Do not catch blind exception: Exception

(BLE001)


664-664: Use explicit conversion flag

Replace with conversion flag

(RUF010)


702-702: Do not catch blind exception: Exception

(BLE001)


705-705: Use explicit conversion flag

Replace with conversion flag

(RUF010)


740-740: Do not catch blind exception: Exception

(BLE001)


743-743: Use explicit conversion flag

Replace with conversion flag

(RUF010)


775-775: Do not catch blind exception: Exception

(BLE001)


778-778: Use explicit conversion flag

Replace with conversion flag

(RUF010)


802-802: Do not catch blind exception: Exception

(BLE001)


805-805: Use explicit conversion flag

Replace with conversion flag

(RUF010)

dream_layer_backend/txt2img_workflow.py

76-76: SyntaxError: Expected except or finally after try block

dream_layer_backend/img2img_workflow.py

80-80: Local variable denoising_strength is assigned to but never used

Remove assignment to unused variable denoising_strength

(F841)

🔇 Additional comments (3)
dream_layer_frontend/src/features/Img2Img/Img2ImgPage.tsx (2)

203-205: Good use of centralized sync.

addImageAndSync keeps frontend and backend in step. LGTM.


18-18: Typo concern resolved
Search confirms every reference uses useImg2ImgGalleryStore (no lowercase “i” instances found).

Likely an incorrect or invalid review comment.

dream_layer_frontend/src/features/Txt2Img/Txt2ImgPage.tsx (1)

263-267: LGTM: centralized add + sync for single-generation flow.

Comment on lines +75 to +85
# Update the data with the actual seed used
data['seed'] = seed

# Handle model name validation
# Handle model name validation
if data.get("force_fast_model", False):
model_name = "v15PrunedEmaonly_v15PrunedEmaonly.safetensors" # Force fast model
print(f"Forcing model: {model_name} for faster generation")
else:
model_name = data.get('model_name', 'juggernautXL_v8Rundiffusion.safetensors')

# Check if it's a closed-source model (DALL-E, FLUX, Ideogram, Runway, Stability AI, Luma, Banana, etc.)
closed_source_models = ['dall-e-3', 'dall-e-2', 'flux-pro', 'flux-dev', 'ideogram-v3', 'runway-gen4', 'stability-sdxl', 'stability-sd-turbo', 'photon-1', 'photon-flash-1', 'banana-gemini']

# Check if it's a closed-source model (DALL-E, FLUX, Ideogram, Runway, Stability AI, Luma, Banana, etc.)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix syntax error: lines are outside the surrounding try block

Lines 75–76 and 78–85 are at the same indent as the outer try: (Line 35), causing “Expected except/finally after try”. Indent them into the try-suite.

-    # Update the data with the actual seed used
-    data['seed'] = seed
+        # Update the data with the actual seed used
+        data['seed'] = seed
-    # Handle model name validation
-    if data.get("force_fast_model", False):
-        model_name = "v15PrunedEmaonly_v15PrunedEmaonly.safetensors"  # Force fast model
-        print(f"Forcing model: {model_name} for faster generation")
-    else:
-        model_name = data.get('model_name', 'juggernautXL_v8Rundiffusion.safetensors')
+        # Handle model selection (env-gated fast preset)
+        force_fast = os.getenv('DL_FORCE_FAST_PRESET', '1') == '1'
+        requested = data.get('model_name') or data.get('ckpt_name')
+        default_fast = os.getenv('DL_FAST_MODEL', 'v15PrunedEmaonly_v15PrunedEmaonly.safetensors')
+        model_name = default_fast if force_fast else (requested or 'juggernautXL_v8Rundiffusion.safetensors')
+        print(f"Using model: {model_name} ({'forced fast' if force_fast else 'requested/fallback'})")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Update the data with the actual seed used
data['seed'] = seed
# Handle model name validation
# Handle model name validation
if data.get("force_fast_model", False):
model_name = "v15PrunedEmaonly_v15PrunedEmaonly.safetensors" # Force fast model
print(f"Forcing model: {model_name} for faster generation")
else:
model_name = data.get('model_name', 'juggernautXL_v8Rundiffusion.safetensors')
# Check if it's a closed-source model (DALL-E, FLUX, Ideogram, Runway, Stability AI, Luma, Banana, etc.)
closed_source_models = ['dall-e-3', 'dall-e-2', 'flux-pro', 'flux-dev', 'ideogram-v3', 'runway-gen4', 'stability-sdxl', 'stability-sd-turbo', 'photon-1', 'photon-flash-1', 'banana-gemini']
# Check if it's a closed-source model (DALL-E, FLUX, Ideogram, Runway, Stability AI, Luma, Banana, etc.)
try:
# … earlier code …
# Update the data with the actual seed used
data['seed'] = seed
# Handle model selection (env-gated fast preset)
force_fast = os.getenv('DL_FORCE_FAST_PRESET', '1') == '1'
requested = data.get('model_name') or data.get('ckpt_name')
default_fast = os.getenv(
'DL_FAST_MODEL',
'v15PrunedEmaonly_v15PrunedEmaonly.safetensors'
)
model_name = default_fast if force_fast else (requested or 'juggernautXL_v8Rundiffusion.safetensors')
print(f"Using model: {model_name} ({'forced fast' if force_fast else 'requested/fallback'})")
# Check if it's a closed-source model (DALL-E, FLUX, Ideogram, Runway, Stability AI, Luma, Banana, etc.)
except Exception as e:
🧰 Tools
🪛 Ruff (0.12.2)

76-76: SyntaxError: Expected except or finally after try block

🤖 Prompt for AI Agents
In dream_layer_backend/txt2img_workflow.py around lines 75–76 and 78–85, the
block that updates data['seed'] and determines model_name is currently at the
same indentation level as the outer try (starting ~line 35), causing a "Expected
except/finally after try" syntax error; move/indent these lines into the
try-suite so they are inside the try block (preserve existing logic, prints, and
comments) ensuring consistent indentation with the rest of the try body.

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.

1 participant