Communitygithub.com

clankercode/agent-file-chat

Deux compétences d'agent réutilisables (simple-agent-comms, simple-agent-room) + outils CLI Python pour la messagerie inter-agents sur disque. Salles en JSON-Lines, moniteurs pilotés par inotify, sans dépendance à un broker. L'agent n'a jamais besoin de connaître les chemins de fichiers.

Qu'est-ce que agent-file-chat ?

Cette compétence fournit un système de chat simple et robuste pour la communication entre agents, basé sur des fichiers sur disque. Elle se compose de deux parties : `simple-agent-room` pour les discussions multipartites (plusieurs agents) et `simple-agent-comms` pour les communications en tête-à-tête avec un sous-agent durable. Le cœur du système repose sur des fichiers JSON-Lines stockés dans `~/.cache/simple-agent-room/`, chaque message étant une ligne JSON atomiquement ajoutée au fichier via O_APPEND, ce qui garantit l'intégrité même en cas d'écritures concurrentes. La surveillance des nouvelles arrivées est assurée par `pyinotify`, un mécanisme événementiel noyau qui élimine tout besoin de scrutation (polling), avec une latence inférieure à la milliseconde. L'interface est volontairement minimaliste : trois commandes (`simple-room-send`, `simple-room-monitor`, `simple-room-scan`) suffisent pour poster, surveiller et analyser les messages, sans jamais exposer les chemins de fichiers à l'agent. Cette compétence est idéale pour orchestrer des équipes d'agents travaillant sur des tâches complexes, permettant le partage de découvertes intermédiaires, la coordination de plans multi-étapes, ou la découverte d'agents durables. Le design sans broker et orienté fichier la rend particulièrement adaptée aux environnements locaux, aux tests, et aux déploiements où la simplicité et la fiabilité priment sur la scalabilité horizontale.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add clankercode/agent-file-chat

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Simple agent room

Quand l'utiliser

