**Motivations:** - Single config file per project (projects/<id>/conf.json) - Project must not depend on ia_dev; only ia_dev solicits the project **Root causes:** - N/A (evolution) **Correctifs:** - N/A **Evolutions:** - lib/project_config.sh: resolve PROJECT_SLUG from IA_PROJECT, .ia_project, ai_project_id; PROJECT_CONFIG_PATH = projects/<id>/conf.json - projects/lecoffreio.json moved to projects/lecoffreio/conf.json; projects/ia_dev/conf.json added - deploy: branch-align, bump-version, change-to-all-branches, pousse, deploy-by-script-to use PROJECT_ROOT/IA_DEV_ROOT and project_config.sh; SCRIPT_REAL for symlink-safe paths - deploy/_lib: shared colors, env-map, ssh, git-flow - gitea-issues: mail list/mark-read/get-thread/send-reply, thread log, agent-loop, wiki scripts; lib.sh loads project config - README: principle no dependency from host project; invoke ./ia_dev/deploy/bump-version.sh etc. from repo root **Pages affectées:** - README.md, projects/README.md, lib/, deploy/, gitea-issues/, projects/lecoffreio/, projects/ia_dev/
114 lines
6.0 KiB
Markdown
114 lines
6.0 KiB
Markdown
# 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** :
|
||
|
||
```bash
|
||
./gitea-issues/agent-loop.sh
|
||
```
|
||
|
||
Avec un intervalle en secondes (défaut 60) :
|
||
|
||
```bash
|
||
./gitea-issues/agent-loop.sh 120
|
||
```
|
||
|
||
Ou via une variable d’environnement :
|
||
|
||
```bash
|
||
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) :
|
||
|
||
```bash
|
||
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` (ou `AGENT_LOOP_STATUS_FILE` si défini).
|
||
- **Contenu** : trois lignes
|
||
1. Horodatage ISO 8601 du dernier tour.
|
||
2. Statut : `idle` | `mails_pending` | `running` | `error`.
|
||
3. 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) :
|
||
|
||
```bash
|
||
# 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 de `mail-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](https://cursor.com/docs/cli/using)). 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` :
|
||
|
||
1. **Option A (manuel)** : ouvrir le projet dans **Cursor**, lancer l’**agent gitea-issues-process** (commande `/gitea-issues-process` ou via l’interface des agents).
|
||
2. **Option B (automatique)** : lancer la boucle avec `AGENT_LOOP_RUN_AGENT=1` et la **Cursor Agent CLI** installée (`agent` dans le PATH). Lorsque des mails non lus sont détectés, le script invoque `agent -p "..." -f` pour exécuter le workflow mails (fil, log, réponse, marquage lu). Voir [Cursor CLI](https://cursor.com/docs/cli/using) 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 :
|
||
|
||
```bash
|
||
./gitea-issues/agent-loop.sh 60 2>&1 | tee -a logs/gitea-issues/agent-loop.log
|
||
```
|
||
|
||
Ou en arrière-plan :
|
||
|
||
```bash
|
||
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>` (ou `pkill -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.
|