# meromero-charrp — G4-MeroMero-v2-31B NVFP4A16 char-rp PROSE seat (non-thinking, MULTIMODAL)
# on ana-ml2 GPU0. Replaces the retired Magidonia GGUF seat (char-rp-gguf / llama-charrp).
#
# Gemma-4 dense but with SLIDING-WINDOW attention -> KV-efficient, serves the full native 256K
# at ~2x concurrency. Vision enabled: preprocessor_config.json was materialized from
# processor_config.json's image_processor section (Gemma4ImageProcessor); audio is
# config-declared but weightless (no audio tensors) so it serves image + text.
#
# Co-located on GPU0 with vllm-aeon-gen (gen). util 0.52 leaves ~5GB GPU0 headroom
# (0.55 left only ~1.8GB). Tunables in .env.

name: meromero-charrp

services:
  vllm-meromero-rp:
    image: ${MEROMERO_IMAGE:-vllm/vllm-openai:latest}
    container_name: ${MEROMERO_CONTAINER:-vllm-meromero-rp}
    restart: unless-stopped
    ipc: host
    ports:
      - "${MEROMERO_PORT:-8016}:8000"
    volumes:
      - /tank/aimodels:/tank/aimodels
    environment:
      - PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
      - VLLM_API_KEY=${API_KEY:-}
    command:
      - ${MEROMERO_MODEL:-/tank/aimodels/meromero-v2-nvfp4-work/G4-MeroMero-v2-31B-NVFP4A16}
      - --quantization
      - compressed-tensors
      - --served-model-name
      - char-rp
      - char-rp-thinking
      # Tool-calling: Gemma-4 emits its OWN native syntax
      # (<|tool_call>call:name{...}<tool_call|>), NOT the qwen3_coder XML the
      # other seats use. vLLM 0.24 ships a matching `gemma4` parser whose token
      # constants line up with this tokenizer's etc/eoc/escape tokens exactly.
      # Without these two flags any tools-bearing request 400s outright.
      - --tool-call-parser
      - gemma4
      - --enable-auto-tool-choice
      # The gemma4 REASONING parser is what absorbs the <|channel>...<channel|>
      # thought markers; without it they leak into `content` verbatim on the
      # post-tool-response turn (upstream vllm #45834 — the chat template leaves
      # the prompt inside an open channel block).
      - --reasoning-parser
      - gemma4
      # Dwarf-panel CoT patch 2026-08-21: force-open <|channel> on enable_thinking:true
      - --chat-template
      - /tank/aimodels/meromero-v2-nvfp4-work/patched_chat_template.jinja
      # MANDATORY companion to the reasoning parser on this seat. The parser
      # reads enable_thinking from chat_template_kwargs and DEFAULTS IT TO TRUE
      # (vllm/parser/gemma4.py:439). True makes is_reasoning_end() return False
      # at a new turn, which pre-initialises the engine to REASONING -> ALL plain
      # RP prose lands in reasoning_content with a NULL content, breaking every
      # char-rp consumer. This template already defaults enable_thinking to false
      # (chat_template.jinja:350), so passing it explicitly renders a BYTE-
      # IDENTICAL prompt (verified across plain/tools/post-tool/system shapes) --
      # it only corrects the parser's state machine. Do not remove.
      - --default-chat-template-kwargs
      - '{"enable_thinking": false}'
      - --max-model-len
      - "${MEROMERO_MAX_MODEL_LEN:-262144}"
      - --max-num-seqs
      - "${MEROMERO_MAX_NUM_SEQS:-32}"
      - --gpu-memory-utilization
      - "${MEROMERO_GPU_MEM_UTIL:-0.52}"
      - --kv-cache-dtype
      - fp8
      - --trust-remote-code
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids:
                - "${MEROMERO_GPU_ID:-0}"
              capabilities:
                - gpu
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 600s
    networks:
      - tnet
    labels:
      # STOPPED 2026-08-24 — superseded by stacks/gemma4-charrp (gemma-4-26B-A4B
      # -it NVFP4 MoE) on the same port and the same served-model-names. Kept as
      # the rollback seat: `docker compose up -d vllm-meromero-rp` here after
      # stopping the gemma4 one, since both want :8016.
      - homepage.group=AI - Dormant
      - homepage.name=char-rp (MeroMero-v2 NVFP4) — rollback
      - homepage.icon=mdi-drama-masks
      - homepage.description=Superseded 2026-08-24 by the Gemma-4 26B-A4B MoE seat; dense 31B NVFP4A16, kept for rollback (ana-ml2 GPU0)
      - homepage.href=http://10.250.50.54:${MEROMERO_PORT:-8016}/docs

networks:
  tnet:
    name: traefik-net
    external: true
