350 lines
11 KiB
Markdown
350 lines
11 KiB
Markdown
# Notes de deploiement - OpenSquared PWA
|
|
|
|
Date: 2026-04-26
|
|
|
|
## Depot
|
|
|
|
```text
|
|
https://gitea.open-squared.tech/admin/openbot.git
|
|
branche main
|
|
```
|
|
|
|
Commits importants:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
- 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
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
cd /root/openbot
|
|
cp deploy/opensquared-assistant.service /etc/systemd/system/opensquared-assistant.service
|
|
systemctl daemon-reload
|
|
systemctl enable --now opensquared-assistant
|
|
```
|
|
|
|
Commandes quotidiennes:
|
|
|
|
```bash
|
|
systemctl start opensquared-assistant
|
|
systemctl stop opensquared-assistant
|
|
systemctl restart opensquared-assistant
|
|
systemctl status opensquared-assistant
|
|
journalctl -u opensquared-assistant -f
|
|
```
|
|
|
|
Raccourci optionnel:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```text
|
|
/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:
|
|
|
|
```nginx
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/certbot;
|
|
}
|
|
|
|
location / {
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
```
|
|
|
|
Certificat cree avec:
|
|
|
|
```bash
|
|
certbot certonly --webroot \
|
|
-w /root/tradon/nginx/certbot \
|
|
-d bot.open-squared.tech
|
|
```
|
|
|
|
Le bloc HTTPS `bot.open-squared.tech` doit utiliser:
|
|
|
|
```nginx
|
|
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:
|
|
|
|
```nginx
|
|
proxy_pass http://172.17.0.1:8080;
|
|
```
|
|
|
|
Verifier:
|
|
|
|
```bash
|
|
docker exec nginx nginx -t
|
|
docker exec nginx nginx -s reload
|
|
curl -I https://bot.open-squared.tech/health
|
|
```
|
|
|
|
## PWA Android
|
|
|
|
Nom installe:
|
|
|
|
```text
|
|
OpenSquared
|
|
```
|
|
|
|
Icone:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
f876b3a Add hands-free PWA mode and systemd service
|
|
94e14a3 Add soft French voice and contact saving
|
|
```
|
|
|
|
Checklist VPS:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
openbot start
|
|
openbot stop
|
|
openbot restart
|
|
openbot logs
|
|
systemctl status opensquared-assistant
|
|
journalctl -u opensquared-assistant -f
|
|
```
|
|
|
|
Variables importantes:
|
|
|
|
```text
|
|
TTS_PROVIDER=browser
|
|
CONTACTS_FILE=/root/openbot/data/contacts.json
|
|
MEMORY_DB=/root/openbot/data/memory.sqlite
|
|
```
|
|
|
|
Exemples vocaux:
|
|
|
|
```text
|
|
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.
|