-
Notifications
You must be signed in to change notification settings - Fork 215
Completed Run registry UI stub Task and Report bundle Task #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThis update introduces a persistent run registry and a report bundle system to the Dream Layer project. It adds backend Flask APIs for run management and report generation, frontend pages and stores for interacting with these features, TypeScript types, and comprehensive tests. The startup script is updated to launch the new backend services and verify their connectivity. Changes
Sequence Diagram(s)Run Registration Flow (txt2img/img2img)sequenceDiagram
participant Client
participant Backend (txt2img/img2img_server)
participant ComfyUI
participant Run Registry API
Client->>Backend (txt2img/img2img_server): POST /api/txt2img or /api/img2img
Backend->>ComfyUI: Send generation request
ComfyUI-->>Backend: Return generated images
Backend->>Run Registry API: POST /api/runs (run config + image info)
Run Registry API-->>Backend: 200 OK (run registered)
Backend-->>Client: Return images + run_id
Report Bundle Generation FlowsequenceDiagram
participant Client
participant Frontend (ReportBundlePage)
participant Backend (report_bundle.py)
participant Run Registry API
Client->>Frontend: Click "Generate Report"
Frontend->>Backend: POST /api/report-bundle (optional run_ids)
Backend->>Run Registry API: GET /api/runs (fetch runs)
Run Registry API-->>Backend: Return run configs
Backend->>Backend: Assemble bundle (CSV, images, config, README)
Backend-->>Frontend: Return download link
Frontend-->>Client: Show download option
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Reviewer's GuideThis PR integrates a run registry and report bundle feature end-to-end by extending the txt2img/img2img servers to register completed runs, introducing two new backend Flask services for managing run configurations and packaging bundles, and adding corresponding UI tabs, pages, state stores, and tests to the frontend to view/delete runs and generate/download report bundles. Sequence diagram for registering a completed run (txt2img/img2img)sequenceDiagram
participant User as actor User
participant Frontend
participant Txt2ImgServer as txt2img/img2img Server
participant RunRegistryAPI as Run Registry API
User->>Frontend: Submit image generation request
Frontend->>Txt2ImgServer: POST /generate (with config)
Txt2ImgServer->>ComfyUI: Send workflow
ComfyUI-->>Txt2ImgServer: Return generated images
Txt2ImgServer->>RunRegistryAPI: POST /api/runs (with run config)
RunRegistryAPI-->>Txt2ImgServer: Run registered
Txt2ImgServer-->>Frontend: Respond with generated images and run_id
Frontend-->>User: Show result and run_id
Sequence diagram for generating and downloading a report bundlesequenceDiagram
participant User as actor User
participant Frontend
participant ReportBundleAPI as Report Bundle API
participant RunRegistryAPI as Run Registry API
User->>Frontend: Open Report Bundle tab
Frontend->>RunRegistryAPI: GET /api/runs
RunRegistryAPI-->>Frontend: List of runs
User->>Frontend: Select runs and click Generate Report
Frontend->>ReportBundleAPI: POST /api/report-bundle (with run_ids)
ReportBundleAPI->>RunRegistryAPI: Fetch run configs
ReportBundleAPI-->>Frontend: Report bundle ready
User->>Frontend: Click Download
Frontend->>ReportBundleAPI: GET /api/report-bundle/download
ReportBundleAPI-->>Frontend: report.zip
Frontend-->>User: Download report.zip
Class diagram for RunConfig and RunRegistry (backend)classDiagram
class RunConfig {
+str run_id
+str timestamp
+str model
+Optional~str~ vae
+List~Dict~ loras
+List~Dict~ controlnets
+str prompt
+str negative_prompt
+int seed
+str sampler
+int steps
+float cfg_scale
+int width
+int height
+int batch_size
+int batch_count
+Dict~str,Any~ workflow
+str version
+List~str~ generated_images
+str generation_type
}
class RunRegistry {
-Dict~str,RunConfig~ runs
+add_run(config: RunConfig)
+get_run(run_id: str) RunConfig
+get_all_runs() List~RunConfig~
+delete_run(run_id: str) bool
}
RunRegistry "1" o-- "*" RunConfig
Class diagram for ReportBundleGenerator (backend)classDiagram
class ReportBundleGenerator {
-str output_dir
-RunRegistry registry
+generate_csv(runs: List~RunConfig~) str
+validate_csv_schema(csv_path: str) bool
+copy_images_to_bundle(runs: List~RunConfig~, bundle_dir: str) List~str~
+create_config_json(runs: List~RunConfig~) str
+create_readme(runs: List~RunConfig~, copied_images: List~str~) str
+create_report_bundle(run_ids: Optional~List~str~~) str
}
ReportBundleGenerator --> RunRegistry
RunRegistry "1" o-- "*" RunConfig
Class diagram for RunConfig and stores (frontend types)classDiagram
class RunConfig {
+string run_id
+string timestamp
+string model
+string vae
+Array loras
+Array controlnets
+string prompt
+string negative_prompt
+number seed
+string sampler
+number steps
+number cfg_scale
+number width
+number height
+number batch_size
+number batch_count
+object workflow
+string version
+string[] generated_images
+string generation_type
}
class RunRegistryState {
+RunConfig[] runs
+boolean loading
+string error
+RunConfig selectedRun
}
class ReportBundleState {
+boolean generating
+string error
+string downloadUrl
}
RunRegistryState --> RunConfig
ReportBundleState --> RunConfig
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @jayashreeks - I've reviewed your changes - here's some feedback:
- The run registration logic in txt2img_server.py and img2img_server.py is nearly identical—consider extracting it into a shared helper function to reduce duplication and make maintenance easier.
- ReportBundleGenerator writes temp CSV, JSON, and README files with fixed names, which could collide if multiple bundles are created concurrently—using Python’s tempfile module or unique per‐request directories would avoid that risk.
- The startup script and frontend stores both hardcode service ports and URLs; centralizing those settings into a single configuration (env vars or a config file) would simplify updates and prevent inconsistencies.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The run registration logic in txt2img_server.py and img2img_server.py is nearly identical—consider extracting it into a shared helper function to reduce duplication and make maintenance easier.
- ReportBundleGenerator writes temp CSV, JSON, and README files with fixed names, which could collide if multiple bundles are created concurrently—using Python’s tempfile module or unique per‐request directories would avoid that risk.
- The startup script and frontend stores both hardcode service ports and URLs; centralizing those settings into a single configuration (env vars or a config file) would simplify updates and prevent inconsistencies.
## Individual Comments
### Comment 1
<location> `dream_layer_backend/img2img_server.py:217` </location>
<code_context>
"comfy_response": comfy_response,
- "workflow": workflow
+ "workflow": workflow,
+ "run_id": run_config.run_id if 'run_config' in locals() else None
})
</code_context>
<issue_to_address>
Possible None run_id in response if registration fails.
Consider omitting the run_id field or returning a clearer error message when registration fails, to avoid confusing clients with a null value.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
except Exception as e:
logger.warning(f"⚠️ Error registering run: {str(e)}")
response = jsonify({
"status": "success",
"message": "Workflow sent to ComfyUI successfully",
"comfy_response": comfy_response,
"workflow": workflow,
"run_id": run_config.run_id if 'run_config' in locals() else None
})
=======
except Exception as e:
logger.warning(f"⚠️ Error registering run: {str(e)}")
response = jsonify({
"status": "error",
"message": f"Failed to register run: {str(e)}",
"comfy_response": comfy_response,
"workflow": workflow
})
return response
response_data = {
"status": "success",
"message": "Workflow sent to ComfyUI successfully",
"comfy_response": comfy_response,
"workflow": workflow
}
if 'run_config' in locals() and hasattr(run_config, 'run_id'):
response_data["run_id"] = run_config.run_id
response = jsonify(response_data)
>>>>>>> REPLACE
</suggested_fix>
### Comment 2
<location> `dream_layer_backend/report_bundle.py:52` </location>
<code_context>
+ """Copy selected grid images to bundle directory"""
+ copied_images = []
+
+ for run in runs:
+ for image_filename in run.generated_images:
+ if image_filename:
+ # Source path in output directory
</code_context>
<issue_to_address>
No deduplication of image filenames when copying images.
This may cause files to be overwritten or duplicated. Please deduplicate the image list before copying.
</issue_to_address>
### Comment 3
<location> `dream_layer_backend/report_bundle.py:224` </location>
<code_context>
+ print(f"📊 Creating report bundle with {len(runs)} runs")
+
+ # Create temporary directory for bundle
+ bundle_dir = f"temp_report_bundle_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
+ os.makedirs(bundle_dir, exist_ok=True)
+
</code_context>
<issue_to_address>
Potential race condition with temp directory naming.
Using only seconds in the directory name may lead to collisions. Recommend adding uuid4 or microseconds for uniqueness.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
print(f"📊 Creating report bundle with {len(runs)} runs")
# Create temporary directory for bundle
=======
print(f"📊 Creating report bundle with {len(runs)} runs")
# Create temporary directory for bundle
import uuid
bundle_dir = f"temp_report_bundle_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4().hex}"
os.makedirs(bundle_dir, exist_ok=True)
>>>>>>> REPLACE
</suggested_fix>
### Comment 4
<location> `dream_layer_backend/run_registry.py:178` </location>
<code_context>
+ run_config = RunConfig(
</code_context>
<issue_to_address>
No validation of required fields in POST /api/runs.
Missing or incorrectly typed fields may cause malformed RunConfig objects or runtime errors. Please add validation for required fields and types before instantiating RunConfig.
</issue_to_address>
### Comment 5
<location> `dream_layer_frontend/src/features/ReportBundle/ReportBundlePage.tsx:31` </location>
<code_context>
+ }, [fetchRuns]);
+
+ const handleGenerateReport = async () => {
+ const runIds = selectedRuns.size > 0 ? Array.from(selectedRuns) : undefined;
+ await generateReport(runIds);
+ };
</code_context>
<issue_to_address>
Passing undefined for runIds may not match backend expectations.
Always pass an array (empty or with values) for runIds to ensure consistent backend behavior.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| except Exception as e: | ||
| logger.warning(f"⚠️ Error registering run: {str(e)}") | ||
|
|
||
| response = jsonify({ | ||
| "status": "success", | ||
| "message": "Workflow sent to ComfyUI successfully", | ||
| "comfy_response": comfy_response, | ||
| "workflow": workflow | ||
| "workflow": workflow, | ||
| "run_id": run_config.run_id if 'run_config' in locals() else None | ||
| }) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): Possible None run_id in response if registration fails.
Consider omitting the run_id field or returning a clearer error message when registration fails, to avoid confusing clients with a null value.
| except Exception as e: | |
| logger.warning(f"⚠️ Error registering run: {str(e)}") | |
| response = jsonify({ | |
| "status": "success", | |
| "message": "Workflow sent to ComfyUI successfully", | |
| "comfy_response": comfy_response, | |
| "workflow": workflow | |
| "workflow": workflow, | |
| "run_id": run_config.run_id if 'run_config' in locals() else None | |
| }) | |
| except Exception as e: | |
| logger.warning(f"⚠️ Error registering run: {str(e)}") | |
| response = jsonify({ | |
| "status": "error", | |
| "message": f"Failed to register run: {str(e)}", | |
| "comfy_response": comfy_response, | |
| "workflow": workflow | |
| }) | |
| return response | |
| response_data = { | |
| "status": "success", | |
| "message": "Workflow sent to ComfyUI successfully", | |
| "comfy_response": comfy_response, | |
| "workflow": workflow | |
| } | |
| if 'run_config' in locals() and hasattr(run_config, 'run_id'): | |
| response_data["run_id"] = run_config.run_id | |
| response = jsonify(response_data) | |
| for run in runs: | ||
| # Prepare loras and controlnets as JSON strings | ||
| loras_json = json.dumps(run.loras) if run.loras else "[]" | ||
| controlnets_json = json.dumps(run.controlnets) if run.controlnets else "[]" | ||
|
|
||
| # Create workflow hash for identification | ||
| workflow_hash = str(hash(json.dumps(run.workflow, sort_keys=True))) | ||
|
|
||
| # Join image paths | ||
| image_paths = ";".join(run.generated_images) if run.generated_images else "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): No deduplication of image filenames when copying images.
This may cause files to be overwritten or duplicated. Please deduplicate the image list before copying.
| print(f"📊 Creating report bundle with {len(runs)} runs") | ||
|
|
||
| # Create temporary directory for bundle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): Potential race condition with temp directory naming.
Using only seconds in the directory name may lead to collisions. Recommend adding uuid4 or microseconds for uniqueness.
| print(f"📊 Creating report bundle with {len(runs)} runs") | |
| # Create temporary directory for bundle | |
| print(f"📊 Creating report bundle with {len(runs)} runs") | |
| # Create temporary directory for bundle | |
| import uuid | |
| bundle_dir = f"temp_report_bundle_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4().hex}" | |
| os.makedirs(bundle_dir, exist_ok=True) |
| run_config = RunConfig( | ||
| run_id=data.get('run_id', str(uuid.uuid4())), | ||
| timestamp=data.get('timestamp', datetime.now().isoformat()), | ||
| model=data.get('model', 'unknown'), | ||
| vae=data.get('vae'), | ||
| loras=data.get('loras', []), | ||
| controlnets=data.get('controlnets', []), | ||
| prompt=data.get('prompt', ''), | ||
| negative_prompt=data.get('negative_prompt', ''), | ||
| seed=data.get('seed', 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): No validation of required fields in POST /api/runs.
Missing or incorrectly typed fields may cause malformed RunConfig objects or runtime errors. Please add validation for required fields and types before instantiating RunConfig.
| }, [fetchRuns]); | ||
|
|
||
| const handleGenerateReport = async () => { | ||
| const runIds = selectedRuns.size > 0 ? Array.from(selectedRuns) : undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Passing undefined for runIds may not match backend expectations.
Always pass an array (empty or with values) for runIds to ensure consistent backend behavior.
| """Create a RunConfig from generation data""" | ||
|
|
||
| # Extract configuration from generation data | ||
| config = RunConfig( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable)
| run = registry.get_run(run_id) | ||
| if run: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use named expression to simplify assignment and conditional (use-named-expression)
| run = registry.get_run(run_id) | |
| if run: | |
| if run := registry.get_run(run_id): |
| success = registry.delete_run(run_id) | ||
| if success: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use named expression to simplify assignment and conditional (use-named-expression)
| success = registry.delete_run(run_id) | |
| if success: | |
| if success := registry.delete_run(run_id): |
| def test_csv_schema_validation(self): | ||
| """Test CSV schema validation with valid and invalid schemas""" | ||
| # Test valid CSV | ||
| valid_csv_content = """run_id,timestamp,model,vae,prompt,negative_prompt,seed,sampler,steps,cfg_scale,width,height,batch_size,batch_count,generation_type,image_paths,loras,controlnets,workflow_hash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Extract duplicate code into method (extract-duplicate-method)
| # Extract and verify contents | ||
| with zipfile.ZipFile(zip_path, 'r') as zipf: | ||
| # Check that results.csv exists | ||
| csv_files = [f for f in zipf.namelist() if f.endswith('results.csv')] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Extract code out into method (extract-method)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Nitpick comments (18)
ComfyUI/user/default/comfy.settings.json (1)
4-5: Consider storing the release timestamp as a string to avoid precision loss in JS runtimes.The integer
1754374644423is within the IEEE-754 safe-integer range, yet JSON consumers that coerce it toDatevianew Date(number)may still lose micro-precision in downstream serialisations. A simple, future-proof tweak:- "Comfy.Release.Timestamp": 1754374644423 + "Comfy.Release.Timestamp": "1754374644423"This keeps the semantic meaning while eliminating any numeric-precision pitfalls.
dream_layer_backend/shared_utils.py (1)
84-84: Replace bareprint()with structured loggingA raw
print("wait_for_image")adds noise to stdout in production and complicates log aggregation/rotation.
All other diagnostics in this file already use descriptive messages; prefer the standardloggingmodule (or your existing logger) so the call can be toggled with log-level configuration.- print("wait_for_image") + logger.debug("wait_for_image invoked") # logger configured at module levelIf a logger is not yet configured in this module, create one near the imports:
import logging logger = logging.getLogger(__name__)dream_layer_frontend/src/pages/Index.tsx (1)
11-13: Consider tightening the tab id type for compile-time safetyNow that two new tabs are added, the
activeTabstate still has a plainstringtype, so misspellings of tab ids won’t be caught by TypeScript.-const [activeTab, setActiveTab] = useState("txt2img"); +type TabId = + | "txt2img" + | "img2img" + | "extras" + | "models" + | "pnginfo" + | "configurations" + | "runregistry" + | "reportbundle"; + +const [activeTab, setActiveTab] = useState<TabId>("txt2img");This makes
handleTabChangeand theswitchexhaustive, preventing runtime fall-through mistakes when more tabs are introduced.Also applies to: 47-50
dream_layer_frontend/src/stores/useRunRegistryStore.ts (2)
6-6: Consider making the API base URL configurable.The hardcoded localhost URL may cause issues in different deployment environments. Consider using environment variables or a configuration file.
-const API_BASE_URL = 'http://localhost:5005/api'; +const API_BASE_URL = process.env.REACT_APP_RUN_REGISTRY_API_URL || 'http://localhost:5005/api';
54-74: Consider adding loading state for consistency.The deleteRun function works correctly but doesn't set loading state like fetchRuns and fetchRun. While this might be intentional for immediate UI feedback, consider consistency across all async operations.
deleteRun: async (runId: string) => { + set({ loading: true, error: null }); try { const response = await fetch(`${API_BASE_URL}/runs/${runId}`, { method: 'DELETE', }); const data = await response.json(); if (data.status === 'success') { // Remove the run from the local state const { runs } = get(); const updatedRuns = runs.filter(run => run.run_id !== runId); - set({ runs: updatedRuns }); + set({ runs: updatedRuns, loading: false }); } else { - set({ error: data.message || 'Failed to delete run' }); + set({ error: data.message || 'Failed to delete run', loading: false }); } } catch (error) { set({ - error: error instanceof Error ? error.message : 'Failed to delete run' + error: error instanceof Error ? error.message : 'Failed to delete run', + loading: false }); } },dream_layer_backend/txt2img_server.py (2)
10-10: Remove unused PIL imports.Static analysis indicates that
PIL.ImageandPIL.ImageDraware imported but not used in this file.-from PIL import Image, ImageDraw
82-110: LGTM! Consider making registry URL configurable.The run registration logic is well-implemented with proper error handling and logging. The registration failure doesn't break the main txt2img workflow, which is good.
Consider making the registry URL configurable:
+import os + +REGISTRY_URL = os.getenv('RUN_REGISTRY_URL', 'http://localhost:5005/api/runs') + # Send to run registry registry_response = requests.post( - "http://localhost:5005/api/runs", + REGISTRY_URL, json=asdict(run_config), timeout=5 )dream_layer_backend/img2img_server.py (2)
13-14: Remove unused imports.Static analysis indicates that
COMFY_API_URLandget_controlnet_modelsare imported but not used in this file.-from shared_utils import send_to_comfyui +from shared_utils import send_to_comfyui -from shared_utils import COMFY_API_URL -from dream_layer_backend_utils.fetch_advanced_models import get_controlnet_models
184-211: LGTM! Consider consistent URL configuration.The run registration logic is well-implemented and consistent with the txt2img_server implementation. Consider making the registry URL configurable for consistency across both servers.
For consistency with potential changes in txt2img_server.py:
+import os + +REGISTRY_URL = os.getenv('RUN_REGISTRY_URL', 'http://localhost:5005/api/runs') + # Send to run registry registry_response = requests.post( - "http://localhost:5005/api/runs", + REGISTRY_URL, json=asdict(run_config), timeout=5 )dream_layer_backend/tests/test_run_registry.py (2)
1-6: Remove unused imports.The
pytestandjsonimports are not used in this test file.Apply this diff to clean up unused imports:
-import pytest -import json import tempfile import os from datetime import datetime from run_registry import RunConfig, RunRegistry, create_run_config_from_generation_data
11-22: Consider using pytest fixtures for better test organization.While the current setup/teardown approach works correctly, pytest fixtures would provide better test organization and dependency injection.
Consider refactoring to use pytest fixtures:
+@pytest.fixture +def temp_registry(): + temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') + temp_file.close() + registry = RunRegistry(temp_file.name) + yield registry + if os.path.exists(temp_file.name): + os.unlink(temp_file.name) + -class TestRunRegistry: - """Test cases for the Run Registry functionality""" - - def setup_method(self): - """Set up test fixtures""" - # Create a temporary file for testing - self.temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') - self.temp_file.close() - self.registry = RunRegistry(self.temp_file.name) - - def teardown_method(self): - """Clean up test fixtures""" - if os.path.exists(self.temp_file.name): - os.unlink(self.temp_file.name) +class TestRunRegistry: + """Test cases for the Run Registry functionality"""dream_layer_frontend/src/features/RunRegistry/RunRegistryPage.tsx (1)
31-35: Consider using a custom confirmation dialog for better UX consistency.While the native
confirm()works functionally, a custom confirmation modal would provide better visual consistency with the rest of the application.Consider replacing with a custom confirmation dialog:
+const [showDeleteDialog, setShowDeleteDialog] = useState<string | null>(null); -const handleDeleteRun = async (runId: string) => { - if (confirm('Are you sure you want to delete this run?')) { - await deleteRun(runId); - } -}; +const handleDeleteRun = async (runId: string) => { + setShowDeleteDialog(runId); +}; +const confirmDelete = async () => { + if (showDeleteDialog) { + await deleteRun(showDeleteDialog); + setShowDeleteDialog(null); + } +};dream_layer_backend/tests/test_report_bundle.py (1)
1-31: Remove unused import and excellent test setup.Similar to the run registry tests,
pytestis imported but not used.Apply this diff to clean up the unused import:
-import pytest import json import csv import tempfileThe test setup with temporary directories and mock image files is well-designed for comprehensive testing.
dream_layer_backend/run_registry.py (2)
3-3: Remove unused import.The
timemodule is imported but never used.import json import os -import time import uuid
113-113: Address the TODO comment for version management.The version is hardcoded. Consider implementing proper version tracking.
Would you like me to help implement a version management system or create an issue to track this task?
dream_layer_backend/report_bundle.py (3)
7-7: Remove unused imports.Remove unused imports to keep the code clean.
-from typing import List, Dict, Any, Optional +from typing import List, Optionalfrom flask_cors import CORS -import requests from run_registry import RunRegistry, RunConfigAlso applies to: 11-11
107-107: Remove unnecessary f-string prefix.The string doesn't contain any placeholders.
- print(f"✅ CSV schema validation passed") + print("✅ CSV schema validation passed")
257-257: Rename unused loop variable.Follow Python convention for unused variables.
- for root, dirs, files in os.walk(bundle_dir): + for root, _dirs, files in os.walk(bundle_dir):
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
ComfyUI/user/default/comfy.settings.json(1 hunks)dream_layer_backend/img2img_server.py(2 hunks)dream_layer_backend/report_bundle.py(1 hunks)dream_layer_backend/run_registry.py(1 hunks)dream_layer_backend/shared_utils.py(1 hunks)dream_layer_backend/tests/test_report_bundle.py(1 hunks)dream_layer_backend/tests/test_run_registry.py(1 hunks)dream_layer_backend/txt2img_server.py(2 hunks)dream_layer_frontend/src/components/Navigation/TabsNav.tsx(2 hunks)dream_layer_frontend/src/features/ReportBundle/ReportBundlePage.tsx(1 hunks)dream_layer_frontend/src/features/ReportBundle/index.ts(1 hunks)dream_layer_frontend/src/features/RunRegistry/RunRegistryPage.tsx(1 hunks)dream_layer_frontend/src/features/RunRegistry/index.ts(1 hunks)dream_layer_frontend/src/pages/Index.tsx(2 hunks)dream_layer_frontend/src/stores/useReportBundleStore.ts(1 hunks)dream_layer_frontend/src/stores/useRunRegistryStore.ts(1 hunks)dream_layer_frontend/src/types/reportBundle.ts(1 hunks)dream_layer_frontend/src/types/runRegistry.ts(1 hunks)start_dream_layer.bat(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 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.
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.
📚 Learning: the dreamlayer project follows an iterative approach to docker development, where basic docker setup...
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.bat
🧬 Code Graph Analysis (6)
dream_layer_frontend/src/types/runRegistry.ts (1)
dream_layer_backend/run_registry.py (1)
RunConfig(12-33)
dream_layer_backend/img2img_server.py (3)
dream_layer_backend/shared_utils.py (1)
send_to_comfyui(161-223)dream_layer_backend/img2img_workflow.py (1)
transform_to_img2img_workflow(26-220)dream_layer_backend/run_registry.py (1)
create_run_config_from_generation_data(87-118)
dream_layer_frontend/src/stores/useRunRegistryStore.ts (2)
dream_layer_frontend/src/types/runRegistry.ts (3)
RunRegistryState(40-45)RunRegistryActions(47-53)RunConfig(1-31)dream_layer_backend/run_registry.py (1)
RunConfig(12-33)
dream_layer_frontend/src/stores/useReportBundleStore.ts (1)
dream_layer_frontend/src/types/reportBundle.ts (2)
ReportBundleState(21-25)ReportBundleActions(27-32)
dream_layer_backend/report_bundle.py (2)
dream_layer_backend/run_registry.py (5)
RunRegistry(35-82)RunConfig(12-33)get_run(68-70)get_run(146-164)get_all_runs(72-74)dream_layer_frontend/src/types/runRegistry.ts (1)
RunConfig(1-31)
dream_layer_backend/run_registry.py (1)
dream_layer_frontend/src/types/runRegistry.ts (1)
RunConfig(1-31)
🪛 Ruff (0.12.2)
dream_layer_backend/txt2img_server.py
10-10: PIL.Image imported but unused
Remove unused import
(F401)
10-10: PIL.ImageDraw imported but unused
Remove unused import
(F401)
dream_layer_backend/img2img_server.py
13-13: shared_utils.COMFY_API_URL imported but unused
Remove unused import: shared_utils.COMFY_API_URL
(F401)
14-14: dream_layer_backend_utils.fetch_advanced_models.get_controlnet_models imported but unused
Remove unused import: dream_layer_backend_utils.fetch_advanced_models.get_controlnet_models
(F401)
dream_layer_backend/tests/test_report_bundle.py
1-1: pytest imported but unused
Remove unused import: pytest
(F401)
dream_layer_backend/tests/test_run_registry.py
1-1: pytest imported but unused
Remove unused import: pytest
(F401)
2-2: json imported but unused
Remove unused import: json
(F401)
14-14: Use a context manager for opening files
(SIM115)
dream_layer_backend/report_bundle.py
7-7: typing.Dict imported but unused
Remove unused import
(F401)
7-7: typing.Any imported but unused
Remove unused import
(F401)
11-11: requests imported but unused
Remove unused import: requests
(F401)
107-107: f-string without any placeholders
Remove extraneous f prefix
(F541)
257-257: Loop control variable dirs not used within loop body
Rename unused dirs to _dirs
(B007)
dream_layer_backend/run_registry.py
3-3: time imported but unused
Remove unused import: time
(F401)
🪛 ast-grep (0.38.6)
dream_layer_backend/report_bundle.py
[warning] 366-366: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables.
Context: app.run(host='0.0.0.0', port=5006, debug=True)
Note: [CWE-489] Active Debug Code. [REFERENCES]
- https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/
(debug-enabled-python)
dream_layer_backend/run_registry.py
[warning] 235-235: Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables.
Context: app.run(host='0.0.0.0', port=5005, debug=True)
Note: [CWE-489] Active Debug Code. [REFERENCES]
- https://labs.detectify.com/2015/10/02/how-patreon-got-hacked-publicly-exposed-werkzeug-debugger/
(debug-enabled-python)
🔇 Additional comments (41)
ComfyUI/user/default/comfy.settings.json (1)
3-3: ConfirmImageFitvalue is recognised by ComfyUI.
"cover"seems plausible, but ComfyUI historically accepted"contain"/"fill"only.
Please double-check the current ComfyUI release notes to ensure"cover"is parsed correctly; otherwise the queue preview could silently fall back to a default.dream_layer_frontend/src/features/RunRegistry/index.ts (1)
1-1: LGTM – concise barrel exportThe re-export is idiomatic and keeps import paths short throughout the app.
dream_layer_frontend/src/features/ReportBundle/index.ts (1)
1-1: LGTM – matches the Run-Registry patternConsistent barrel export; no issues spotted.
dream_layer_frontend/src/components/Navigation/TabsNav.tsx (1)
19-20: LGTM – new tabs wired correctly
ids match those used inIndex.tsx, and icons import cleanly. No behavioural issues detected.dream_layer_frontend/src/stores/useRunRegistryStore.ts (3)
16-33: LGTM!The fetchRuns function implementation is well-structured with proper error handling, loading state management, and type-safe response processing.
35-52: LGTM!The fetchRun function correctly implements single run fetching with proper parameter handling and consistent error management patterns.
76-82: LGTM!The helper functions clearError and setSelectedRun are simple and correctly implemented.
dream_layer_backend/txt2img_server.py (2)
5-5: LGTM!The new imports for run registry functionality are appropriate and necessary.
Also applies to: 12-13
115-116: LGTM!The response modifications appropriately include the generated images and run ID, with safe handling for cases where run registration might fail.
start_dream_layer.bat (4)
126-126: LGTM!The step counter updates correctly reflect the addition of two new backend services, maintaining consistency across all service startup messages.
Also applies to: 134-134, 138-138, 142-142, 158-158
145-152: LGTM!The new service startup commands for run registry and report bundle servers follow the established pattern with proper logging and console management.
175-176: LGTM!The new service URLs are properly formatted and consistently presented with the existing service information.
199-210: LGTM!The connectivity tests for the new services follow the established pattern and use appropriate endpoints for health checking.
dream_layer_backend/img2img_server.py (2)
7-7: LGTM!The new imports for run registry functionality are appropriate and necessary.
Also applies to: 15-16
216-217: LGTM!The response modifications appropriately include the workflow and run ID, with safe handling for cases where run registration might fail.
dream_layer_frontend/src/types/runRegistry.ts (1)
1-53: LGTM! Excellent type definitions.The TypeScript interfaces are well-designed and provide good type safety:
RunConfiginterface matches the backend dataclass perfectly- LoRA and ControlNet arrays properly allow additional properties with index signatures
- Union type for
generation_typeprovides better type safety than the backend string type- API response and state management interfaces are appropriate for frontend architecture
dream_layer_backend/tests/test_run_registry.py (7)
23-58: LGTM! Comprehensive validation of required fields.This test effectively validates that all required fields exist in the RunConfig dataclass. The use of
hasattris appropriate for this validation approach.
60-105: Excellent defensive programming test.This test ensures the system handles edge cases gracefully with empty or None values. This type of validation is crucial for production reliability.
107-162: LGTM! Thorough testing of data transformation.This test comprehensively validates the
create_run_config_from_generation_datafunction with realistic test data and proper value mapping verification.
164-187: LGTM! Good edge case testing with empty data.This test complements the previous test by validating robust handling of empty/missing data with appropriate default values.
189-227: LGTM! Excellent persistence testing.This test validates that the registry properly persists data across instances, which is crucial for the run registry functionality. The test pattern of creating a new registry instance to verify loading is particularly effective.
228-284: LGTM! Good validation of sorting and listing functionality.This test ensures runs are returned in the correct order (newest first) and validates the complete listing functionality. The timestamp-based sorting is important for the UI experience.
286-325: LGTM! Comprehensive deletion testing with edge cases.This test covers both successful deletion and the important edge case of attempting to delete non-existent runs. The return value validation ensures proper API contract adherence.
dream_layer_frontend/src/features/ReportBundle/ReportBundlePage.tsx (6)
1-28: LGTM! Well-structured component with clean architecture.The component follows modern React patterns with proper imports, custom hooks, and good separation of concerns using Zustand stores.
24-55: LGTM! Effective state management with appropriate data structures.The use of
Setfor selected runs is efficient for lookups and the state update patterns follow React best practices. The event handlers are clean and properly structured.
57-67: LGTM! Well-implemented utility functions with proper error handling.The
formatTimestampfunction includes defensive error handling, andgetGenerationTypeColorprovides consistent UI styling. Both functions are pure and reusable.
69-153: LGTM! Comprehensive UI with excellent user experience.The UI provides clear visual hierarchy, proper state handling (loading, error, success), and intuitive user interactions. The information presentation is well-organized and accessible.
156-204: LGTM! Comprehensive run listing with excellent information design.The run listing provides comprehensive information in a well-organized format, handles empty states gracefully, and includes intuitive selection mechanisms. The scrollable area ensures good UX even with many runs.
208-252: LGTM! Excellent documentation and user guidance.The report bundle contents section provides clear, comprehensive information about what users will receive. The use of icons and detailed schema information enhances user understanding.
dream_layer_frontend/src/features/RunRegistry/RunRegistryPage.tsx (4)
1-51: LGTM! Well-structured component with consistent patterns.The component follows good React patterns with clean imports, proper TypeScript typing, and utility functions that maintain consistency with other components in the codebase.
53-88: LGTM! Excellent loading and error state handling.The skeleton loading pattern provides good UX feedback, and the error handling includes proper retry functionality. The UI patterns are consistent with the overall application design.
90-190: LGTM! Comprehensive run listing with excellent user experience.The UI provides clear information hierarchy, handles empty states well, and includes appropriate actions (view/delete) with proper visual feedback. The use of badges and icons enhances readability.
192-316: LGTM! Comprehensive modal with excellent information organization.The modal effectively presents all run configuration details in a well-structured format. The conditional rendering for optional fields (LoRAs, ControlNets) and proper JSON formatting for workflow data enhance usability.
dream_layer_frontend/src/types/reportBundle.ts (1)
1-32: LGTM! Well-structured TypeScript definitions with proper separation of concerns.The interfaces provide comprehensive typing for the report bundle feature with appropriate optionality, clear separation of request/response types, and good use of union types for status fields.
dream_layer_backend/tests/test_report_bundle.py (7)
33-106: LGTM! Comprehensive CSV schema validation testing.This test ensures all required CSV columns are present and properly validates the schema. The use of comprehensive test data with both txt2img and img2img types provides good coverage.
108-142: LGTM! Excellent edge case testing for empty values.This test ensures the system handles empty/minimal data gracefully without crashes, which is crucial for production reliability.
144-169: LGTM! Good validation testing with both positive and negative cases.The test covers both valid and invalid CSV schemas, ensuring proper validation logic. Testing both success and failure cases is essential for robust validation.
171-235: LGTM! Excellent end-to-end integration testing.This test validates the complete report bundle creation process, ensuring that all referenced images are actually included in the zip file. The comprehensive verification of bundle contents is thorough.
237-297: LGTM! Important consistency validation testing.This test ensures deterministic behavior by creating multiple bundles from the same data and verifying identical structure. This is crucial for reliable report generation.
299-351: LGTM! Thorough config.json structure validation.This test ensures the config.json file has all required metadata and run information, validating both the structure and content completeness.
353-400: LGTM! Comprehensive README content validation.This test ensures the README file contains all necessary sections and references to report files, providing good documentation validation for the report bundle.
| controlnets_json = json.dumps(run.controlnets) if run.controlnets else "[]" | ||
|
|
||
| # Create workflow hash for identification | ||
| workflow_hash = str(hash(json.dumps(run.workflow, sort_keys=True))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a deterministic hash function for workflow identification.
Python's built-in hash() function is not deterministic across runs, which could cause inconsistent workflow hashes.
+import hashlib
+
# Create workflow hash for identification
- workflow_hash = str(hash(json.dumps(run.workflow, sort_keys=True)))
+ workflow_json = json.dumps(run.workflow, sort_keys=True)
+ workflow_hash = hashlib.sha256(workflow_json.encode()).hexdigest()[:16]📝 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.
| workflow_hash = str(hash(json.dumps(run.workflow, sort_keys=True))) | |
| import hashlib | |
| # Create workflow hash for identification | |
| workflow_json = json.dumps(run.workflow, sort_keys=True) | |
| workflow_hash = hashlib.sha256(workflow_json.encode()).hexdigest()[:16] |
🤖 Prompt for AI Agents
In dream_layer_backend/report_bundle.py at line 58, replace the use of Python's
built-in hash() function with a deterministic hash function such as
hashlib.sha256. Convert the JSON string of run.workflow to bytes, compute the
hash digest using hashlib, and then convert it to a hexadecimal string to ensure
consistent and deterministic workflow_hash values across runs.
| for temp_file in [csv_path, config_path, readme_path]: | ||
| if os.path.exists(temp_file): | ||
| os.remove(temp_file) | ||
|
|
||
| # Cleanup temp directory | ||
| shutil.rmtree(bundle_dir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for cleanup operations.
File removal could fail if files don't exist or are locked by another process.
# Cleanup temp files
for temp_file in [csv_path, config_path, readme_path]:
- if os.path.exists(temp_file):
- os.remove(temp_file)
+ try:
+ if os.path.exists(temp_file):
+ os.remove(temp_file)
+ except Exception as e:
+ logger.warning(f"Failed to remove temp file {temp_file}: {e}")
# Cleanup temp directory
- shutil.rmtree(bundle_dir)
+ try:
+ shutil.rmtree(bundle_dir)
+ except Exception as e:
+ logger.warning(f"Failed to remove temp directory {bundle_dir}: {e}")Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In dream_layer_backend/report_bundle.py around lines 264 to 269, the cleanup
code removes files and directories without handling potential errors like
missing files or locked resources. Wrap the os.remove calls and shutil.rmtree
call in try-except blocks to catch and log exceptions, ensuring the cleanup
process does not crash the program if a file is missing or locked.
| temp_csv = "temp_validation.csv" | ||
| with open(temp_csv, 'w', encoding='utf-8') as f: | ||
| f.write(csv_content) | ||
|
|
||
| is_valid = generator.validate_csv_schema(temp_csv) | ||
|
|
||
| # Cleanup | ||
| if os.path.exists(temp_csv): | ||
| os.remove(temp_csv) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use context manager or finally block for temp file cleanup.
Ensure temp files are cleaned up even if validation fails.
# Write CSV content to temp file for validation
temp_csv = "temp_validation.csv"
- with open(temp_csv, 'w', encoding='utf-8') as f:
- f.write(csv_content)
-
- is_valid = generator.validate_csv_schema(temp_csv)
-
- # Cleanup
- if os.path.exists(temp_csv):
- os.remove(temp_csv)
+ try:
+ with open(temp_csv, 'w', encoding='utf-8') as f:
+ f.write(csv_content)
+
+ is_valid = generator.validate_csv_schema(temp_csv)
+ finally:
+ # Cleanup
+ if os.path.exists(temp_csv):
+ try:
+ os.remove(temp_csv)
+ except Exception:
+ pass📝 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.
| temp_csv = "temp_validation.csv" | |
| with open(temp_csv, 'w', encoding='utf-8') as f: | |
| f.write(csv_content) | |
| is_valid = generator.validate_csv_schema(temp_csv) | |
| # Cleanup | |
| if os.path.exists(temp_csv): | |
| os.remove(temp_csv) | |
| # Write CSV content to temp file for validation | |
| temp_csv = "temp_validation.csv" | |
| try: | |
| with open(temp_csv, 'w', encoding='utf-8') as f: | |
| f.write(csv_content) | |
| is_valid = generator.validate_csv_schema(temp_csv) | |
| finally: | |
| # Cleanup | |
| if os.path.exists(temp_csv): | |
| try: | |
| os.remove(temp_csv) | |
| except Exception: | |
| pass |
🤖 Prompt for AI Agents
In dream_layer_backend/report_bundle.py around lines 345 to 353, the temporary
CSV file cleanup is done after validation but not guaranteed if an exception
occurs. Refactor the code to use a try-finally block or a context manager to
ensure the temporary file is always deleted, even if validate_csv_schema raises
an error. This will guarantee proper cleanup of the temp file regardless of
validation success or failure.
| }), 500 | ||
|
|
||
| if __name__ == '__main__': | ||
| app.run(host='0.0.0.0', port=5006, debug=True) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disable debug mode for production deployment.
Running Flask with debug=True is a security vulnerability that exposes sensitive information.
if __name__ == '__main__':
- app.run(host='0.0.0.0', port=5006, debug=True)
+ app.run(host='0.0.0.0', port=5006, debug=os.environ.get('FLASK_DEBUG', 'False').lower() == 'true')Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In dream_layer_backend/report_bundle.py at line 367, the Flask app is being run
with debug=True, which is insecure for production. Change the debug parameter to
False or remove it entirely to disable debug mode for production deployment.
| for run_id, run_data in data.items(): | ||
| self.runs[run_id] = RunConfig(**run_data) | ||
| except Exception as e: | ||
| print(f"Error loading run registry: {e}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use proper logging instead of print statements.
Replace print statements with proper logging for better production monitoring and debugging.
Add logging configuration at the top of the file:
import logging
logger = logging.getLogger(__name__)Then replace print statements:
- print(f"Error loading run registry: {e}")
+ logger.error(f"Error loading run registry: {e}")- print(f"Error saving run registry: {e}")
+ logger.error(f"Error saving run registry: {e}")Also applies to: 61-61
🤖 Prompt for AI Agents
In dream_layer_backend/run_registry.py at lines 52 and 61, replace the print
statements used for error messages with proper logging calls. First, add logging
configuration at the top of the file by importing logging and creating a logger
instance with logger = logging.getLogger(__name__). Then, replace print(f"Error
loading run registry: {e}") and similar print statements with
logger.error(f"Error loading run registry: {e}") to ensure errors are logged
appropriately for production monitoring and debugging.
| model=generation_data.get('model_name', 'unknown'), | ||
| vae=generation_data.get('vae_name'), | ||
| loras=generation_data.get('lora', []), | ||
| controlnets=generation_data.get('controlnet', {}).get('units', []), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add defensive check for controlnet data structure.
Using .get('units', []) on a potentially None value could raise an AttributeError.
- controlnets=generation_data.get('controlnet', {}).get('units', []),
+ controlnets=(generation_data.get('controlnet') or {}).get('units', []),📝 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.
| controlnets=generation_data.get('controlnet', {}).get('units', []), | |
| controlnets=(generation_data.get('controlnet') or {}).get('units', []), |
🤖 Prompt for AI Agents
In dream_layer_backend/run_registry.py at line 101, the code assumes
'controlnet' is a dictionary and directly calls .get('units', []) on it, which
can raise an AttributeError if 'controlnet' is None. Add a defensive check to
ensure 'controlnet' is a dictionary before accessing 'units'. For example,
retrieve 'controlnet' first, verify it is a dict, then safely get 'units' or
default to an empty list.
| }), 500 | ||
|
|
||
| if __name__ == '__main__': | ||
| app.run(host='0.0.0.0', port=5005, debug=True) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disable debug mode for production deployment.
Running Flask with debug=True exposes sensitive information and allows code execution. This is a security vulnerability.
if __name__ == '__main__':
- app.run(host='0.0.0.0', port=5005, debug=True)
+ app.run(host='0.0.0.0', port=5005, debug=os.environ.get('FLASK_DEBUG', 'False').lower() == 'true')Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In dream_layer_backend/run_registry.py at line 236, the Flask app is started
with debug=True, which is insecure for production. Change the debug parameter to
False or remove it entirely to disable debug mode when deploying to production,
preventing exposure of sensitive information and potential code execution
vulnerabilities.
|
|
||
| interface ReportBundleStore extends ReportBundleState, ReportBundleActions {} | ||
|
|
||
| const API_BASE_URL = 'http://localhost:5006/api'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Move API base URL to environment configuration.
Hardcoding the API URL makes it difficult to deploy to different environments. Consider using environment variables or a configuration file.
-const API_BASE_URL = 'http://localhost:5006/api';
+const API_BASE_URL = import.meta.env.VITE_REPORT_BUNDLE_API_URL || 'http://localhost:5006/api';📝 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.
| const API_BASE_URL = 'http://localhost:5006/api'; | |
| -const API_BASE_URL = 'http://localhost:5006/api'; | |
| +const API_BASE_URL = import.meta.env.VITE_REPORT_BUNDLE_API_URL || 'http://localhost:5006/api'; |
🤖 Prompt for AI Agents
In dream_layer_frontend/src/stores/useReportBundleStore.ts at line 6, the API
base URL is hardcoded, which reduces flexibility for different deployment
environments. Replace the hardcoded URL with a reference to an environment
variable, such as process.env.VITE_API_BASE_URL or a similar config, and ensure
the environment variable is properly set in the deployment configurations.
| const data = await response.json(); | ||
|
|
||
| if (data.status === 'success') { | ||
| set({ | ||
| generating: false, | ||
| downloadUrl: `${API_BASE_URL}/report-bundle/download` | ||
| }); | ||
| } else { | ||
| set({ | ||
| error: data.message || 'Failed to generate report bundle', | ||
| generating: false | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check HTTP response status before parsing JSON.
The code assumes all responses can be parsed as JSON, which may fail for non-200 status codes or network errors.
const data = await response.json();
- if (data.status === 'success') {
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({ message: 'Failed to generate report bundle' }));
+ set({
+ error: errorData.message || `HTTP ${response.status}: ${response.statusText}`,
+ generating: false
+ });
+ } else if (data.status === 'success') {
set({
generating: false,
downloadUrl: `${API_BASE_URL}/report-bundle/download`
});
} else {
set({
error: data.message || 'Failed to generate report bundle',
generating: false
});
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In dream_layer_frontend/src/stores/useReportBundleStore.ts around lines 28 to
40, the code parses the response as JSON without checking if the HTTP response
status is successful. To fix this, first check if response.ok is true before
calling response.json(). If not ok, handle the error appropriately by setting
the error state with a relevant message and avoid parsing JSON from unsuccessful
responses.
| validateSchema: async (csvContent: string) => { | ||
| try { | ||
| const response = await fetch(`${API_BASE_URL}/report-bundle/validate`, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ | ||
| csv_content: csvContent | ||
| }), | ||
| }); | ||
|
|
||
| const data = await response.json(); | ||
| return data.status === 'success' && data.valid; | ||
| } catch (error) { | ||
| console.error('Schema validation failed:', error); | ||
| return false; | ||
| } | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve error handling in validateSchema.
The function silently returns false for all errors without updating the error state, making it difficult to debug validation failures.
validateSchema: async (csvContent: string) => {
try {
const response = await fetch(`${API_BASE_URL}/report-bundle/validate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
csv_content: csvContent
}),
});
+ if (!response.ok) {
+ set({ error: `Validation failed: HTTP ${response.status}` });
+ return false;
+ }
+
const data = await response.json();
return data.status === 'success' && data.valid;
} catch (error) {
console.error('Schema validation failed:', error);
+ set({ error: error instanceof Error ? error.message : 'Schema validation failed' });
return false;
}
},📝 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.
| validateSchema: async (csvContent: string) => { | |
| try { | |
| const response = await fetch(`${API_BASE_URL}/report-bundle/validate`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| csv_content: csvContent | |
| }), | |
| }); | |
| const data = await response.json(); | |
| return data.status === 'success' && data.valid; | |
| } catch (error) { | |
| console.error('Schema validation failed:', error); | |
| return false; | |
| } | |
| }, | |
| validateSchema: async (csvContent: string) => { | |
| try { | |
| const response = await fetch(`${API_BASE_URL}/report-bundle/validate`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| csv_content: csvContent | |
| }), | |
| }); | |
| if (!response.ok) { | |
| set({ error: `Validation failed: HTTP ${response.status}` }); | |
| return false; | |
| } | |
| const data = await response.json(); | |
| return data.status === 'success' && data.valid; | |
| } catch (error) { | |
| console.error('Schema validation failed:', error); | |
| set({ error: error instanceof Error ? error.message : 'Schema validation failed' }); | |
| return false; | |
| } | |
| }, |
🤖 Prompt for AI Agents
In dream_layer_frontend/src/stores/useReportBundleStore.ts around lines 78 to
96, the validateSchema function catches errors and returns false but does not
update any error state, which hinders debugging. Modify the catch block to
update a relevant error state or store with the error details before returning
false, so that the UI or logs can reflect the validation failure cause.
|
Hey @jayashreeks , |
|
Hi @darcy3000,
|
|
Hi @jayashreeks , |
|
Thank you so much, @darcy3000 |

Description
Added Run Registry tab to register the runs for both txt2img and img2img
Added Report Bundle tab to download the contents in a zip file
Evidence Required ✅
Checklist
Summary by Sourcery
Add end-to-end support for run management and reporting by introducing a Run Registry for storing frozen run configurations and a Report Bundle service for packaging run data into downloadable zip archives, complete with new UI tabs, backend APIs, and tests
New Features:
Enhancements:
Tests:
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores