Commit Graph
24 Commits
Author SHA1 Message Date
Ashim 08a7ffe403 Enhance logging and error handling across tools; add full tool audit and Playwright tests
- Added model mismatch warnings in colorize, enhance-faces, and upscale routes.
- Improved error handling in colorize, enhance_faces, remove_bg, restore, and upscale scripts with detailed logging.
- Updated Dockerfile to align NCCL versions for compatibility.
- Introduced a new full tool audit script to test all tools for functionality and GPU usage.
- Created Playwright E2E tests for GPU-dependent tools to ensure proper functionality and performance.
2026-04-17 23:06:31 +08:00
ashim-hq 79c4ed6a35 perf: parallelize model downloads and switch to registry cache
- Parallelize all 14 model downloads using ThreadPoolExecutor (6 workers)
  Downloads were sequential (~30 min), now concurrent (~5-10 min)
- Switch Docker cache from type=gha to type=registry (GHCR)
  GHA cache has 10 GB limit causing blob eviction and corrupted builds
  Registry cache has no size limit and persists across runner instances
- Add pip download cache mounts to all pip install layers
  Prevents re-downloading packages when layers rebuild
2026-04-17 14:54:23 +08:00
ashim-hq f28792a5ed fix: resolve runtime model path mismatch for non-root Docker user
Set U2NET_HOME=/opt/models/rembg so rembg models pre-downloaded at
build time as root are found at runtime by the non-root ashim user.
Without this every fresh container re-downloaded the 973 MB BiRefNet
models on first background-removal request.

Apply the same fix to PaddleOCR: download to /opt/models/paddlex and
symlink into both /root/.paddlex and /app/.paddlex so PaddleX finds
models regardless of which HOME gosu resolves at runtime.

Fall back to per-request spawning in bridge.ts when the persistent
dispatcher crashes mid-request (e.g. OOM loading a large ONNX model),
so the operation succeeds instead of surfacing "Python dispatcher
exited unexpectedly" to the user.

Improve entrypoint.sh permission warning to mention Windows bind mounts
as the likely cause.
2026-04-16 23:45:02 +08:00
Siddharth Kumar Sah b7033b3f53 fix(docker): use hf_hub_download for HuggingFace models to fix CDN 504s
urlretrieve against the HuggingFace CDN was consistently returning HTTP
504 in GitHub Actions runners for LaMa, NAFNet, and the OpenCV caffemodel.
The huggingface_hub library has built-in retry logic, resumable downloads,
and better CDN routing than bare urlretrieve.

- download_lama_model: urlretrieve → hf_hub_download (Carve/LaMa-ONNX)
- download_nafnet_model: urlretrieve → hf_hub_download (mikestealth/nafnet-models)
- download_opencv_colorize_models: caffemodel → hf_hub_download (space repo_type)
- _urlretrieve: retry count 3→5, flat 10s delay → exponential backoff (10/20/40/80s)
- Also reverts the SKIP_MODEL_DOWNLOADS=true from CI workflow (wrong approach)
2026-04-14 23:05:09 +08:00
Siddharth Kumar Sah fb6cff0fec fix(docker): add retry logic to model downloads for transient 5xx/timeout errors
download_models.py used bare urllib.request.urlretrieve() with no retry
logic. CI hit a HTTP 504 Gateway Timeout mid-build, failing the Docker
Build Test. Added _urlretrieve() wrapper that retries up to 3 times with
a 10s delay on any 5xx or network error. Also adds imports for time and
urllib.error.
2026-04-14 22:49:49 +08:00
Siddharth Kumar Sah 85b1cfc10a chore: rename Stirling-Image to ashim across entire codebase
Complete rebrand from Stirling-Image to ashim following the project
move to https://github.com/ashim-hq/ashim.

Changes across 117 files:
- Package scope: @stirling-image/* → @ashim/*
- GitHub URLs: stirling-image/stirling-image → ashim-hq/ashim
- Docker Hub: stirlingimage/stirling-image → ashimhq/ashim
- GitHub Pages: stirling-image.github.io → ashim-hq.github.io
- All branding text: "Stirling Image" → "ashim"
- Docker service/volumes/user: stirling → ashim
- Database: stirling.db → ashim.db
- localStorage keys: stirling-token → ashim-token
- Environment variables: STIRLING_GPU → ASHIM_GPU
- Python cache dirs: .cache/stirling-image → .cache/ashim
- SVG filter IDs, test prefixes, and all other references
2026-04-14 20:55:42 +08:00
stirling-image f00a86aa18 fix(docker): rename duplicate download_codeformer_model function
The ONNX variant shadowed the .pth variant due to identical function
names, so codeformer.pth was never downloaded. Renamed the ONNX
function to download_codeformer_onnx_model so both run.
2026-04-14 18:00:47 +08:00
stirling-image 382e974eed fix(docker): use HuggingFace mirror for colorization caffemodel
The original Berkeley server (eecs.berkeley.edu) is dead, returning
404 after redirect. Switched to a reliable HuggingFace-hosted mirror
of the same 129MB model file.
2026-04-14 17:41:39 +08:00
stirling-image fce2c64ba2 fix(docker): add User-Agent header to model downloads
The Berkeley colorization server returns 403 for the default
Python-urllib User-Agent. Setting a global opener fixes this
for all model downloads.
2026-04-14 17:26:01 +08:00
stirling-image fede23e3a6 fix(docker): correct facexlib parsing_parsenet.pth download URL
The model is in the v0.2.2 release, not v0.1.0.
2026-04-14 17:07:23 +08:00
8d8ab4bc45 fix(docker): close remaining airgap gaps for fully offline operation (#70)
Three fixes to ensure zero network access after docker pull:

1. rembg model allowlist: validate model parameter against the 7
   pre-downloaded models, preventing rembg from attempting to download
   unknown models via a raw API call.

2. GFPGAN/CodeFormer auxiliary models: pre-download facexlib's
   detection_Resnet50_Final.pth and parsing_parsenet.pth at build time.
   These were previously downloaded on first use via basicsr. Symlinks
   in /app/gfpgan/weights/ ensure codeformer-pip also finds them.

3. OpenCV colorize models: pre-download the prototxt, caffemodel, and
   pts_in_hull.npy so the lightweight OpenCV colorizer fallback works
   in addition to the primary DDColor method.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 16:51:46 +08:00
stirling-image e3bfa6585a fix(ai): use .tflite URL for blaze_face_short_range model
Google removed the .task bundle from their MediaPipe storage,
causing Docker builds to fail with a 404 during model download.
2026-04-14 16:43:42 +08:00
519541867e fix(ai): support both old and new mediapipe APIs for airgapped Docker (#69)
MediaPipe >= 0.10.30 removed the mp.solutions namespace. This broke
face blur, face enhance, red-eye removal, and photo restoration for
users running newer mediapipe versions (closes #43).

All 5 Python scripts that use mediapipe now try the legacy mp.solutions
API first and fall back to the new mp.tasks API on AttributeError.
Model files (blaze_face_short_range.task, face_landmarker.task) are
pre-downloaded during Docker build into /opt/models/mediapipe/ so the
image works fully airgapped. Local dev auto-downloads to .models/.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-14 16:18:17 +08:00
6a43cc1b77 feat: SOTA AI photo restoration with multi-step pipeline (#58) (#62)
Add comprehensive photo restoration tool that chains multiple AI models:
- Scratch/tear/spot detection via morphological analysis (top-hat/black-hat transforms)
- Damage inpainting via LaMa ONNX model (reuses existing infrastructure)
- Face enhancement via CodeFormer ONNX (~377MB, from facefusion/models-3.0.0)
- Noise reduction via OpenCV NLMeans in LAB color space
- Optional B&W auto-colorization via DDColor (reuses existing model)

Settings: 3 restoration modes (Light/Auto/Heavy), individual feature toggles
for scratch removal, face enhancement (with fidelity slider), denoising
(with strength slider), and auto-colorize. Before/after comparison view.

Handles HEIC, HEIF, and all standard formats. Batch processing supported.
No new Python dependencies - reuses onnxruntime, cv2, mediapipe, PIL.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 21:57:51 +08:00
8071fe61c5 feat: AI face enhancement with GFPGAN and CodeFormer (#61)
* feat(shared): add enhance-faces tool definition and i18n strings

* feat(ai): add face enhancement script with GFPGAN and CodeFormer support

Detects faces via MediaPipe dual-model approach, then enhances using
GFPGAN (proven) or CodeFormer (via codeformer-pip) with auto fallback.
Supports strength-based alpha blending with original image.

* feat(ai): add TypeScript bridge for face enhancement

* feat(api): add enhance-faces route with GFPGAN/CodeFormer support

* feat(web): add enhance-faces settings component and register in tool registry

* feat(docker): add CodeFormer dependency and model download

- Add codeformer-pip to both CPU and GPU requirements
- Download CodeFormer model (~375MB) at Docker build time
- Add CodeFormer to smoke test verification

* fix(enhance-faces): address code review findings

- Skip alpha blend for CodeFormer (strength already applied via fidelity weight)
- Hide "only enhance main face" checkbox when Best (CodeFormer) is selected
- Fix sensitivity slider labels (swap More/Fewer faces to match actual behavior)
- Register EnhanceFacesControls in pipeline step settings
- Remove model names from user-facing descriptions

* fix(enhance-faces): fix CodeFormer integration and Docker setup

- Add codeformer-pip install to Dockerfile with --no-deps to avoid numpy 2.x conflict
- Re-pin numpy==1.26.4 after codeformer-pip install
- Pin codeformer-pip==0.0.4 in requirements files
- Broaden auto-mode fallback to catch any Exception from CodeFormer

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 21:56:59 +08:00
dfffc0a8cc feat(noise-removal): SOTA noise removal with 4 quality tiers (#57)
* feat(noise-removal): register tool in shared constants and i18n

* feat(noise-removal): add SCUNet and NAFNet model architectures

* feat(noise-removal): add Python denoising engine with 4 quality tiers

* feat(noise-removal): add TypeScript bridge for Python sidecar

* feat(noise-removal): add frontend settings with 4-tier selector

* feat(noise-removal): register in tool registry and pipeline

* feat(noise-removal): add Fastify API route with Zod validation

* feat(noise-removal): add SCUNet and NAFNet model downloads to Docker build

* test(noise-removal): add to e2e tool page rendering tests

* test(noise-removal): add integration tests for API endpoint

* style: fix biome formatting and import ordering

* fix(noise-removal): use correct model download URLs

NAFNet model is hosted on HuggingFace, not GitHub releases.
Also align SCUNet URL to use the KAIR releases (same as Docker build).

* fix(noise-removal): remove emojis from tier selector, simplify labels

Drop emoji icons from Quick/Balanced/Quality/Maximum buttons. Replace
technical algorithm names with plain descriptions users can understand.

---------

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:50:23 +08:00
c280076098 feat: SOTA AI photo colorization with DDColor deep learning model (#57) (#58)
Add AI-powered photo colorization that converts B&W/grayscale images to
full color using DDColor (ICCV 2023 dual-decoder architecture) via ONNX
Runtime. Includes model selection (Auto/DDColor/Classic), adjustable color
intensity, batch processing, before/after preview, and full HEIC/HEIF support.

Co-authored-by: stirling-image <stirling-image@users.noreply.github.com>
2026-04-13 19:40:55 +08:00
Siddharth Kumar Sah 0a506efe24 feat(erase-object): overhaul object eraser with LaMa inpainting improvements
Update erase-object pipeline, eraser canvas, and inpainting Python script.
Add LaMa model download script and update Dockerfile for model support.
Update multi-file tool routes for consistency.
2026-04-13 00:48:05 +08:00
Siddharth Kumar Sah f2e17d2d44 fix(upscale): overhaul UI, fix AI pipeline bugs, add format support
- Replace Auto/AI/Fast buttons with Fast/Balanced/Best (consistent with other tools)
- Rename "Denoise" to "Noise Reduction" with explanatory subtitle
- Change output format from 3 buttons to dropdown with all formats (PNG, JPG, WebP, AVIF, TIFF, GIF, HEIC, HEIF)
- Add HEIC/HEIF input decoding (was missing unlike other tools)
- Add HEIC/HEIF/AVIF output conversion via Sharp and heif-enc
- Generate browser-compatible WebP preview for non-previewable output formats
- Fix torchvision compatibility shim so Real-ESRGAN actually loads (was silently falling back to Lanczos)
- Fix denoise crash: Image.fromarray() instead of type(img).fromarray()
- Redirect stdout for entire AI pipeline to prevent library messages corrupting JSON output
- Add GFPGAN model download for face enhancement
- Use batch endpoint for multi-file uploads (enables Download All ZIP)
2026-04-12 21:22:55 +08:00
Siddharth Kumar Sah 28ee147cc7 feat(ocr): upgrade PaddleOCR to v3.x with PP-OCRv5 and VL model in Docker 2026-04-12 18:38:40 +08:00
Siddharth Kumar Sah 3345cb266a feat: add Ultra quality mode with BiRefNet-matting, rename quality tiers
Ultra quality (People only):
- BiRefNet-matting ONNX (928MB) for true alpha matting with per-pixel
  transparency on hair wisps and fine edges
- Custom rembg session class, zero new Python dependencies
- Model pre-downloaded in Docker build for immediate availability

Quality tier labels: Fast / HD / Max / Ultra (shorter, fits 4-col grid)
2026-04-12 18:23:09 +08:00
Siddharth Kumar Sah 1707521f3a feat: replace Python seam carving with caire Go binary
Replace the Python seam-carving library with caire (esimov/caire v1.5.0),
a Go-based content-aware resize engine that is faster and supports both
shrinking and enlarging via seam insertion.

- Add Go builder stage in Dockerfile to compile caire from source
- Rewrite seam-carving.ts to call caire via execFile (no Python sidecar)
- Remove content-aware-resize from PYTHON_SIDECAR_TOOLS (60s timeout)
- Add new options: blur radius, edge sensitivity, square mode, face detection
- Move content-aware toggle below standard resize in UI (subtler placement)
- Rename "Don't enlarge" to "Limit to original size" with hover tooltip
- Add smooth progress bar for medium-duration tools
- Delete seam_carve.py and remove seam-carving pip dependency
- Update integration tests and visual regression screenshots
2026-04-11 17:49:28 +08:00
stirling-imageandGitHub b0083e2b08 feat: unified Docker image with GPU auto-detection (#37)
Merge CPU, CUDA, and lite Docker images into a single unified image.
One tag (latest) works on all platforms: amd64 (NVIDIA CUDA) and arm64 (CPU).
GPU auto-detected at runtime. All ML models and packages baked in.

Key changes:
- Platform-conditional Dockerfile (nvidia/cuda on amd64, node on arm64)
- tini as PID 1 for proper signal handling
- Fix FILES_STORAGE_PATH data loss bug
- Fix RealESRGAN upscaler (was broken, always fell back to Lanczos)
- Fix PaddleOCR language codes and stdout corruption
- Simplified CI/CD (single build, single tag)
- Expanded model pre-download with verification
- Shutdown timeout, improved health endpoint
- Remove unused lama-cleaner
2026-04-10 13:21:06 +08:00
Siddharth Kumar Sah 80e536bcf8 chore: remove dead code, add test infrastructure, update docs
- Delete 3 dead files: use-batch-processor.ts, use-i18n.ts, smart-crop.ts (AI package)
- Remove dead getJobProgress function and unused runPythonScript wrapper
- Remove 6 unused imports across API and web apps
- Remove unused shared types (ImageFormat, AppConfig, ApiError, HealthResponse, JobProgress)
  and constants (SUPPORTED_INPUT_FORMATS/OUTPUT_FORMATS, DEFAULT_OUTPUT_FORMAT)
- Remove unused store method (setOriginalBlobUrl) and clean AI package re-exports
- Add test infrastructure: vitest config, unit/integration/e2e tests, fixtures, screenshots
- Add Docker test infrastructure: Dockerfile.test, docker-compose.test.yml
- Add download_models.py for pre-baking AI model weights in Docker
- Add filename sanitization utility (apps/api/src/lib/filename.ts)
- Update .gitignore to exclude coverage/, *.tsbuildinfo, .superpowers/, test artifacts
- Update .dockerignore to exclude test/coverage/IDE artifacts from builds
- Update docs: remove smart crop from AI docs (uses Sharp directly), update bridge docs
2026-03-23 11:46:45 +08:00