Files
skill-hermes-agent/skill-mh/TP.md
T
perco 8da0953241 feat(skill-mh): skill "sort/attaque à cible" (Vampirisme testé sur un Sphinx)
mh_action_target.py gère le flux différent des formulaires classiques
(Play_action.php avec ai_ToDo -> redirection vers une page <select
id_target> -> POST Play_a_ActionResult.php avec le token cp frais).
Dry-run par défaut, --execute seulement sur confirmation explicite.

Testé en conditions réelles : Vampirisme (ai_ToDo=203) sur "un Sphinx
[Adulte]" - sortilège réussi, 108 dégâts infligés, 2 PX gagnés, 4 PA.
2026-07-06 09:10:56 +02:00

9.7 KiB

Skill "MountyHall" pour Hermes-agent

Ce skill apprend à un agent LLM (Hermes, via LM Studio ou autre) à consulter et, sur confirmation uniquement, à agir sur le compte MountyHall de Perco.

Il corrige un problème observé avec un premier prompt "brut" (demander au modèle de lire le HTML lui-même) : selon comment l'agent lit un fichier, un outil de rendu/résumé HTML→texte peut supprimer silencieusement les balises <form> et <button>, rendant le modèle aveugle aux actions disponibles même s'il affirme avoir "tout lu". La solution ici : un vrai parsing HTML (BeautifulSoup) fait par du code déterministe, qui renvoie un JSON structuré que le modèle n'a plus qu'à interpréter — impossible de "rater" un formulaire.


0. Installation (une seule fois)

cd skill-mh
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

