Pipeline complet dans feature/hermes-auto-improve :
- auto-improve.py : analyse admin/ avec hermes --profile funk-ai, applique
les améliorations, committe dans la branche, ré-ingère dans Qdrant
- trigger-server.py : HTTP 9095 (POST /trigger, /trigger/all, /trigger/subdir,
/trigger/dry-run) pour déclenchement depuis n8n ou manuellement
- Ansible role hermes_auto_improve : déploie scripts + service systemd sur s01
- n8n workflow "Hermes Auto-Improve" (ID: CX72UUOempE1YtNL) : schedule
hebdo dimanche 09h + webhook manuel → analyse → résumé LLM → email
Tout reste dans cette branche — rien ne touche main avant review.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Réécriture complète pour une expérience chat naturelle :
- Mode VEILLE : écoute "Ok Hermès" → active la conversation
- Mode CONVERSATION : 60s de parole libre sans répéter le wake word
- webrtcvad mode=3 (remplace détection énergie) — fini les faux déclenchements
- Single large-v3 (supprime la détection 2 niveaux peu fiable)
- VOICE_INJECT prefix pour forcer des réponses courtes
- Mots de sortie : "au revoir", "bonne nuit", "stop hermes", "fin"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- VAD mode : Whisper small (~0.3s) pour détecter "ok hermes", large-v3 uniquement pour transcrire la commande
- PTT mode : large-v3 direct (inchangé)
- install-service.sh : installe hermes-voice comme service utilisateur systemd (auto-start à la session)
- doc mise à jour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- tools/hermes-voice/ : pipeline VAD → faster-whisper → LiteLLM → piper TTS
- mot-clé "hermes" détecté dans la transcription Whisper (pas de wake word model)
- modes : VAD continu + push-to-talk + --no-tts pour debug
- nftables : ouvrir port 4000 LiteLLM vers LAN domestique (192.168.1.0/24)
- admin/ia/hermes-voice.md : documentation installation et utilisation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Installation poste perso + storage-01, configuration namespace par défaut,
raccourcis navigation, cas d'usage fréquents, dépannage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
n8n tourne dans un pod k8s — le port 25 de postfix n'était ouvert
que pour 192.168.10.0/24 (nœuds cluster), pas pour 10.42.0.0/16
(pods). Connexion ETIMEDOUT au nœud Send Email du workflow alertes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Brevo rejetait les mails envoyés depuis aliyesilkaya93@gmail.com
(domaine non vérifié côté Brevo). Gmail SMTP signe lui-même les mails
→ livraison garantie vers le compte Gmail destinataire.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
LiteLLM écoutait sur 127.0.0.1 uniquement — les pods k8s (10.42.x.x)
ne pouvaient pas atteindre 192.168.10.1:4000, Open WebUI affichait
"Aucun modèle disponible". Binding changé en 0.0.0.0 + nftables ouvert
pour 192.168.10.0/24 et 10.42.0.0/16.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Grant user privileges : ajout no_log:true (mot de passe visible en clair
dans les logs Ansible en cas d'échec via item loop)
- Alias 'db' déprécié par community.postgresql → renommé 'database'
- litellm DB recrée manuellement (corruption pg_attribute copiée depuis RAID)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
La tâche "Mount RAID5 array (fstab + immediate)" écrasait l'entrée fstab
bind-mount (/home/data → /srv/data) et remontait le RAID à chaque apply.
- Suppression de ansible.posix.mount state=mounted pour le RAID
- La tâche mdadm.conf devient conditionnelle (when: stdout non vide)
et failed_when: false pour ne pas bloquer si le RAID n'est pas assemblé
- Ajout d'un sanity-check : vérifie que /srv/data est un répertoire
- Commentaires explicatifs dans tasks/ et defaults/ pour prévenir toute
régression future
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Open WebUI (openwebui.lab.local) :
- Connecté à LiteLLM (192.168.10.1:4000/v1) comme backend OpenAI-compatible
- PostgreSQL via storage-01 pour l'historique des conversations
- PVC 5Gi NFS pour les uploads, Traefik IngressRoute
n8n (n8n.lab.local) :
- PostgreSQL via storage-01, chiffrement des credentials
- PVC 2Gi NFS, Traefik IngressRoute
- Webhook URL interne : http://n8n.lab.local
Ansible : ajoute openwebui et n8n dans postgresql_databases/users
(vault_pg_openwebui_password + vault_pg_n8n_password à ajouter au vault)
Prérequis avant 1er déploiement :
make vault-edit # ajouter les 2 passwords
make apply-storage --tags postgresql
kubectl create secret generic open-webui-secret -n ai ...
kubectl create secret generic n8n-secret -n ai ...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Incident : sdb ATA bus errors sous charge I/O bloquaient le rsync en état D
- Résolution : sdb marqué (F) dans mdadm, rsync relancé (205 MB/s, 35s)
- Fix : version.info corrompu dans segment Qdrant RocksDB (0.D\0 → 0.6.0)
- Architecture : /srv/data bind-monté depuis /home/data (NVMe XFS, 801 GB libres)
- fstab mis à jour, tous les services opérationnels
- CLAUDE.md : venv bootstrap, make --tags invalide, incidents.md dans admin/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Indexation de admin/ (284 chunks) dans Qdrant via embeddings Qwen3-8B.
rag-query utilisable en CLI et depuis le profil funk-ai de Hermes.
Note: modèle d'embedding générique — qualité limitée, voir admin/ia/rag.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>