7.6 KiB
Boucle agent (agent-loop) – surveillance des mails et fichier témoin
Script qui tourne en boucle dans l’environnement Cursor de ce projet pour surveiller les mails non lus et maintenir un fichier témoin indiquant si la boucle est active.
Rôle du script
- Exécuter périodiquement
mail-list-unread.sh(sans modifier l’état des mails). - Mettre à jour à chaque tour un fichier témoin (statut + horodatage) pour savoir si la boucle est active.
- Quand des mails non lus sont détectés, écrire un fichier pending et afficher un message invitant à lancer l’agent dans Cursor.
Le script ne traite pas les mails lui‑même : le traitement (réponse, issues, commits) est fait par l’agent gitea-issues-process. Vous pouvez soit lancer l’agent à la main dans Cursor, soit faire lancer l’agent par la boucle en activant AGENT_LOOP_RUN_AGENT=1 (voir ci‑dessous) si la Cursor Agent CLI est installée.
Environnement au démarrage
Au démarrage, le script source systématiquement ~/.bashrc (si le fichier existe et est lisible), puis ajoute ~/.local/bin au PATH si ce répertoire existe. Ainsi, la commande agent (Cursor Agent CLI) est trouvée même si la boucle est lancée depuis un contexte où le shell n’a pas chargé le profil (nohup, cron, etc.).
Lancement
Si le fichier .secrets/gitea-issues/agent-loop.env existe, il est sourcé au démarrage (voir agent-loop.env.example).
Depuis la racine du dépôt :
./gitea-issues/agent-loop.sh
Avec un intervalle en secondes (défaut 60) :
./gitea-issues/agent-loop.sh 120
Ou via une variable d’environnement :
AGENT_LOOP_INTERVAL_SEC=120 ./gitea-issues/agent-loop.sh
Pour l’exécuter en arrière-plan et garder la boucle active après fermeture du terminal, utiliser nohup ou un gestionnaire de processus (systemd, screen, tmux) :
nohup ./gitea-issues/agent-loop.sh 60 >> logs/gitea-issues/agent-loop.log 2>&1 &
Fichier témoin (actif / inactif)
- Emplacement :
logs/gitea-issues/agent-loop.status(ouAGENT_LOOP_STATUS_FILEsi défini). - Contenu : trois lignes
- Horodatage ISO 8601 du dernier tour.
- Statut :
idle|mails_pending|running|error. - Détail optionnel (ex. message pour l’utilisateur).
Considérer la boucle comme active si le fichier a été modifié depuis moins de 2 × intervalle (ex. moins de 120 s si intervalle = 60 s). Au-delà, la boucle est considérée arrêtée.
Exemple de vérification (intervalle 60 s) :
# Fichier modifié il y a moins de 120 s ?
[ $(($(date +%s) - $(stat -c %Y logs/gitea-issues/agent-loop.status 2>/dev/null || 0))) -lt 120 ] && echo "Actif" || echo "Inactif"
Ou simplement consulter la première ligne du fichier (date du dernier tour) et la comparer à l’heure courante.
Fichier pending (mails en attente)
- Emplacement :
logs/gitea-issues/agent-loop.pending. - Rôle : quand des mails non lus sont détectés, le script y écrit un bloc (horodatage, statut
mails_pending, puis la sortie demail-list-unread.sh). Permet de voir quels mails attendent un traitement par l’agent. - Quand il n’y a plus de non lus, le script vide ce fichier au tour suivant.
Variables d’environnement
Variables possibles dans .secrets/gitea-issues/agent-loop.env ou en export shell :
| Variable | Défaut | Description |
|---|---|---|
AGENT_LOOP_INTERVAL_SEC |
60 | Intervalle entre deux vérifications (secondes). Peut aussi être passé en premier argument au script. |
AGENT_LOOP_RUN_AGENT |
0 | Si mis à 1, la boucle lance la Cursor Agent CLI (agent) quand des mails non lus sont détectés, avec un prompt qui exécute le workflow mails de gitea-issues-process. Nécessite que la commande agent soit installée (voir Cursor CLI). Si agent n’est pas dans le PATH, la boucle se contente de mettre à jour le statut et le fichier pending. |
AGENT_LOOP_MODEL |
sonnet-4.6 |
Modèle utilisé par la CLI (agent --model ...). Par défaut sonnet-4.6 pour limiter les blocages liés aux quotas Opus. Ex. : AGENT_LOOP_MODEL=gpt-5.4-low ; liste : agent models. |
AGENT_LOOP_STATUS_FILE |
logs/gitea-issues/agent-loop.status |
Chemin du fichier témoin. |
AGENT_LOOP_PENDING_FILE |
logs/gitea-issues/agent-loop.pending |
Chemin du fichier pending. |
GITEA_ISSUES_DIR |
répertoire du script | Racine des scripts gitea-issues (pour appeler mail-list-unread.sh). |
Traiter les mails
Dès que le statut est mails_pending ou que des mails apparaissent dans agent-loop.pending :
- Option A (manuel) : ouvrir le projet dans Cursor, lancer l’agent gitea-issues-process (commande
/gitea-issues-processou via l’interface des agents). - Option B (automatique) : lancer la boucle avec
AGENT_LOOP_RUN_AGENT=1et la Cursor Agent CLI installée (agentdans le PATH). Lorsque des mails non lus sont détectés, le script invoqueagent -p "..." -fpour exécuter le workflow mails (fil, log, réponse, marquage lu). Voir Cursor CLI pour l’installation.
L’agent lit les non lus, consulte les fils, répond par mail, crée des issues si besoin, et marque les mails comme lus.
Après passage de l’agent, au prochain tour de la boucle le statut repassera à idle et le fichier pending sera vidé (s’il n’y a plus de non lus).
Logs
Le script n’écrit pas de log structuré par défaut. Pour garder une trace des tours et des messages affichés :
./gitea-issues/agent-loop.sh 60 2>&1 | tee -a logs/gitea-issues/agent-loop.log
Ou en arrière-plan :
nohup ./gitea-issues/agent-loop.sh 60 >> logs/gitea-issues/agent-loop.log 2>&1 &
Arrêter la boucle
- Si le script est en premier plan :
Ctrl+C. - Si lancé en arrière-plan :
kill <pid>(oupkill -f agent-loop.sh).
Après arrêt, le fichier témoin ne sera plus mis à jour ; après 2 × intervalle, il doit être considéré comme inactif.
Boucle limitée depuis le chat (sans API payante)
Pour lancer depuis ce chat (instance Cursor ouverte, abonnement Ultra) une boucle limitée : récupération des mails → attente 1 min → récupération → … sans consommer de crédits API ni lancer la CLI agent :
- Demander dans le chat : « Lance la boucle récupération emails : subagent puis attend 1 min et relance, N itérations » (ou similaire).
- L’agent exécute
cd /home/desk/code/lecoffre_ng_test && ./ia_dev/gitea-issues/agent-loop-chat-iterations.sh [N]depuis la racine du dépôt projet. Par défaut N=3 ; pour 300 itérations, lancer en terminal (tmux/screen) depuis la même racine. - Au lancement, le script envoie un mail de test à nicolas.cantu@pm.me pour vérifier SMTP ; si l'envoi échoue, le script s'arrête (code 1).
- Chaque itération exécute
mail-list-unread.shpuis attend 60 secondes. Les mails en attente sont écrits danslogs/gitea-issues/agent-loop.pending; traiter ensuite dans le même chat (workflow gitea-issues-process, voir.cursor/agents/gitea-issues-process.md).
Pourquoi l'envoi pouvait échouer : si le script était invoqué depuis la racine projet avec ROOT = toplevel Git (racine projet), le chemin ./gitea-issues/ n'existait pas (gitea-issues est dans ia_dev). Le script utilise maintenant le répertoire contenant gitea-issues (ia_dev) comme racine et appelle les sous-scripts via GITEA_ISSUES_DIR.
Script : gitea-issues/agent-loop-chat-iterations.sh [N]. Boucle illimitée en terminal : cd <racine_projet> && while true; do ./ia_dev/gitea-issues/mail-list-unread.sh; sleep 60; done.