# Outils opérationnels (TOOLS.md) > **Source de vérité skills.** Ce fichier liste les capacités RÉELLEMENT > disponibles pour l'agent. Si une capacité y figure, l'agent PEUT et DOIT > l'utiliser. Si l'utilisateur demande une action documentée ici, l'agent > NE DOIT PAS répondre "je ne peux pas". --- ### 1.0 IMPORTANT — Comment l'agent invoque les commandes gog `gog` n'est PAS un tool natif d'OpenClaw. C'est une commande CLI installée dans le container PATH. L'agent DOIT l'invoquer via le tool natif `exec` (ou son alias `bash`) avec la commande gog complète comme argument. INTERDIT (l'agent essaye d'appeler `gog` comme tool → ÉCHEC garanti) : tool: gog args: { "operation": "send", "to": "...", "subject": "..." } OBLIGATOIRE (l'agent appelle `exec` avec la commande gog complète) : tool: exec args: { "command": "gog gmail send -a tallagrand.thierry@gmail.com --to ... --subject ... --body ..." } Toutes les commandes documentées ci-dessous (sections 1.1 à 1.6) doivent être invoquées via `exec` ou `bash` avec la commande complète comme argument. ### Pattern général pour TOUTE commande CLI dans ce fichier Cette règle s'applique aussi à : `python3`, `curl`, `jq`, `git`, `node`, et tout binaire installé dans le container. Bon réflexe : tool: exec, args: { "command": " " } Mauvais réflexe : tool: , args: { ... } ## 1. Gmail — gog CLI v0.21.0 (OPÉRATIONNEL) **Statut** : ACTIF depuis 9 juin 2026. Auth OAuth Google persistée. **Compte** : tallagrand.thierry@gmail.com **Path keyring** : /home/node/.openclaw/gogcli/data/keyring/ **Doc complète** : workspace/gmail-rules.md ### 1.1 LECTURE | Tâche | Commande | |---|---| | Chercher des threads | gog gmail search "" -a tallagrand.thierry@gmail.com -j --max N | | Lister labels | gog gmail labels list -a tallagrand.thierry@gmail.com | | Détail d'un thread | gog gmail thread get -a tallagrand.thierry@gmail.com -j | | Détail d'un message | gog gmail messages get -a tallagrand.thierry@gmail.com -j | ### 1.2 ENVOI (capacité ACTIVE) Syntaxe : gog gmail send -a tallagrand.thierry@gmail.com --to --subject "" --body "" Flags utiles : - --cc=, --bcc= : copies - --body-html="" : version HTML (alternative à --body) - --attach= : pièce jointe (répétable, ex: graphe PNG) - --reply-to-message-id= : répondre à un mail spécifique - --dry-run : simuler sans envoyer - -j : sortie JSON Exemple concret avec attachement : gog gmail send -a tallagrand.thierry@gmail.com --to tallagrand.thierry@gmail.com --subject "Cours ORA" --body "ORA.PA : 17,86€ (+1,16%)" --attach /home/node/.openclaw/workspace/charts/ora-2026-06-11-1700.png ### 1.3 BROUILLONS (alternative prudente) | Tâche | Commande | |---|---| | Créer un brouillon | gog gmail drafts create -a --to --subject "..." --body "..." | | Lister brouillons | gog gmail drafts list -a | | Envoyer un brouillon | gog gmail drafts send -a | | Supprimer brouillon | gog gmail drafts delete -a | ### 1.4 MUTATIONS — `--dry-run` OBLIGATOIRE avant mass action | Tâche | Commande | |---|---| | Mettre à la corbeille | gog gmail trash "" -a --dry-run puis --force | | Archiver | gog gmail archive "" -a --dry-run puis --force | | Modifier labels | gog gmail messages modify -a --add-label X --remove-label Y | ### 1.5 Mapping question utilisateur → action | Question | Commande à utiliser | |---|---| | "Envoie un mail à X avec sujet Y et corps Z" | gog gmail send --to X --subject "Y" --body "Z" | | "Envoie-moi un mail" | gog gmail send --to tallagrand.thierry@gmail.com ... | | "Combien de mails j'ai aujourd'hui" | gog gmail search "in:inbox newer_than:1d" -j --max 100 | | "Trie mes promos vieilles" | gog gmail trash "category:promotions older_than:30d" --dry-run | | "Liste les mails de X" | gog gmail search "from:X" -j --max N | ### 1.6 Hard constraints Gmail - INTERDIT : "je ne peux pas envoyer un mail" — la capacité EST active - INTERDIT : "Gmail à venir" — c'est OPÉRATIONNEL depuis 9/6/2026 - Si une commande échoue, RAPPORTER l'erreur réelle (stderr) - 2 erreurs syntax/auth max → STOP, demander à l'utilisateur - --dry-run avant action en masse (>5 mails) - Container headless : pas de browser disponible --- ## 2. WhatsApp — Plugin OpenClaw ### 2.1 Capacités confirmées - Envoi message texte vers utilisateur (+33607148216) - Envoi image PNG/JPEG (à valider Phase E.5) - Commande slash /new : nouvelle session DM (testée 10/6 OK) ### 2.2 Format restrictions - AUTORISÉS : PNG, JPEG, WebP, PDF, Office docs, archives - INTERDIT : SVG (rejeté par WhatsApp Cloud API avec OutboundDeliveryError) ### 2.3 Mapping question → action | Question | Action | |---|---| | "Envoie-moi un message WhatsApp" | tool whatsapp send_message | | "Envoie le graphe sur WhatsApp" | tool whatsapp send_message + image PNG attachée | | Cron horaire bourse | delivery.mode=announce → dernière réponse agent envoyée auto | ### 2.4 Hard constraint - Si erreur "OutboundDeliveryError image/svg+xml" : convertir en PNG - Si l'envoi WhatsApp échoue : rapporter l'erreur exacte, ne pas re-tenter en boucle --- ## 3. Bourse — Workflow N8N (REFONTE 2026-06-24) > ⚠️ OBSOLÈTES (ne plus utiliser) : `generate_chart.py`, `get_quote.py`, > `clean_bourse_md.py`, `orange-bourse.md`. Toute la bourse passe par N8N. ### 3.1 Webhook graphe (outil principal) - URL : `https://n8n.airtria.pro/webhook/bourse-graphe` (POST JSON) - Workflow N8N id : `4bluZIeN3TnbzIrv` ("Bourse — Graphe multi-tickers (v3)") - Renvoie : un PNG (image/png) prêt pour WhatsApp - Body JSON (tout optionnel) : - `tickers` : liste de symboles Yahoo, ex ["ORA.PA","TTE.PA","NVDA"] - `range` : 1d|5d|1mo|3mo|6mo|1y (def 5d) - `interval` : 15m|60m|1d (def 60m) - `beginAtZero` : true (axe Y depuis 0) | false (zoom variations) - `title` : titre optionnel - Gestion marché fermé / ticker invalide : renvoie un PNG "Aucune donnée" (jamais d'invention de cours). Exemple : ```bash curl -s -X POST "https://n8n.airtria.pro/webhook/bourse-graphe" \ -H "Content-Type: application/json" \ -d '{"tickers":["ORA.PA","TTE.PA"],"beginAtZero":true}' \ -o /home/node/.openclaw/workspace/charts/bourse.png ``` ### 3.2 Watchlist = bourse-config.json - Path : `/home/node/.openclaw/workspace/bourse-config.json` - Source de vérité des tickers suivis + options par défaut. - L'agent ÉDITE ce fichier pour ajouter/retirer une valeur. ### 3.3 Prix texte rapide (sans graphe) - `curl -fs "https://query1.finance.yahoo.com/v8/finance/chart/SYMBOLE?interval=1d&range=1d" | jq '.chart.result[0].meta'` ### 3.4 Modifier le comportement du graphe - Via MCP `n8n-mcp` (update_workflow) ou l'API n8n, workflow id `4bluZIeN3TnbzIrv`. - Node JS "Fetch + Build QuickChart" = logique fetch+rendu. Rendu via QuickChart `version:"4"`. --- ## 4. Filesystem workspace ### 4.1 Path racine /home/node/.openclaw/workspace/ ### 4.2 Capacités - Lecture/écriture de tout fichier dans workspace - Exec scripts python3, bash dans workspace/scripts/ - PAS d'install pip durant runtime (figé Dockerfile : yfinance, requests) ### 4.3 Fichiers structurants | Fichier | Rôle | |---|---| | MEMORY.md | Connaissances persistantes | | AGENTS.md | Comportement, hard constraints | | SOUL.md / IDENTITY.md | Identité, persona | | TOOLS.md (ce fichier) | Skills opérationnel | | HEARTBEAT.md | Mode batch/cron silencieux | | gmail-rules.md | Règles métier Gmail | | HANDOFF.md | État global / transfert inter-sessions | | bourse-config.json | Watchlist + options du graphe bourse (obsolète : orange-bourse.md) | --- ## 5. Outils système disponibles ### 5.1 Dans le container - python3 (3.11), pip3 (figé build-time) - node (Node.js), npm - curl, jq, git, tini - gog (Google APIs CLI v0.21.0) ### 5.2 Web - web_fetch : ~1500 chars max par fetch - web_search : 10 résultats max - Toutes URLs publiques HTTPS --- ## 6. Bourse — Pipeline (refonte N8N 2026-06-24) ### 6.1 Architecture - L'agent reçoit la demande → POST webhook N8N (section 3.1) → PNG → WhatsApp. - Watchlist dans `bourse-config.json` (section 3.2). - Cron clôture (40 17 * * 1-5, Europe/Paris) : appelle le webhook et envoie le PNG WhatsApp. ### 6.2 Format réponse standard - Avec graphe : 3 lignes texte + PNG attaché. - Prix simple : `ORA.PA : 16,89€ (-0,68%)`. - Marché fermé/indispo : le PNG "Aucune donnée" + le dire, ne pas inventer. --- ## 7. Hard constraint GLOBAL — Anti-amnésie L'agent NE DOIT JAMAIS dire "je ne peux pas faire X" sans avoir vérifié dans ce fichier (TOOLS.md) si X est une capacité documentée. ### Procédure mentale obligatoire avant de refuser : 1. Vérifier dans TOOLS.md si X est documenté 2. Si oui → tenter la commande, rapporter le résultat (succès ou erreur exacte) 3. Si erreur, demander de l'aide à l'utilisateur (pas prétendre l'incapacité) 4. Si vraiment non documenté → "Je ne trouve pas cette capacité, peux-tu préciser ?" ### Exemples de refus INTERDITS - "Je ne peux pas envoyer de mail" (faux : voir section 1.2) - "Je n'ai pas accès à Gmail" (faux : voir section 1) - "Gmail est à venir" (faux : opérationnel depuis 9/6/2026) - "Je suis dans un environnement sécurisé sans capacité" (faux : capacités listées ci-dessus) ### Nouvelle obligation (11/6/2026 post-test) L'agent NE DOIT JAMAIS dire "tool 'gog' isn't available" ou équivalent. `gog` n'est jamais un tool, c'est une commande shell. Si l'agent voit "gog" dans une instruction, il DOIT utiliser `exec` : tool: exec, args: { "command": "gog gmail send ..." } Idem pour python3, curl, jq, git, node, et tout binaire CLI : ces commandes passent TOUJOURS par `exec` ou `bash`, jamais comme tool direct. --- ## 8. Procédure d'ajout d'outil 1. Documenter dans TOOLS.md (ce fichier) avec syntaxe exacte 2. Ajouter mapping question→action (section 1.5, 2.3, etc.) 3. Ajouter hard constraint si nécessaire 4. Tester en dashboard ou WhatsApp /new 5. Backup TOOLS.md avant modification (.bak-) --- ## 9. Gmail daily cron ### 9.1 Job actif | Cron | Schedule | Rôle | Canal | |---|---|---|---| | `daily-email-report` | `30 8 * * *` Europe/Paris | Résumé quotidien Gmail des dernières 24h | WhatsApp `announce` vers `+33607148216` | ### 9.2 Format de réponse attendu - Ligne 1 : résumé global court (ex: « Gmail : 3 nouveaux, 1 important »). - Lignes suivantes : détail UNIQUEMENT les messages importants (livraisons, rendez-vous, alertes, factures). - Pour chaque message important : expéditeur, sujet, date/heure d'arrivée. - Maximum 5 messages détaillés. - Réponse en français. - Ignorer les promotions et newsletters dans le détail. ### 9.3 Source de vérité - Le job est défini dans `state/openclaw.sqlite`, table `cron_jobs`. - Les fichiers `cron/jobs.json*` sont des migrations obsolètes d'anciens jobs bourse. Ne PAS les utiliser pour modifier ce cron.