diff --git a/README.md b/README.md index 09111d1..def64e5 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,6 @@ services: - IMMICH_URL=http://192.168.1.10:2283 - API_KEY=your-immich-api-key - FRIGATE_URL=http://192.168.1.10:5000 - - AUTO_MODE=true - CRON_SCHEDULE=0 3 * * 0 # Every Sunday at 3 AM volumes: - /path/to/models:/models @@ -161,7 +160,7 @@ The first run after a fresh install downloads the embedding models (~1-2 GB). Su | Variable | Default | Description | | :--- | :--- | :--- | -| `AUTO_MODE` | `false` | Run without interactive prompts — required for Docker/cron use | +| `AUTO_MODE` | *(auto)* | Force non-interactive mode even in a terminal; auto-detected otherwise (no TTY = auto) | | `TRAINING_MODE` | `face` | `face` — upload crops to Frigate API; `object` — save crops to disk | | `STRATEGY` | `auto` | `auto` (adaptive), `standard` (30 images), `broad` (100 images) | | `LIMIT` | *(unset)* | Exact image count — overrides `STRATEGY` | diff --git a/compose.yml b/compose.yml index c7bfada..3a4b75b 100644 --- a/compose.yml +++ b/compose.yml @@ -9,7 +9,9 @@ services: - FRIGATE_URL=${FRIGATE_URL} # ── Mode & Strategy ─────────────────────────────────────────────────── - - AUTO_MODE=true + # Auto mode is active by default when no TTY is present (Docker/cron). + # Run with `docker run -it` or set AUTO_MODE=true to force non-interactive + # in a terminal. # TRAINING_MODE: face = upload to Frigate face recognition API # object = save crops to output dir for manual Frigate placement - TRAINING_MODE=face @@ -34,7 +36,7 @@ services: # - MAX_AUTO_IMAGES=80 # Hard cap on auto-diversity selection (default: 80) # ── Caching & Models ────────────────────────────────────────────────── - - FORCE_CPU=false + # - FORCE_CPU=true # Disable GPU, fall back to CPU # - ENABLE_CACHE=false # Disable embedding cache (default: true) - CACHE_DIR=/app/.if_cache - HF_HOME=/models/huggingface @@ -55,8 +57,6 @@ services: - /path/to/winnow/models:/models - /path/to/winnow/cache:/app/.if_cache - /path/to/winnow/output:/app/frigate_train - stdin_open: true - tty: true restart: unless-stopped deploy: resources: diff --git a/winnow/cli.py b/winnow/cli.py index 5da70a4..4ea9fdb 100644 --- a/winnow/cli.py +++ b/winnow/cli.py @@ -64,21 +64,18 @@ def main() -> None: rprint("[bold red]Could not fetch people from Immich. Check URL/Key.[/bold red]") return - # Check for non-interactive mode; also force auto when stdin has no TTY - # (e.g. Docker without -it) to avoid an EOFError crash - auto_mode = os.environ.get("AUTO_MODE", "false").lower() == "true" or not sys.stdin.isatty() + # Auto mode when no TTY (Docker, cron, pipes) — the primary use case. + # A TTY means local interactive use; AUTO_MODE=true overrides that for scripting. + auto_mode = not sys.stdin.isatty() or os.environ.get("AUTO_MODE", "").lower() in ("true", "1", "yes") dry_run = os.environ.get("DRY_RUN", "false").lower() in ("true", "1", "yes") if dry_run: rprint("[bold yellow]DRY RUN — no images will be downloaded or uploaded[/bold yellow]") if auto_mode: - if not sys.stdin.isatty() and os.environ.get("AUTO_MODE", "false").lower() != "true": - rprint("[dim]No TTY detected — running in auto mode. Set AUTO_MODE=true to suppress this.[/dim]") - else: - rprint("[bold cyan]Running in AUTO mode (non-interactive)[/bold cyan]") jobs = auto_configure(people) else: + rprint("[bold cyan]Interactive mode — set AUTO_MODE=true to skip prompts[/bold cyan]") jobs = interactive_configure(people) if jobs: