Files
openbot/DEPLOY_NOTES.md
2026-04-27 19:20:01 +02:00

11 KiB

Notes de deploiement - OpenSquared PWA

Date: 2026-04-26

Depot

https://gitea.open-squared.tech/admin/openbot.git
branche main

Commits importants:

fb8cc4d Initial PWA assistant proof of concept
94148e8 Rename installed PWA to OpenSquared
1f815fa Version PWA icon asset to refresh Android cache
1b9933d Fix voice button audio unlock hang

Derniers changements locaux a deployer:

- Service systemd `opensquared-assistant` pour tourner hors session Putty.
- Raccourci optionnel `/usr/local/bin/openbot`.
- Mode mains libres: `Demarrer` ecoute en continu, envoi apres 2 secondes de silence.
- TTS par defaut via voix navigateur `fr-FR` pour eviter l'accent anglais Groq.
- Voix navigateur adoucie avec preference pour voix feminine francaise.
- Ajout de contacts email par conversation.
- Carnet de contacts prod dans `/root/openbot/data/contacts.json`.
- Memoire professionnelle SQLite dans `/root/openbot/data/memory.sqlite`.
- Cache PWA: opensquared-assistant-v7.

VPS

Serveur: 46.202.173.47
Dossier app: /root/openbot
Domaine: bot.open-squared.tech
URL: https://bot.open-squared.tech

L'app Flask a ete testee sur:

http://46.202.173.47:8080/health
https://bot.open-squared.tech/health

Python

Sur le VPS, python3 -m venv .venv a d'abord echoue car python3.12-venv manquait.

Correctif:

apt update
apt install -y python3.12-venv
cd /root/openbot
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Service systemd

Installer ou mettre a jour le service:

cd /root/openbot
cp deploy/opensquared-assistant.service /etc/systemd/system/opensquared-assistant.service
systemctl daemon-reload
systemctl enable --now opensquared-assistant

Commandes quotidiennes:

systemctl start opensquared-assistant
systemctl stop opensquared-assistant
systemctl restart opensquared-assistant
systemctl status opensquared-assistant
journalctl -u opensquared-assistant -f

Raccourci optionnel:

install -m 755 /root/openbot/deploy/openbot /usr/local/bin/openbot
openbot start
openbot stop
openbot restart
openbot logs

HTTPS et Nginx Docker

Le VPS utilise deja un docker-compose.yml avec un conteneur nginx.

Montage nginx:

/root/tradon/nginx/conf -> /etc/nginx/conf.d
/etc/letsencrypt -> /etc/letsencrypt:ro
/root/tradon/nginx/certbot -> /var/www/certbot

Le bloc HTTP doit servir les challenges avant la redirection:

location /.well-known/acme-challenge/ {
    root /var/www/certbot;
}

location / {
    return 301 https://$host$request_uri;
}

Certificat cree avec:

certbot certonly --webroot \
  -w /root/tradon/nginx/certbot \
  -d bot.open-squared.tech

Le bloc HTTPS bot.open-squared.tech doit utiliser:

ssl_certificate /etc/letsencrypt/live/bot.open-squared.tech/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bot.open-squared.tech/privkey.pem;

Proxy depuis nginx Docker vers Flask sur l'hote:

proxy_pass http://172.17.0.1:8080;

Verifier:

docker exec nginx nginx -t
docker exec nginx nginx -s reload
curl -I https://bot.open-squared.tech/health

PWA Android

Nom installe:

OpenSquared

Icone:

static/icons/icon-v2.svg

Pour forcer Android/Chrome a prendre la nouvelle icone:

  1. git pull sur le VPS.
  2. Ouvrir https://bot.open-squared.tech/icons/icon-v2.svg.
  3. Desinstaller l'ancienne PWA.
  4. Reinstaller depuis Chrome.

Cache et bouton micro

Le bouton Demarrer etait non reactif sur navigateur parce que unlockAudio() pouvait rester bloque sur audio.play() avec un audio vide.

Correctif applique:

  • unlockAudio() utilise maintenant AudioContext.
  • index.html charge /app.js?v=5.
  • Service worker: opensquared-assistant-v5.
  • Le bouton Demarrer lance le mode mains libres.
  • Le message vocal est envoye automatiquement apres 2 secondes de silence.
  • La voix par defaut est celle du navigateur en fr-FR, via TTS_PROVIDER=browser.
  • La version v6 privilegie une voix feminine francaise si disponible sur l'appareil.
  • Les contacts peuvent etre ajoutes en disant par exemple: Ajoute Sophie avec l'adresse sophie@example.com.
  • Le service systemd definit CONTACTS_FILE=/root/openbot/data/contacts.json.
  • La version v7 ajoute une memoire professionnelle SQLite pour clients, projets, taches, notes et depots Git.
  • Le service systemd definit MEMORY_DB=/root/openbot/data/memory.sqlite.

Si le bouton ne reagit pas apres un deploiement:

PC: Ctrl+F5
Android: fermer l'app, rouvrir Chrome, ou desinstaller/reinstaller la PWA

Si ca persiste, ouvrir F12 -> Console et lire l'erreur JS.

Fin de session - 2026-04-27

Etat fonctionnel vise:

  • L'app ne depend plus d'une session Putty ouverte.
  • systemd gere le processus opensquared-assistant.
  • Gunicorn lance app:app depuis /root/openbot.
  • Le bouton Demarrer active une ecoute mains libres.
  • Une phrase est transmise automatiquement apres environ 2 secondes de silence.
  • La reponse est lue avec une voix navigateur francaise, adoucie et preferee feminine si disponible.
  • Les contacts email peuvent etre ajoutes par conversation.
  • Les clients, projets, taches, notes et depots Git associes peuvent etre memorises en SQLite.

Commits a avoir sur le VPS:

f876b3a Add hands-free PWA mode and systemd service
94e14a3 Add soft French voice and contact saving

Checklist VPS:

cd /root/openbot
git pull
cp deploy/opensquared-assistant.service /etc/systemd/system/opensquared-assistant.service
systemctl daemon-reload
systemctl enable --now opensquared-assistant
install -m 755 deploy/openbot /usr/local/bin/openbot
openbot restart
openbot status

Commandes utiles:

openbot start
openbot stop
openbot restart
openbot logs
systemctl status opensquared-assistant
journalctl -u opensquared-assistant -f

Variables importantes:

TTS_PROVIDER=browser
CONTACTS_FILE=/root/openbot/data/contacts.json
MEMORY_DB=/root/openbot/data/memory.sqlite

Exemples vocaux:

Ajoute Sophie avec l'adresse sophie@example.com
Envoie un email a Sophie
SAFTCO est un nouveau client, note quelque part que je dois rappeler le directeur
Associe le repo /root/openbot/repos/saftco au projet Portail SAFTCO
Qu'est-ce que tu sais sur SAFTCO ?

Attention cache mobile:

  • index.html charge /app.js?v=7.
  • Service worker: opensquared-assistant-v7.
  • Si Android garde l'ancien JS, fermer/rouvrir Chrome ou reinstaller la PWA.

Session memoire professionnelle et routeur SQL - 2026-04-27

Objectif:

  • Construire une memoire professionnelle utilisable par l'assistant vocal.
  • Stocker clients, projets, taches, notes et repos associes.
  • Permettre des questions naturelles du type:
    • Quels sont mes clients ?
    • Que dois-je faire pour ICT ?
    • Pour quel client ai-je le plus de taches ?
    • Note que pour FAIRCOT je dois tester le lien vers le PDF.

Problemes observes pendant les tests:

  • Les premieres versions etaient trop basees sur des regex et des actions en dur.
  • Les formulations vocales variables, les typos et les phrases de suivi rendaient cette approche fragile.
  • Exemple: note le comme une tache pour FAIRCOT devait comprendre que le faisait reference au message precedent, pas a une regle specifique.
  • Les actions de lecture specialisees se multipliaient trop vite: liste clients, liste taches, taches par client, client avec le plus de taches, etc.
  • Risque identifie: creer une action rigide pour chaque question probable au lieu de laisser le modele raisonner sur le schema.

Architecture retenue:

  • SQLite reste le stockage principal.
  • Le modele recoit:
    • le schema de la base,
    • un extrait de memoire actuelle,
    • l'historique recent de conversation,
    • le dernier message utilisateur.
  • Un routeur LLM decide entre trois sorties:
    • action: ecriture controlee, par exemple ajouter client, ajouter tache, terminer tache, ajouter repo.
    • interroger_base: lecture SQL readonly generee par le modele.
    • clarification: question a Laurent si la cible ou l'intention est ambigue.
  • Les lectures globales ne doivent plus devenir une explosion d'actions codees en dur.
  • Pour une question analytique, le modele genere un SELECT, puis l'app execute uniquement ce SQL en lecture seule.

Pourquoi ce choix:

  • Les questions metier sont ouvertes et evoluent vite.
  • Le modele est meilleur pour mapper une demande naturelle vers une intention ou une requete SQL que des regex fragiles.
  • Le dernier message reste prioritaire, mais le modele doit raisonner avec l'historique recent pour comprendre lui, le, cette tache, ce client.
  • Les ecritures restent controlees par une liste d'actions permises afin d'eviter qu'un SQL genere ne modifie la base.
  • Les lectures sont flexibles via SQL readonly, mais protegees par validation.

Securite SQL readonly:

  • memory.execute_read_query() accepte uniquement une seule requete SELECT.
  • Les points-virgules, commentaires SQL, PRAGMA, INSERT, UPDATE, DELETE, DROP, etc. sont rejetes.
  • SQLite set_authorizer bloque les operations non autorisees.
  • Les tables lisibles sont limitees a:
    • clients
    • projects
    • tasks
    • repositories
    • memories
  • Le resultat est limite pour eviter les sorties trop longues.

Corrections importantes de la session:

  • Le routeur utilise maintenant davantage d'historique recent pour les phrases de suivi.
  • Le prompt de secours ne demande plus au modele de produire du JSON d'action; cela evite de concurrencer le routeur.
  • Les anciennes fonctions regex sont considerees comme heritage/code mort si elles ne sont plus appelees.
  • Correction du bug "'id'" en rouge:
    • cause: des lignes SQL de synthese etaient stockees dans le contexte comme si elles etaient toujours des taches completes avec id et title;
    • fix: le contexte n'assume plus que chaque ligne possede ces champs.

Decision importante:

  • Ne pas ajouter de micro-regles specifiques comme pending_note pour chaque cas de suivi.
  • Preferer un routeur LLM qui evalue l'intention avec toute la conversation recente.
  • Si le modele doute, il doit demander une precision plutot que choisir une action au hasard.

Limite actuelle:

  • La qualite depend beaucoup du modele Groq utilise pour le routage.
  • Si les references implicites continuent a echouer, tester un modele plus fort ou separer en deux appels:
    • appel 1: comprendre l'intention et la cible avec l'historique;
    • appel 2: generer l'action ou le SQL readonly.

Etat mental a garder pour la suite:

  • Pour les ecritures: actions explicites, schema stable, confirmation si doute.
  • Pour les lectures: SQL readonly genere par le modele.
  • Pour les phrases ambigues: clarification utilisateur.
  • Eviter de transformer chaque bug conversationnel en regex supplementaire.