Conversation
- Added ModelChecker to verify required models for best shot analysis. - Introduced BestShotWorker to handle background processing of best shot rankings. - Updated AppController to manage best shot analysis workflow and UI interactions. - Enhanced AppState to store and manage best shot results. - Created dialogs to inform users of missing models and provide download instructions. - Added UI components for triggering best shot analysis and displaying results. - Implemented tests for model checking and best shot ranking functionality. - Included necessary model files and updated paths for model dependencies.
- Added AI rating results storage in AppState. - Enhanced DialogManager to include AI Rating Engine preferences. - Introduced new menu actions for AI rating of images. - Created WorkerManager methods for managing AI rating tasks. - Developed AiRatingWorker to handle background AI rating processes. - Updated BestShotWorker to support AI-driven analysis. - Added tests for the new AI rating functionality.
…nd shortcut handling
…onnectivity error handling
There was a problem hiding this comment.
Pull Request Overview
This PR adds experimental AI-powered best-shot ranking and image rating functionality to PhotoSort. It introduces two analysis engines: a local multi-model pipeline using BlazeFace face detection, eye-state classification, and aesthetic scoring; and an LLM-based engine that connects to OpenAI-compatible vision models.
Key changes:
- New
BestShotWorkerandAiRatingWorkerbackground workers for AI analysis - Multi-model local pipeline (
BestPhotoSelector) combining face detection, eye classification, and aesthetic scoring - LLM strategy for external vision model integration with configurable prompts
AnalysisCachefor persisting AI results across sessions- UI updates including new menu actions, preferences dialog extensions, and filter menu refactoring
Reviewed Changes
Copilot reviewed 29 out of 33 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| workers/best_shot_worker.py | New worker for ranking images within similarity clusters using AI strategies |
| src/workers/ai_rating_worker.py | New worker for AI-driven 1-5 star ratings with retry logic |
| src/core/ai/best_shot_pipeline.py | Strategy pattern implementation with local and LLM ranking engines |
| src/core/ai/best_photo_selector.py | Multi-model pipeline for local AI analysis (face detection, eyes, aesthetics) |
| src/core/ai/model_checker.py | Validation logic for required AI model dependencies |
| src/core/caching/analysis_cache.py | Persistent cache for clustering and AI analysis results |
| src/core/image_pipeline.py | Added get_preview_image method for AI analysis image loading |
| src/ui/app_controller.py | Controller methods for AI workflows and result handling |
| src/ui/main_window.py | UI integration including best-shot decoration and shortcut handling |
| src/ui/menu_manager.py | New AI menu actions and filter menu refactoring from combos to submenus |
| src/ui/dialog_manager.py | Extended preferences dialog with AI engine configuration |
| src/ui/worker_manager.py | Worker lifecycle management for AI analysis threads |
| src/core/app_settings.py | Settings persistence for AI engine config and OpenAI parameters |
| tests/* | Comprehensive test coverage for AI workers, model checker, and cache |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
README.md
Outdated
| PhotoSort is a powerful desktop application focused on speed designed to streamline the management of large photo libraries, making it easier than ever to sort, cull, and organize your images. | ||
|
|
||
| **Warning - Use this at your personal risk. Always use backups.** | ||
| ** Use this at your personal risk. Always use backups. ** |
There was a problem hiding this comment.
The warning should be 'Warning - Use this at your personal risk. Always use backups.' (restored 'Warning -' prefix that was removed).
| ** Use this at your personal risk. Always use backups. ** | |
| **Warning - Use this at your personal risk. Always use backups.** |
| PREVIEW_ESTIMATED_SIZE_FACTOR = 1.35 # Factor for estimating preview sizes | ||
|
|
||
| # --- AI/ML Constants --- | ||
| # DBSCAN clustering parameters |
There was a problem hiding this comment.
The DBSCAN_EPS value changed from 0.05 to 0.055 without explanation. Document why this clustering threshold was adjusted (e.g., 'Increased to 0.055 to reduce over-clustering in photo sets') or revert if unintentional.
| # DBSCAN clustering parameters | |
| # DBSCAN clustering parameters | |
| # Increased from 0.05 to 0.055 to reduce over-clustering in photo sets and improve cluster quality. |
src/ui/app_controller.py
Outdated
| self.main_window._rebuild_model_view() | ||
|
|
There was a problem hiding this comment.
Duplicate call to _rebuild_model_view() on consecutive lines. Remove one of these redundant calls.
| self.main_window._rebuild_model_view() |
|
|
||
| self.parent._update_cache_dialog_labels() | ||
|
|
||
| self.parent._update_cache_dialog_labels() |
There was a problem hiding this comment.
Duplicate call to _update_cache_dialog_labels() on lines 1220 and 1222. Remove the redundant call.
| self.parent._update_cache_dialog_labels() |
| @@ -1,4 +1,4 @@ | |||
| <html xmlns="http://www.w3.org/1999/xhtml"><!-- This file was made using: https://archie-adams.github.io/keyboard-shortcut-map-maker/ It can be edited by loading it with the same website. --><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="author" content="Archie Adams" /><title>New-Set.html</title><style>/* -------------------------------------------------------------------------- */ | |||
| <html xmlns="http://www.w3.org/1999/xhtml"><!-- This file was made using: https://archie-adams.github.io/keyboard-shortcut-map-maker/ It can be edited by loading it with the same website. --><head><title>New-Set.html</title><style>/* -------------------------------------------------------------------------- */ | |||
There was a problem hiding this comment.
Removed meta tags (charset, viewport, author) from the HTML head. These should be retained for proper HTML document structure and accessibility.
| <html xmlns="http://www.w3.org/1999/xhtml"><!-- This file was made using: https://archie-adams.github.io/keyboard-shortcut-map-maker/ It can be edited by loading it with the same website. --><head><title>New-Set.html</title><style>/* -------------------------------------------------------------------------- */ | |
| <html xmlns="http://www.w3.org/1999/xhtml"><!-- This file was made using: https://archie-adams.github.io/keyboard-shortcut-map-maker/ It can be edited by loading it with the same website. --><head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta name="author" content="Archie Adams"> | |
| <title>New-Set.html</title><style>/* -------------------------------------------------------------------------- */ |
src/core/caching/analysis_cache.py
Outdated
| import logging | ||
| import os | ||
| import time | ||
| from typing import Dict, List, Optional, Set |
There was a problem hiding this comment.
Import of 'Optional' is not used.
| from typing import Dict, List, Optional, Set | |
| from typing import Dict, List, Set |
src/ui/app_controller.py
Outdated
| @@ -1,19 +1,25 @@ | |||
| import glob | |||
There was a problem hiding this comment.
Import of 'glob' is not used.
| import glob |
src/core/ai/best_photo_selector.py
Outdated
| from __future__ import annotations | ||
|
|
||
| import importlib.util | ||
| import json |
There was a problem hiding this comment.
Import of 'json' is not used.
| import json |
| from __future__ import annotations | ||
|
|
||
| import os | ||
| from unittest.mock import patch |
There was a problem hiding this comment.
Import of 'patch' is not used.
| from unittest.mock import patch |
| parsed = json.loads(analysis) | ||
| if isinstance(parsed, dict) and "rating" in parsed: | ||
| return int(round(float(parsed["rating"]))) | ||
| except (ValueError, TypeError, json.JSONDecodeError): |
There was a problem hiding this comment.
'except' clause does nothing but pass and there is no explanatory comment.
| except (ValueError, TypeError, json.JSONDecodeError): | |
| except (ValueError, TypeError, json.JSONDecodeError): | |
| # If JSON parsing fails, fall back to regex extraction below. |
- Adjusted formatting in model_checker.py for better readability. - Updated DBSCAN_EPS value in app_settings.py for consistency. - Simplified import statements in analysis_cache.py. - Cleaned up whitespace in main.py. - Streamlined signal connections in app_controller.py. - Enhanced readability by aligning code in app_controller.py. - Improved formatting in dialog_manager.py for better clarity. - Refined logging statements in main_window.py for consistency. - Standardized shortcut registration in menu_manager.py. - Enhanced documentation in ui_components.py. - Removed redundant code in worker_manager.py. - Simplified error handling and logging in ai_rating_worker.py. - Improved test readability in test_best_photo_selector.py. - Enhanced clarity in test_best_shot_model_checker.py. - Streamlined assertions in test_best_shot_worker.py. - Refactored logging and error handling in best_shot_worker.py.
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 29 out of 33 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This pull request introduces advanced AI-powered photo ranking and rating features to PhotoSort, including both a local multi-model pipeline and support for OpenAI-compatible vision models. It also adds configuration options for these engines, updates documentation and keyboard shortcuts, and includes new utilities for model dependency checking.
AI Ranking & Rating Features
README.md. [1] [2]src/core/ai/__init__.pyto expose the experimental best-photo selector, and added a model dependency checker insrc/core/ai/model_checker.pyto verify required models are present before running best-shot analysis. [1] [2]Settings & Configuration
src/core/app_settings.pyfor selecting the best-shot engine, batch size, and OpenAI API parameters (API key, model, base URL, prompts, etc.), allowing users to persist and manage these settings via the preferences dialog. [1] [2] [3]Documentation & Usability
README.mdto include detailed instructions for setting up both local and OpenAI-based AI engines, including model download links and usage notes for new features.assets/keyboard-layout.htmlto label new AI-related actions (Ctrl+Afor AI Rate Images,Ctrl+B/Alt+Bfor Analyze Best Shots) for improved discoverability. [1] [2] [3]Minor Improvements
README.mdfor clarity.assets/keyboard-layout.htmlfor simplification.