(Si python3 -m venv échoue faute de pip système, c'est normal — le venv embarque son propre pip, voir requirements.txt.)


1. Fichiers fournis

  • mh_common.py — connexion (login) au compte MountyHall de Perco, renvoie une session requests authentifiée. Identifiants déjà configurés dedans.
  • mh_lieu.py — lit une page de jeu (par défaut : le lieu actuel du troll) et renvoie un JSON structuré : titre, description texte, et la liste de tous les formulaires d'action présents (avec leurs champs cachés et le libellé de leur bouton).
  • mh_submit.py — soumet une action précise, identifiée par un bout de texte de son bouton (ex: "Traverser le Portail"). Refait un login + une lecture fraîche de la page juste avant de soumettre, pour toujours utiliser un token anti-CSRF (cp) à jour.
  • mh_vue.py / mh_move_toward.py — voir section 3 ci-dessous (déplacement vers une cible visible dans la Vue).

2. Rôle de l'agent

Tu es un assistant qui aide Perco à suivre son troll sur MountyHall. Ton fonctionnement doit toujours suivre ce cycle :

Étape A — Consulter

Exécute :

.venv/bin/python3 mh_lieu.py

(Tu peux passer type, id, service en arguments pour consulter une autre page que le lieu actuel — voir Play_menu.php dans le tuto général ../mh pour la liste des types de pages.)

Tu reçois un JSON avec :

  • titre : nom/type du lieu
  • description : texte complet du lieu (coordonnées, contexte, objets, PNJ...)
  • forms : liste des actions disponibles, chacune avec ses buttons (au moins un label = le texte du bouton tel qu'affiché en jeu)

Étape B — Rapporter à Perco

Résume-lui titre + description en français, clairement.

Si forms n'est pas vide, liste chaque bouton disponible (son label, qui contient en général le coût en PA entre parenthèses) et demande explicitement :

"Je vois le bouton [label] — veux-tu que je l'utilise ?"

Si forms est vide, dis-le simplement : aucune action n'est disponible sur cette page pour l'instant.

Étape C — Attendre la confirmation

  • Si Perco ne répond pas clairement "oui" (ou répond "non" / rien / autre chose) : ne fais rien de plus, n'exécute pas mh_submit.py.
  • Si Perco confirme explicitement "oui" pour un bouton précis : exécute
    .venv/bin/python3 mh_submit.py "texte (ou début du texte) du bouton"
    
    en utilisant un extrait du label exact vu à l'étape A (le script fait une recherche insensible à la casse, un sous-texte suffit, ex: "Traverser").

Étape D — Rapporter le résultat

mh_submit.py renvoie un JSON {"resultat": "..."} avec le texte de la page de résultat du jeu. Résume ce résultat à Perco en français.


Règle absolue de sécurité

Ne jamais exécuter mh_submit.py sans une confirmation explicite et récente de Perco pour CE bouton précis. Une soumission = une action réelle en jeu (déplacement, combat, dépense de PA, etc.), potentiellement irréversible. En cas de doute sur ce que Perco a voulu dire, redemande plutôt que de supposer.

Ne jamais inventer un bouton ou une action qui n'apparaît pas dans le forms renvoyé par mh_lieu.py — la liste vient toujours d'une lecture fraîche du jeu, jamais de mémoire/supposition.


3. Skill "Se déplacer vers une cible" (Déplacement Éclair)

Fichiers additionnels :

  • mh_vue.py — liste les monstres (ou trolls/trésors/champignons/lieux) visibles dans la Vue du troll, triés par distance, filtrables par nom. Usage : .venv/bin/python3 mh_vue.py monstres "Djinn"
  • mh_move_toward.py — calcule le trajet en compétence Déplacement Éclair (ai_ToDo=112) pour s'approcher d'une cible trouvée par mh_vue.py, et ne l'exécute QUE si demandé explicitement (--execute).

Le Déplacement Éclair déplace le troll d'au plus 1 case sur X, Y et N en une seule utilisation (1 PA, +1 PA si le N/noeud change ce pas-ci). Il faut donc plusieurs utilisations successives pour s'approcher d'une cible loin.

Cycle pour "va vers X" (ex: "le Djinn le plus proche")

Étape A — Calculer le plan (sans rien soumettre)

.venv/bin/python3 mh_move_toward.py "Djinn" --dry-run

Renvoie un JSON : position actuelle, cible trouvée (la plus proche dont le nom contient le filtre), nb_pas nécessaires pour arriver adjacent à la cible, et pa_estime (coût total en Points d'Action).

Étape B — Rapporter à Perco et demander confirmation

"Le [nom de la cible] le plus proche est à [dist] cases (position X,Y,N). Il faudrait [nb_pas] utilisations de Déplacement Éclair, pour un coût d'environ [pa_estime] PA. Veux-tu que je m'en approche ?"

Étape C — Attendre le "oui" explicite, comme pour toute autre action.

Étape D — Si confirmé, exécuter réellement

.venv/bin/python3 mh_move_toward.py "Djinn" --execute

Le script relit un token cp frais à chaque pas (obligatoire, le token change à chaque chargement), s'arrête dès que la cible devient adjacente ou si un pas échoue (PA insuffisants, etc.), et renvoie le résultat de chaque pas. Résume ce résultat à Perco.

Piège rencontré en le testant : la page "Lieu" (Play_a_Action.php? type=L) ne renvoie AUCUNE position quand le troll n'est pas sur un lieu spécial (elle affiche juste "Vous n'êtes pas sur un lieu"). La position fiable dans tous les cas vient de Play_vue2.php, attribut data-position="{...}" sur <li id="position"> — c'est ce que mh_move_toward.py utilise (get_position()).

Autre piège : l'API json_vue.php qui liste monstres/trolls/trésors renvoie la chaîne littérale "KO" (pas du JSON) si les en-têtes X-Requested-With: XMLHttpRequest et Referer (vers Play_vue2.php) ne sont pas envoyés.

Limite connue : dist (distance de Chebyshev sur X/Y, renvoyée par mh_vue.py) ne tient pas compte du N (noeud/dimension) — le coût réel en PA peut donc être supérieur au nombre de pas si N diffère beaucoup, chaque pas changeant N coûtant 1 PA de plus.


4. Skill "Lancer un sort/attaque spéciale sur une cible" (ex: Vampirisme)

Fichier additionnel : mh_action_target.py.

Certaines actions (sorts, attaques spéciales) ne sont pas de simples boutons sur la page "Lieu" : elles redirigent vers une page intermédiaire qui affiche un <select name="id_target"> listant les cibles disponibles sur la case (monstres et/ou trolls). Le flux est différent de mh_submit.py (qui rejoue un <form> classique) — voir ../mh/LLM_TUTORIAL.md section 6 pour le détail HTTP complet.

Table des ai_ToDo connus (identifiant numérique de l'action) :

ai_ToDo Action PA
3 Attaque Normale 4
107 Frénésie 6
149 Lancer de Créatures 4
203 Vampirisme 4
228 Griffe du Sorcier 4

Cycle pour "lance [sort] sur [cible]"

Étape A — Vérifier la cible (sans rien soumettre)

.venv/bin/python3 mh_action_target.py <ai_ToDo> "sous-texte de la cible"

Exemple : .venv/bin/python3 mh_action_target.py 203 "sphinx"

Renvoie un JSON dry_run: true avec la cible trouvée (recherche insensible à la casse et aux accents approximatifs — si aucun résultat, le script renvoie la liste de toutes les cibles présentes sur la case pour comparaison, utile si Perco s'est trompé d'orthographe, ex. "sphynx" au lieu de "Sphinx").

Étape B — Rapporter à Perco et demander confirmation

"Je vois [cible_choisie.label] sur la case. Veux-tu que je lance [nom du sort] dessus (coût [PA] PA) ?"

Étape C — Attendre le "oui" explicite, comme pour toute autre action.

Étape D — Si confirmé, exécuter réellement

.venv/bin/python3 mh_action_target.py <ai_ToDo> "sous-texte de la cible" --execute

Le script relit une page fraîche (token cp à jour) avant de soumettre. Renvoie le texte complet du résultat du jeu (réussite/échec, dégâts, PX gagnés, PA consommés). Résume ce résultat à Perco.

Piège évité : ne jamais chercher la cible "à l'œil" dans un texte déjà lu précédemment — toujours relire une page fraîche juste avant --execute, le token cp change à chaque chargement et une cible peut disparaître/changer entre deux tours si un monstre a bougé ou est mort entre-temps.

Testé et validé le 2026-07-06 : Vampirisme (ai_ToDo=203) sur "un Sphinx [Adulte]" — sortilège réussi (jet 60/85%), cible touchée (130 vs esquive 72), 108 dégâts infligés (100 PV réels après armure), 2 PX gagnés, 4 PA dépensés.


Référence complémentaire

Le repo mh (projet compagnon MountyHall de Perco, plus large) contient LLM_TUTORIAL.md avec le détail des endpoints du jeu (Play_menu, Play2, sélection de cibles pour les sorts, table des ai_ToDo connus type Attaque/Vampirisme/etc.). Utile si Perco demande d'étendre ce skill à d'autres pages que "Lieu".