5.4 KiB
hermes-nabil (VPS Contabo) — images, flyers et rendu navigateur
Prototype du futur
hermes-desktop(Mac). Completecommon/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 — ni OpenCode, ni Gemini free tier
OpenCode : aucune capacite image (teste 18/07/2026)
/images/generations: 404, l'endpoint n'existe pas.mimo-v2-omni: 400 "Upstream request failed" meme sur un prompt texte trivial -> modele mort cote provider.mimo-v2.5(200) invente un lien imgur bidon quand on lui demande une image./models: 403 Cloudflare 1010 sans en-teteUser-Agent.
Gemini direct (Google AI Studio) : quota 0 sur le free tier
Cle valide (50 modeles listes), mais tous les modeles image renvoient 429 limit: 0 :
gemini-3-pro-image, gemini-3.1-flash-image, gemini-2.5-flash-image et variantes.
Les imagen-4.0-* renvoient 404 "no longer available to new users".
=> La generation d'images Google est reservee au tier payant (facturation activee sur le projet).
Ce n'est pas un probleme de cle : la meme cle liste les modeles et fonctionne en texte.
Backend retenu : OpenRouter -> google/gemini-2.5-flash-image
Meme modele (nano-banana), accessible immediatement, cout une fraction de centime par image.
Voir openrouter-image-gen.md pour les pieges (modalities, message.images[]).
Cle OPENROUTER_API_KEY dans data/.env (issue de HERMES_PERSO_OPERSOKEY -> en realite
HERMES_PERSO_OPENROUTER_KEY du NAS, transferee sans exposition :
voir transfert-secret-inter-machines.md).
/data/nyora/nyora_image.py implemente la cascade OpenRouter -> Gemini direct :
Gemini reste cable et prendra le relais sans modification de code le jour ou la facturation
Google sera activee. Le backend OpenRouter accepte en plus une image source (edition :
fond neutre, retouche), ce que la voie Gemini directe ne fait pas ici.
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/.envest le seul fichier lu par Hermes (pas le.envracine).- Le wrapper mcp interdit
docker rm -f: utiliserdocker compose up -d(recreate propre) etdocker run --rmpour les tests jetables.