91 lines
5.0 KiB
Bash
Executable File
91 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Agent loop: poll for unread mails periodically and maintain a witness file.
|
|
# Run from repo root. Use a fichier témoin (status) to know if the loop is active.
|
|
#
|
|
# Usage:
|
|
# ./gitea-issues/agent-loop.sh [interval_seconds]
|
|
# AGENT_LOOP_INTERVAL_SEC=120 ./gitea-issues/agent-loop.sh
|
|
#
|
|
# Witness file: projects/<id>/logs/gitea-issues/agent-loop.status (or AGENT_LOOP_STATUS_FILE)
|
|
# Updated every iteration. If mtime is older than 2*interval, consider the loop stopped.
|
|
# Pending file: projects/<id>/logs/gitea-issues/agent-loop.pending (or AGENT_LOOP_PENDING_FILE)
|
|
# Written when unread mails exist; contains timestamp and mail list. Clear after agent run.
|
|
#
|
|
# Optional: set AGENT_LOOP_RUN_AGENT=1 to run the Cursor Agent CLI when mails are detected.
|
|
# Requires Cursor Agent CLI (https://cursor.com/docs/cli/using). If "agent" is not in PATH, the loop only updates status/pending.
|
|
#
|
|
# Optional: AGENT_LOOP_MODEL=<model> to force the model (e.g. sonnet-4.6, gpt-5.4-low). Default: sonnet-4.6 to avoid Opus usage limits when running unattended.
|
|
#
|
|
set -euo pipefail
|
|
# Source user env so PATH includes ~/.local/bin (Cursor Agent CLI, etc.)
|
|
if [ -n "${HOME:-}" ] && [ -r "$HOME/.bashrc" ]; then
|
|
set +u
|
|
# shellcheck source=/dev/null
|
|
source "$HOME/.bashrc" 2>/dev/null || true
|
|
set -u
|
|
fi
|
|
[ -n "${HOME:-}" ] && [ -d "$HOME/.local/bin" ] && export PATH="$HOME/.local/bin:$PATH"
|
|
|
|
GITEA_ISSUES_DIR="${GITEA_ISSUES_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
ROOT="$(cd "${GITEA_ISSUES_DIR}/../.." && pwd)"
|
|
export GITEA_ISSUES_DIR
|
|
export REPO_ROOT="${ROOT}"
|
|
cd "$ROOT"
|
|
# Per-project logs under projects/<id>/logs (lib.sh sets PROJECT_LOGS_DIR)
|
|
# shellcheck source=lib.sh
|
|
source "${GITEA_ISSUES_DIR}/lib.sh" 2>/dev/null || true
|
|
LOGS_GITEA="${PROJECT_LOGS_DIR:-$ROOT/logs}/gitea-issues"
|
|
|
|
# Load agent-loop parameters from .secrets (optional; .secrets under ia_dev)
|
|
AGENT_LOOP_ENV="${GITEA_ISSUES_DIR}/../.secrets/gitea-issues/agent-loop.env"
|
|
if [ -r "$AGENT_LOOP_ENV" ]; then
|
|
set +u
|
|
# shellcheck source=/dev/null
|
|
source "$AGENT_LOOP_ENV"
|
|
set -u
|
|
fi
|
|
|
|
INTERVAL="${1:-${AGENT_LOOP_INTERVAL_SEC:-60}}"
|
|
STATUS_FILE="${AGENT_LOOP_STATUS_FILE:-$LOGS_GITEA/agent-loop.status}"
|
|
PENDING_FILE="${AGENT_LOOP_PENDING_FILE:-$LOGS_GITEA/agent-loop.pending}"
|
|
mkdir -p "$(dirname "$STATUS_FILE")"
|
|
|
|
write_status() {
|
|
local status="$1"
|
|
local detail="${2:-}"
|
|
printf "%s\n%s\n%s\n" "$(date -Iseconds)" "$status" "$detail" > "$STATUS_FILE"
|
|
}
|
|
|
|
while true; do
|
|
write_status "running" "interval=${INTERVAL}s"
|
|
out=""
|
|
if out=$("${GITEA_ISSUES_DIR}/mail-list-unread.sh" 2>&1); then
|
|
if echo "$out" | grep -q "UID="; then
|
|
write_status "mails_pending" "Des mails non lus. Lancer l'agent gitea-issues-process dans Cursor."
|
|
printf "%s\n%s\n%s\n%s\n" "$(date -Iseconds)" "mails_pending" "---" "$out" > "$PENDING_FILE"
|
|
echo "[agent-loop] $(date -Iseconds) — Mails non lus détectés. Lancer l'agent gitea-issues-process dans Cursor."
|
|
if [ "${AGENT_LOOP_RUN_AGENT:-0}" = "1" ] && command -v agent >/dev/null 2>&1; then
|
|
write_status "running_agent" "Lancement de l'agent Cursor pour traiter les mails."
|
|
echo "[agent-loop] $(date -Iseconds) — Lancement de l'agent Cursor (workflow gitea-issues-process mails)."
|
|
AGENT_MODEL="${AGENT_LOOP_MODEL:-sonnet-4.6}"
|
|
echo "[agent-loop] $(date -Iseconds) — Modèle: $AGENT_MODEL"
|
|
AGENT_OPTS=(-p "Exécute le workflow mails entrants de l'agent gitea-issues-process : les mails non lus viennent d'être détectés. 1) Pour chaque mail listé (voir contenu dans logs/gitea-issues/agent-loop.pending) : exécuter ./gitea-issues/mail-get-thread.sh <uid>, puis ./gitea-issues/mail-thread-log.sh init --uid <uid>, conserver THREAD_ID. 2) Pour chaque mail : rédiger une réponse NOUVELLE (non technique, didactique, contexte LeCoffre.io ; pour bug demander l'environnement, pour évolution considérer test). IMPORTANT : le --body de mail-send-reply.sh doit être du texte COMPOSÉ PAR TOI, jamais une copie ou citation d'un message du fil. Ne jamais renvoyer le contenu d'un message précédent (ex. réponse antérieure de ai.support). Envoyer avec ./gitea-issues/mail-send-reply.sh --to <adresse_From_du_mail_utilisateur> --subject \"Re: ...\" --body \"<ta_réponse>\", puis ./gitea-issues/mail-thread-log.sh append-sent, puis ./gitea-issues/mail-mark-read.sh <uid>. 3) Uniquement branche test, ne pas modifier les agents ni scripts d'agents. Répondre à tous les mails avant de marquer comme lu." -f --model "$AGENT_MODEL")
|
|
if agent "${AGENT_OPTS[@]}" 2>&1; then
|
|
write_status "agent_done" "Agent terminé."
|
|
else
|
|
write_status "mails_pending" "Agent terminé avec erreur ou interruption. Relancer l'agent manuellement si besoin."
|
|
fi
|
|
fi
|
|
else
|
|
write_status "idle" "Aucun mail non lu."
|
|
if [ -f "$PENDING_FILE" ]; then
|
|
: > "$PENDING_FILE"
|
|
fi
|
|
fi
|
|
else
|
|
write_status "error" "mail-list-unread a échoué"
|
|
echo "[agent-loop] $(date -Iseconds) — Erreur mail-list-unread" >&2
|
|
fi
|
|
sleep "$INTERVAL"
|
|
done
|