Une room est un journal de chat multipartite. N'importe quel nombre d'agents peut poster dans une room, et n'importe quel agent peut la Monitor (surveiller). Utilisations typiques :

  • Plusieurs sous-agents travaillant sur des tâches connexes et ayant besoin de partager des résultats intermédiaires (un codeur signalant un bug d'analyseur, un chercheur rapportant une URL, un testeur signalant une assertion échouée).
  • Un agent durable qui doit être découvrable par d'autres agents pouvant apparaître plus tard.
  • Un canal de coordination pour une "équipe d'agents" exécutant un plan en plusieurs étapes.

Pour les communications en tête-à-tête avec un seul sous-agent durable, la compétence sœur simple-agent-comms (deux fichiers + un moniteur) est plus légère.

Ce que vous (l'agent) devez savoir

Trois commandes, toutes sur le $PATH. Vous n'avez pas besoin de connaître les chemins de fichiers. Le nom de la room est la seule chose que vous manipulez.

simple-room-send    <room> [args]    # poster un message
simple-room-monitor <room> [args]    # diffuser les nouveaux messages (compatible Monitor)
simple-room-scan    <room> <subcmd>  # compter / tail / actifs / grep / ids / chemin

C'est tout. Vous choisissez un nom de room (alphanumérique, point, underscore, tiret ; max 64 caractères), vous choisissez un identifiant d'agent pour vous-même, et vous envoyez / lisez.

Si le reste du système a besoin de savoir où la room est stockée, l'emplacement canonique unique est ~/.cache/simple-agent-room/<room>.log, surmontable via $SIMPLE_AGENT_ROOM_DIR (rare — uniquement pour les tests ou les configurations multi-locataires).

Démarrage rapide (un agent, une ligne)

simple-room-send kitchen "la cuisinière est allumée"  # vous avez posté un message
simple-room-scan  kitchen tail -n 5                    # vous avez lu les 5 derniers
simple-room-scan  kitchen active --window 60           # qui est ici

Démarrage rapide (deux agents en coordination)

# agent A                                            # agent B
simple-room-send tasks -m "Je commence"               \
                                                      simple-room-monitor tasks   # dans un Monitor :
                                                                       ▲           #   les nouvelles lignes arrivent,
                                                                       │           #   les messages de soi-même sont filtrés
# --- plus tard, dans un autre terminal/tour ---     simple-room-send tasks -m "accusé réception"

Le bon schéma : lancer le moniteur comme une commande d'arrière-plan persistante dans un appel d'outil Monitor(...), puis envoyer / analyser / parler au premier plan.

Diagrammes ASCII

Poster un message

       agent                       simple-room-send              sur le disque
       ─────                       ────────────────              ───────────
  $ simple-room-send kitchen \         │
        -a alice -m "salut"           │  format_record
                                     │  → ligne JSON + '\n'
                                     │  → os.open(O_APPEND|O_CREAT, 0o644)
                                     │  → os.write(fd, ligne)
                                     ▼
                          ~/.cache/simple-agent-room/kitchen.log
                          ─────────────────────────────────────────
                          {"id":"…","ts":"…","agent":"alice", … }
                          {"id":"…","ts":"…","agent":"bob",   … }
                          …

Les posteurs concurrents ne déchirent pas leurs enregistrements : les écritures O_APPEND sont atomiques sur POSIX pour les tampons ≤ PIPE_BUF (4096 octets), et l'enregistrement JSON fait toujours moins de 1 Ko en pratique.

Surveillance (la forme Monitor(...))

       simple-room-monitor                  Outil Monitor
       ───────────────────                  ─────────────
  backfill : lire les N derniers enregistrements   stdout
             (ou 0 pour "live uniquement")             │
             analyser JSON, ignorer soi-même    ──────►│  chaque ligne est un
                                                        │  événement d'arrière-plan,
  live :   pyinotify.watch sur le fichier               │  pas une réponse utilisateur
           IN_MODIFY  ─► lire les nouveaux octets
           IN_DELETE  ─► attendre la recréation
           IN_MOVE    ─► attendre la recréation
                                                        ▼
                                                  l'agent lit la ligne,
                                                  décide quoi faire

Le script ne scrute pas. Il bloque dans pyinotify.Notifier et se réveille sur les événements du noyau. La latence entre l'envoi et la livraison de l'événement est inférieure à la milliseconde sur les systèmes de fichiers locaux.

Analyse (lecture seule)

       simple-room-scan <room> <subcmd> [args]
       ────────────────────────────────────────
              │
              ├─ count                 → 1 ligne : nombre total d'enregistrements
              ├─ ids                   → 1 id par ligne (trié)
              ├─ path                  → 1 ligne : chemin absolu du fichier
              ├─ active  [--window S]  → "agent<TAB>ts" par agent actif
              ├─ tail    [-n N] [-a A] → N derniers (ou d'un agent) enregistrements
              └─ grep    <pattern>     → enregistrements dont msg correspond
                       [--since-seq N]
                       [-a A] [--json]
              │
              ▼
       iter_records(chemin) → flux de dictionnaires
       (ignore les lignes vides / '#' / malformées)

Référence

simple-room-send <room> [-m MSG] [-k {msg,system,meta}] [-a AGENT] [--stdin]

drapeausignification
-m MESSAGEle texte du message (sinon lire stdin)
--stdinforcer la lecture depuis stdin (remplace -m)
-k KINDmsg (défaut), system, ou meta
-a AGENTidentifiant de l'agent local ; défaut $SIMPLE_AGENT_ID sinon $USER-<host>-<pid>
--seq Nséquence monotone explicite (optionnel)
--id IDidentifiant d'enregistrement explicite (uuid4 hex, optionnel)
--ts ISOhorodatage explicite (optionnel)
-qsupprimer la confirmation "envoyé id=…" sur stderr

Le message est stocké textuellement (les sauts de ligne, tabulations, barres obliques inverses sont échappés JSON à l'intérieur de l'enregistrement ; vous les voyez du côté lecture comme des caractères normaux).

simple-room-monitor <room> [-a AGENT] [--exclude-self] [--backfill N] [--grep PATTERN] [--json]

drapeausignification
-a AGENTidentifiant de l'agent local (défaut comme ci-dessus)
--exclude-selfignorer les enregistrements de l'agent local (défaut : activé)
--no-exclude-selfles inclure (utilisez-le quand vous voulez voir vos propres messages)
-b Némettre les N derniers enregistrements existants avant de passer en direct
(-1 = tous ; 0 = événements uniquement, le défaut)
--grep PATTERNn'émettre que les enregistrements dont la ligne rendue correspond à l'expression régulière
--jsonémettre l'enregistrement JSON brut par ligne (sinon HH:MM:SS agent: msg)

Le script tourne jusqu'à être tué. Utilisez-le comme command d'un appel d'outil Monitor(...) persistant — le bon schéma est un moniteur par room par session. Les événements du moniteur sont des événements d'arrière-plan, pas des réponses utilisateur ; ne les traitez pas comme un message utilisateur qui termine un tour.

simple-room-scan <room> <subcommand> [args]

sous-commandeargssortie
count—nombre total d'enregistrements
ids—un identifiant d'agent par ligne
path—chemin absolu du fichier
active--window SECONDS (120)agent<TAB>ts par agent actif
tail-n N (20), -a AGENT, --jsonN derniers enregistrements
grepPATTERN, --since-seq N, -a A, --json, -c (count→stderr)enregistrements correspondants

grep est sensible à la casse et utilise la syntaxe des expressions régulières Python (qui est proche de PCRE pour les cas courants — ., *, +, ?, \b, classes de caractères).

Le motif d'auto-filtrage (la recette "ne pas se parler à soi-même")

Le moniteur utilise par défaut --exclude-self car dans une boucle de tour d'agent unique, l'agent vient d'envoyer son propre message, et le rejouer comme événement est du bruit. Si vous avez besoin des deux côtés d'une session de débogage à agent unique visible, passez --no-exclude-self.

Deux agents dans la même room doivent choisir des identifiants d'agent différents. La valeur par défaut ($USER-<host>-<pid>) est unique par processus ; si vous lancez plusieurs agents depuis le même shell, définissez SIMPLE_AGENT_ID pour chacun afin de les distinguer.

Ce que vous n'avez pas besoin de savoir

  • Le chemin sur le disque. Il est ~/.cache/simple-agent-room/<room>.log. Vous n'écrivez jamais directement dedans. simple-room-scan <room> path vous le dira si vous êtes curieux.
  • Le schéma. La bibliothèque lit le fichier, analyse le JSON, ignore les lignes malformées et déséchappe les chaînes msg. Vous voyez un dictionnaire avec id, ts, agent, msg, kind, seq optionnel.
  • La scrutation. Le moniteur est entièrement piloté par événements (inotify).
  • Le verrouillage. Les enregistrements font < 4 Ko, O_APPEND est atomique sur POSIX, donc aucun flock / fcntl n'est nécessaire. Deux rédacteurs peuvent poster simultanément sans déchirer leurs enregistrements.

Modes de défaillance à connaître

  • inotify obsolète après suppression/renommage : la bibliothèque rattache la surveillance sur IN_CREATE pour le même chemin, donc un outil de rotation de logs qui remplace le fichier est géré. Si vous rm le fichier manuellement, le moniteur créera un nouveau fichier vide à l'envoi suivant.
  • Collision d'identifiant d'agent : deux agents avec le même identifiant verront les messages de l'autre comme les leurs (et les filtreront par défaut). Utilisez toujours SIMPLE_AGENT_ID ou la valeur par défaut $USER-<host>-<pid>.
  • Décalage d'horloge : ts est l'heure UTC de l'horloge murale de l'expéditeur. Si vous triez par ts entre agents, réglez NTP. Pour l'ordre au sein d'un seul agent, utilisez seq.
  • Messages très longs : il n'y a pas de limite stricte, mais si vous postez régulièrement > 4 Ko, vous pourriez atteindre PIPE_BUF et commencer à voir des enregistrements déchirés. Gardez les messages < 4 Ko.
  • Lignes malformées : le lecteur ignore silencieusement toute ligne qui ne s'analyse pas comme un objet JSON. Déchets entrants = déchets silencieusement ignorés ; les enregistrements valides autour ne sont pas affectés.

Fichiers

skills/simple-agent-room/
  SKILL.md                       ← ce fichier
  bin/
    simple-room-send             ← wrapper léger, appelle lib.simple_room_send.main
    simple-room-monitor          ← wrapper léger, appelle lib.simple_room_monitor.main
    simple-room-scan             ← wrapper léger, appelle lib.simple_room_scan.main
  lib/
    simple_agent_room_lib.py     ← bibliothèque partagée (format/analyse, inotify, scan)
    simple_room_send.py          ← point d'entrée d'envoi
    simple_room_monitor.py       ← point d'entrée de moniteur
    simple_room_scan.py          ← point d'entrée d'analyse

Chaque wrapper bin/simple-room-* est un fichier Python de 12 lignes qui ajuste sys.path et délègue à lib/simple_room_*.main. Les wrappers résolvent leur propre chemin réel, donc les liens symboliques dans ~/.local/bin/ fonctionnent de manière transparente.

Installation

Depuis la racine du dépôt :

./install.sh

Cela place simple-agent-room dans ~/.claude/skills/ et ~/.agents/skills/, et les trois CLI sur votre $PATH en tant que simple-room-send, simple-room-monitor, simple-room-scan.

Si vous préférez le faire manuellement :

ln -s "$PWD/skills/simple-agent-room"                    ~/.claude/skills/simple-agent-room
ln -s "$PWD/skills/simple-agent-room"                    ~/.agents/skills/simple-agent-room
ln -s "$PWD/skills/simple-agent-room/bin/"*             ~/.local/bin/

Dépendances

  • Python ≥ 3.10
  • pyinotify (pip install pyinotify). Requis uniquement par le moniteur ; simple-room-send et simple-room-scan fonctionnent sans.

Skills associés