nas-runbooks/common/hermes-nabil-images-flyers-...

4.5 KiB

hermes-nabil (VPS Contabo) — images, flyers et rendu navigateur

Prototype du futur hermes-desktop (Mac). Complete common/hermes-nabil-vps-deploiement.md.

1. Toolset navigateur : hermes postinstall doit etre BAKE dans l'image

hermes postinstall installe Node, ffmpeg, ripgrep, agent-browser + Chromium (/root/.agent-browser/browsers/chrome-<version>/chrome, ~390 Mo). Tout cela vit dans le filesystem du conteneur : un docker compose up -d qui recree le conteneur le perd.

Piege vecu

Ajouter simplement RUN hermes postinstall a un FROM python:3.11-slim echoue en silence (build exit 0, image sans navigateur) :

  • listes apt vides -> Unable to locate package ripgrep / ffmpeg
  • Node.js not found — Could not find Node.js 22 binary for linux-x64

Dockerfile correct

FROM python:3.11-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
      curl ca-certificates xz-utils nodejs npm ffmpeg ripgrep \
      fonts-dejavu-core fonts-liberation \
      libnss3 libnspr4 libdbus-1-3 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
      libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
      libgbm1 libpango-1.0-0 libcairo2 libasound2 libatspi2.0-0 libx11-6 \
      libxcb1 libxext6 libexpat1 libuuid1 \
 && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir hermes-agent \
    python-docx python-pptx openpyxl XlsxWriter reportlab pypdf pillow markdown requests
ENV HERMES_HOME=/data
WORKDIR /data
RUN hermes postinstall && rm -rf /var/lib/apt/lists/* /tmp/*
CMD ["hermes","gateway","run"]

Verification apres build (sans toucher au conteneur en service) :

docker run --rm --entrypoint bash hermes-nabil:latest -lc \
  'which node ffmpeg rg; ls -d /root/.agent-browser/browsers/chrome-*'

Image finale ~666 Mo. Build ~4 min -> toujours en detache (nohup docker build ... > log 2>&1 &), le connecteur mcp-vps tombe sur les operations longues.

2. Rendu HTML/CSS -> PNG / PDF

Pas besoin de Playwright : Chrome headless en CLI suffit et est plus robuste.

CH=$(ls -d /root/.agent-browser/browsers/chrome-*/chrome | tail -1)
$CH --headless --disable-gpu --no-sandbox --hide-scrollbars \
    --window-size=1080,1350 --screenshot=/data/out.png file:///data/in.html
$CH --headless --disable-gpu --no-sandbox --no-pdf-header-footer \
    --print-to-pdf=/data/out.pdf file:///data/in.html

Les ERROR:dbus/bus.cc sont cosmetiques (pas de bus D-Bus en conteneur), le fichier est bien ecrit. --no-sandbox obligatoire en conteneur. @page{size:WxH;margin:0} en CSS pour un PDF au format exact.

3. Generation d'images IA — OpenCode ne sait PAS faire

Teste le 18/07/2026 sur https://opencode.ai/zen/go/v1 :

  • /images/generations : 404 (endpoint inexistant chez OpenCode).
  • mimo-v2-omni : 400 "Upstream request failed" meme sur un simple prompt texte -> modele mort cote provider.
  • mimo-v2.5 (200) invente un lien imgur bidon quand on lui demande une image.
  • /models renvoie 403 Cloudflare 1010 sans en-tete User-Agent -> toujours envoyer un UA.

=> Backend image = Google AI Studio (Gemini/Imagen), cle GEMINI_API_KEY dans data/.env. Cascade implementee dans /data/nyora/nyora_image.py : gemini-3-pro-image-preview -> gemini-2.5-flash-image -> imagen-4.0-generate-001 -> imagen-3.0-generate-002. Auth par en-tete x-goog-api-key (pas de cle dans l'URL, pas de fuite dans les logs).

4. Pipeline flyer Nyora

/data/nyora/nyora_flyer.py : image IA -> HTML/CSS charte Or Bruni (navy #1A1A2E, cream #F5F5F0, gold #B8862A) -> PNG + PDF -> envoi Telegram (multipart urllib, zero dependance). Skill agent : /data/skills/nyora-flyer/SKILL.md.

python3 /data/nyora/nyora_flyer.py '{"nom":"x","titre":"Titre <em>or</em>","sous_titre":"NYORA",
 "corps":["ligne 1","ligne 2"],"cta":"Contact","prompt_image":"... sans texte","telegram":true}'

Regle : le prompt image precise sans texte — le texte est pose en HTML (net, orthographe maitrisee). Image encodee en base64 inline dans le HTML : un seul fichier, pas de probleme de chemin cote Chrome.

5. Rappels

  • Verifier une cle sans l'afficher : set -a; . /data/.env; set +a; eval v=\${VAR}; echo ${#v}. Attention : ${#VAR} sur le nom renvoie la longueur du nom, pas de la valeur.
  • data/.env est le seul fichier lu par Hermes (pas le .env racine).
  • Le wrapper mcp interdit docker rm -f : utiliser docker compose up -d (recreate propre) et docker run --rm pour les tests jetables.