# FabledCurator GPU agent — desktop run via docker compose.
#
# Usage:
#   1. Generate a token: FC → Settings → Tagging → GPU agent → Generate token.
#   2. Create a .env next to this file:
#        FC_URL=http://curator.traefik.internal
#        FC_TOKEN=<paste-the-token>
#        # optional: CCIP_MODEL=ccip-caformer_b36-24   (the F1-0.94 variant)
#   3. docker compose up -d     (pulls the published image)
#   4. Open http://localhost:8770 → Start. Pause/Stop hands the GPU back.
#      docker compose down       to stop the container entirely.
#
# Surviving a curator redeploy (you're away, can't touch the agent):
#   - A running agent rides out curator being unreachable on its own — it retries
#     leasing with capped backoff and resumes when the server is back. In-flight
#     work is handed back (not failed), so a redeploy never poisons good jobs.
#   - AUTO_START=1 (below) also resumes the worker if the AGENT container itself
#     restarts (host reboot / crash via `restart: unless-stopped`) — no click.
#
# Needs the NVIDIA Container Toolkit installed on the host for --gpus.

services:
  fc-gpu-agent:
    image: git.fabledsword.com/bvandeusen/fabledcurator-agent:latest
    pull_policy: always
    ports:
      - "8770:8770"
    environment:
      FC_URL: ${FC_URL:-http://curator.traefik.internal}
      FC_TOKEN: ${FC_TOKEN:?set FC_TOKEN in .env (FC → GPU agent → Generate token)}
      CCIP_MODEL: ${CCIP_MODEL:-}
      DETECTOR_LEVEL: ${DETECTOR_LEVEL:-m}
      BATCH_SIZE: ${BATCH_SIZE:-4}
      # Resume the worker automatically on container start (survive a reboot /
      # crash-restart while you're away). Set to 0 to require a manual Start.
      AUTO_START: ${AUTO_START:-1}
      # Autoscale the worker count (throughput hill-climb that finds the sweet
      # spot + backs off under VRAM pressure). On by default; toggle live in the
      # control UI. Set to 0 to start in manual mode.
      AUTO_SCALE: ${AUTO_SCALE:-1}
      # Aggregate download cap in MB/s (stills + video streams combined), so the
      # agent can't saturate the desktop's network and wreck browsing — WiFi
      # especially. 0 = unlimited; tunable live in the control UI.
      BANDWIDTH_LIMIT_MB_S: ${BANDWIDTH_LIMIT_MB_S:-8}
      # Crop embedder (SigLIP concept bag): float16 keeps VRAM low on a shared
      # desktop GPU; the model itself is announced by the server.
      SIGLIP_DTYPE: ${SIGLIP_DTYPE:-float16}
      # Crop PROPOSERS (extra YOLO detectors → more/better concept crops). Each
      # downloads its weights once (cached on the models volume) and self-disables
      # if the download/load fails. Blank any one to turn it off.
      #   PERSON_WEIGHTS: general COCO person detector (Western/realistic figures),
      #     merged with the anime detector. yolo11n.pt (~6 MB, auto-downloaded).
      #   ANATOMY_WEIGHTS: booru_yolo anime/furry/NSFW components (~40 MB). NB the
      #     repo states no license — fine for private use. yolov8n_as01.pt is the
      #     6 MB nano if you want lighter than yolov11m_aa22.pt.
      #   PANEL_WEIGHTS: mosesb comic-panel detector (Apache-2.0), "hf_repo::file".
      PERSON_WEIGHTS: ${PERSON_WEIGHTS:-yolo11n.pt}
      ANATOMY_WEIGHTS: ${ANATOMY_WEIGHTS:-https://github.com/aperveyev/booru_yolo/raw/main/models/yolov11m_aa22.pt}
      PANEL_WEIGHTS: ${PANEL_WEIGHTS:-mosesb/best-comic-panel-detection::best.pt}
    volumes:
      # Persist the downloaded ONNX models so restarts are fast.
      - fc-agent-models:/models
    restart: unless-stopped
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

volumes:
  fc-agent-models:
