Image Moderation Service

TypeScript/Express service that checks uploaded images for NSFW/explicit content using a local vision LLM running on an AMD NPU. When an image is flagged unsafe, it fires callbacks to replace the image and flag the user.

How It Works

  1. An image is uploaded to POST /moderate
  2. The image is sent to the local vision LLM (gemma3:4b via FLM proxy) for analysis
  3. The LLM classifies the image as safe or unsafe
  4. If unsafe and metadata was provided, two callbacks fire (fire-and-forget):
    • Upload service — replaces the image with a stub
    • Parochia — flags the user for moderation

Endpoints

Method Path Description
POST /moderate Moderate an image (multipart: file, context, imagePath, userId, siteId)
GET /health Health check

Configuration

All configuration is via environment variables (.env file):

Variable Default Description
PORT 8100 Service port
VISION_AI_URL http://localhost:8000/v1/chat/completions Vision LLM endpoint
VISION_AI_MODEL gemma3:4b Vision model to use
UPLOAD_SERVICE_REPLACE_URL Callback URL to replace flagged images
UPLOAD_SERVICE_SECRET Auth secret for upload service callback
PAROCHIA_CALLBACK_URL Callback URL to flag users in Parochia
PAROCHIA_CALLBACK_SECRET Auth secret for Parochia callback

Usage

npm install        # Install dependencies
npm run build      # Compile TypeScript → dist/
npm start          # Run the service
npm run dev        # Development mode with hot-reload

# Windows service
node service-install.js
node service-uninstall.js

Project Structure

src/
  server.ts      — Express app, routes, callback logic
  moderate.ts    — Image moderation logic (vision LLM calls)

Dependencies

  • express — HTTP server
  • multer — Multipart file upload handling
  • sharp — Image processing
  • dotenv — Environment variable loading
  • node-windows — Windows service management

Environment

  • OS: Windows 11, AMD NPU hardware
  • Runtime: Node.js + TypeScript
  • Vision LLM: gemma3:4b served by FLM proxy on localhost:8000
Description
Image moderation service using local vision LLM
Readme 53 KiB
Languages
TypeScript 92.7%
JavaScript 7.3%