download_sam_model.py crashed with an uncaught PermissionError when
data/models/ is root-owned (common after a prior Docker run) and a
non-root host user tries to recreate the convenience sam_model.pth
symlink — observed in the wild, and it aborted the whole prefetch run
before U2Net/BEN2/BiRefNet-HR were ever attempted. Worse, the same
unguarded symlink call sat inside the post-download try/except, so a
successful download could get deleted just because the symlink step
failed afterward. Wrapped symlink creation in a shared helper that
warns and continues instead of raising — the real model file already
satisfies entrypoint.sh's checks regardless of the symlink.
prefetch-models.sh now treats SAM, U2Net, and the HuggingFace models as
independent steps (one failing no longer aborts the rest) and prints a
summary of which steps failed, so a single run gives full diagnostic
signal instead of stopping at the first error.
Detection priority (probed once, cached):
1. Real-ESRGAN PyTorch + CUDA GPU → fastest, best quality
2. Real-ESRGAN PyTorch + Apple MPS → fast on Apple Silicon
3. Real-ESRGAN NCNN Vulkan binary → fast on any GPU via Vulkan (no CUDA needed)
4. Real-ESRGAN PyTorch CPU → works, slow (warned in UI)
5. Lanczos → always available, instant fallback
Backend:
- services/upscale.py: full capability probe (probe_upscale_capabilities),
implementations for PyTorch (CUDA/MPS/CPU auto-device) and NCNN binary,
upscale_sync() resolves method with fallback chain,
async upscale_image() runs in thread pool
- print_tools.py: /api/print/upscale uses new service; method="auto" by default;
GET /api/print/upscale/available returns full capability map with device info
and recommended_label; POST /api/print/upscale/refresh-caps busts cache
without restart (useful after installing NCNN binary into container)
Frontend:
- upscale.js: fetches capability map on first open; builds method selector showing
only available options; labels recommended method with ★; shows device info
(CUDA/MPS/CPU/NCNN) in dialog; maps display label back to method key on submit;
shows actual method used in success toast and undo history entry
Scripts:
- scripts/download_realesrgan.py: downloads NCNN Vulkan binary for current platform
(Linux/macOS/Windows) to /app/data/models/realesrgan/; makes executable;
run inside container or locally
https://claude.ai/code/session_01B58MaJCU1R6KwBDJCp8AfN
- Fix My Library: Add CSS styling for library browser, items now visible
- Integrate My Library into Shapes tool with tabbed interface
- Improve AI Inpaint: Add transform mode for scaling/sizing selections
- Add helpful guidance explaining inpaint vs transform modes
- Add U2net as alternative background removal (avoids rembg issues)
- Create U2net model definition and download script
- Improve Caddyfile with multiple options and troubleshooting guide
Note: Brush Select (AI Paint) tool was already implemented and working.
https://claude.ai/code/session_01CLedz6CanT9t46KBvng3vz
- Fix database path mismatch: download_sample_eyes.py now uses
ai_photo_edit.db instead of photoedit.db
- Add init_database.py script to initialize DB before eye import
- Add AUTO_DOWNLOAD_SAM=true environment variable (default: enabled)
- Update entrypoint.sh to:
1. Initialize database first
2. Auto-download SAM model (~375MB) on first startup
3. Then import eyes (now works since DB exists)
- Update path detection to work in both Docker and local environments
- Add torch, torchvision, segment-anything to requirements
- Create download_sam_model.py script to fetch SAM checkpoint
- Update tools.py to use local SAM with Replicate API fallback
- Add SAM model check to entrypoint.sh with helpful instructions
- Model persists in /app/data/models via Docker volume mount
Creates scripts/download_sample_eyes.py that:
- Downloads public domain classical sculpture images from Wikimedia
- Creates patch records in database
- Generates thumbnails
- Populates the Eye Catalog with starter content