From ea5dd014b6d690cede963ba4e4089f2e5b8479ea Mon Sep 17 00:00:00 2001 From: Thierry Date: Thu, 25 Jun 2026 01:56:29 +0200 Subject: [PATCH] Refonte bourse via N8N + passage modele Thinking - openclaw.json: qwen3-vl reasoning:true, maxTokens 16384, nettoyage entrees dupliquees - handoffs: synthese HANDOFF-2026-06-24-BOURSE-N8N.md (archi webhook N8N, config, tests) --- handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md | 116 ++++++++ openclaw.json | 332 ++++++++++++++++++++++ 2 files changed, 448 insertions(+) create mode 100644 handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md create mode 100644 openclaw.json diff --git a/handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md b/handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md new file mode 100644 index 0000000..25ff074 --- /dev/null +++ b/handoffs/HANDOFF-2026-06-24-BOURSE-N8N.md @@ -0,0 +1,116 @@ +# HANDOFF — Refonte Bourse via N8N + passage modèle Thinking + +**Date :** 2026-06-24 / 2026-06-25 +**Auteur :** session OpenCode (assistant) + Thierry +**Périmètre :** suivi boursier (Orange, Total, etc.), workflow N8N, modèle vLLM + +--- + +## 1. Contexte / problème initial + +- `orange-bourse.md` était corrompu chaque semaine : le LLM l'éditait **à la main** + (cron `orange-intraday` 8×/jour) → doublons, sections vides, ordre cassé. +- Jours de bourse fermée non gérés → cours inventés ou lignes incohérentes. +- Tout en dur dans des scripts Python (`get_quote.py`, `generate_chart.py`) : + ajouter une valeur = réécrire un script. +- 2 workflows N8N "Bourse" préexistants **cassés** (IDs dupliqués, données en dur, + faux endpoint WhatsApp). +- Graphe avec axe Y non-zéro → "variations géantes pour 5 cts". +- Modèle en variante Instruct (`reasoning:false`). + +## 2. Nouvelle architecture + +``` +Toi (WhatsApp / GUI) + │ langage naturel ("ajoute Nvidia", "zoom variations") + ▼ +Agent OpenClaw (Qwen3-VL Thinking) + │ interprète → appelle le webhook (curl) ou édite bourse-config.json + ▼ +N8N workflow "Bourse — Graphe multi-tickers (v3)" [id 4bluZIeN3TnbzIrv] + │ fetch Yahoo (multi-tickers, range/interval), gère marché fermé + ▼ renvoie un PNG (QuickChart, axe Y configurable) +Agent → affiche le PNG (WhatsApp / GUI) +``` + +**Principe : l'agent = interlocuteur, N8N = exécutant. Plus AUCUNE donnée éditée à la main.** + +## 3. Le workflow N8N (source unique du graphe) + +- **Nom :** `Bourse — Graphe multi-tickers (v3)` +- **ID :** `4bluZIeN3TnbzIrv` (actif) +- **Webhook :** `POST https://n8n.airtria.pro/webhook/bourse-graphe` +- **Nodes :** Webhook → Code "Fetch + Build QuickChart" → HTTP QuickChart → Respond (binary PNG) +- **Body JSON (tout optionnel) :** + - `tickers` : ex `["ORA.PA","TTE.PA","NVDA"]` (FR = suffixe `.PA`, US = sans suffixe) + - `range` : `1d|5d|1mo|3mo|6mo|1y` (def `5d`) + - `interval` : `15m|60m|1d` (def `60m`) + - `beginAtZero` : `true` (axe Y depuis 0) | `false` (zoom serré sur les variations, `grace:"5%"`) + - `title` : titre optionnel +- **Marché fermé / ticker invalide :** renvoie un PNG "Aucune donnée" (jamais de cours inventé). +- **Point technique clé :** QuickChart nécessite `version:"4"` (Chart.js v4) dans le + payload pour que `scales.y.min:0` / `beginAtZero` soient respectés. Sans ça l'axe + ne descend pas à 0. + +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 +``` + +## 4. Fichiers / config modifiés + +| Fichier | Changement | +|---|---| +| `workspace/bourse-config.json` | **NOUVEAU** : watchlist + défauts + aliases (source de vérité éditable par l'agent) | +| `workspace/AGENTS.md` | Section BOURSE réécrite (pilotage N8N), anciennes hard-constraints supprimées | +| `workspace/TOOLS.md` | Sections 3 et 6 réécrites (webhook N8N, scripts marqués obsolètes) | +| `openclaw.json` | `qwen3-vl` → `reasoning:true`, `maxTokens` 8192→16384, suppression entrée doublon `qwen3-vl-thinking` et ref orpheline `vllm/qwen3.6` | +| Crons (SQLite) | `orange-cloture` (40 17 * * 1-5) → appelle le webhook N8N + envoie PNG WhatsApp ; `orange-intraday`/`orange-ouverture`/`orange-chart-update` **désactivés** | +| N8N | 2 workflows bourse cassés supprimés (`rJswndMIRj7R7uQ6`, `w30bBJXQFgRV6RMB`) | +| Cache modèle (SQLite) | `agent_model_catalogs` + `model_capability_cache` purgés (entrées qwen3-vl périmées) → régénérés au restart | + +**Archivé (récupérable) :** `workspace/_archive-bourse-20260624/` +(get_quote.py, generate_chart.py, clean_bourse_md.py, orange-bourse.md + backups, SVG/PNG de test). + +**Backups DB :** `state/openclaw.sqlite.bak-pre-bourse-refonte-*`, `*-pre-catalog-purge-*`. + +## 5. Modèle vLLM (Thinking) + +- vLLM sert `Qwen/Qwen3-VL-30B-A3B-Thinking-FP8` sous `--served-model-name=qwen3-vl` + (nom inchangé → zéro reconfig réseau côté OpenClaw). +- Flags clés : `--reasoning-parser=qwen3`, `--enable-auto-tool-choice`, + `--tool-call-parser=hermes`, sampling `temp=0.6 top_p=0.95 top_k=20`. +- Côté OpenClaw : entrée `qwen3-vl` = `reasoning:true`, `maxTokens:16384`, `contextWindow:65536`. +- **GUI** expose un menu REASONING (Off/Minimal/Low/Medium/High). Défaut conseillé : **Medium**. + High pour conception/debug de workflows ; Low/Medium pour les graphes courants. +- Le mode Thinking est plus lent (~17-21 tok/s) mais plus juste sur le tool-calling. +- **Max tokens GUI** : monter le défaut de session de 800 → ~8192 (réglage côté navigateur, + pas de défaut serveur dans cette version). + +## 6. Validations effectuées (tests réels) + +- ORA seul, ORA+TTE, ORA+TTE+NVDA (1 mois) → PNG corrects, axe à 0. +- `beginAtZero:false` → zoom serré (ex ORA 16,65–17,10 €) : micro-variations visibles. +- Ticker invalide → PNG "Aucune donnée". +- Agent (Thinking) a appelé le webhook de façon autonome avec les bons tickers + (`ORA.PA`,`TTE.PA`) → exécution N8N `671723` ✅, livré WhatsApp + GUI. +- Après restart : sélecteur GUI propre (plus d'entrée fantôme), agent liste OK. + +## 7. Reste à faire / vérifs + +- [ ] Régler le max tokens GUI à ~8192 (navigateur). +- [ ] Tester "2 graphes séparés zoomés" (Orange / Total) → doit faire 2 appels `beginAtZero:false`. +- [ ] Surveiller le 1er cron `orange-cloture` réel (lenteur Thinking vs timeouts). +- [ ] Anthropic = **non cotée en bourse** (pas de ticker) — le dire si demandé. +- [ ] Si besoin, monter `OPENCLAW_CRON_JOB_TIMEOUT_MS` si le Thinking déborde. + +## 8. Notes opérationnelles + +- Modifier le comportement du graphe = éditer le node JS du workflow `4bluZIeN3TnbzIrv` + via MCP `n8n-mcp` ou l'API n8n (le tool MCP `update_workflow`/`activate` est buggé + sur cette version → préférer l'API REST n8n directe : `PUT /workflows/{id}` puis + `POST /workflows/{id}/activate`). +- Ne JAMAIS rééditer `orange-bourse.md` (mort, archivé). diff --git a/openclaw.json b/openclaw.json new file mode 100644 index 0000000..eddcd86 --- /dev/null +++ b/openclaw.json @@ -0,0 +1,332 @@ +{ + "gateway": { + "mode": "local", + "bind": "lan", + "auth": { + "mode": "token", + "token": "119bca22-377a-4b69-a484-9b08cc79a782", + "rateLimit": { + "maxAttempts": 10, + "windowMs": 60000, + "lockoutMs": 300000 + } + }, + "remote": { + "url": "ws://127.0.0.1:18789", + "token": "119bca22-377a-4b69-a484-9b08cc79a782" + }, + "controlUi": { + "allowedOrigins": [ + "https://openclaw.airtria.pro", + "http://10.10.10.17:18789" + ] + }, + "trustedProxies": [ + "172.16.0.0/12", + "127.0.0.1", + "10.10.10.0/24" + ], + "tailscale": {} + }, + "skills": { + "entries": { + "1password": { + "enabled": false + }, + "apple-notes": { + "enabled": false + }, + "apple-reminders": { + "enabled": false + }, + "bear-notes": { + "enabled": false + }, + "blogwatcher": { + "enabled": false + }, + "blucli": { + "enabled": false + }, + "camsnap": { + "enabled": false + }, + "clawhub": { + "enabled": false + }, + "coding-agent": { + "enabled": false + }, + "discord": { + "enabled": false + }, + "eightctl": { + "enabled": false + }, + "gemini": { + "enabled": false + }, + "gh-issues": { + "enabled": false + }, + "gifgrep": { + "enabled": false + }, + "github": { + "enabled": false + }, + "gog": { + "enabled": true + }, + "goplaces": { + "enabled": false + }, + "himalaya": { + "enabled": false + }, + "imsg": { + "enabled": false + }, + "mcporter": { + "enabled": false + }, + "model-usage": { + "enabled": false + }, + "nano-pdf": { + "enabled": false + }, + "obsidian": { + "enabled": false + }, + "openai-whisper": { + "enabled": false + }, + "openai-whisper-api": { + "enabled": false + }, + "openhue": { + "enabled": false + }, + "oracle": { + "enabled": false + }, + "ordercli": { + "enabled": false + }, + "peekaboo": { + "enabled": false + }, + "sag": { + "enabled": false + }, + "session-logs": { + "enabled": false + }, + "sherpa-onnx-tts": { + "enabled": false + }, + "slack": { + "enabled": false + }, + "songsee": { + "enabled": false + }, + "sonoscli": { + "enabled": false + }, + "spotify-player": { + "enabled": false + }, + "summarize": { + "enabled": false + }, + "things-mac": { + "enabled": false + }, + "tmux": { + "enabled": false + }, + "trello": { + "enabled": false + }, + "video-frames": { + "enabled": false + }, + "voice-call": { + "enabled": false + }, + "wacli": { + "enabled": false + }, + "xurl": { + "enabled": false + }, + "whatsapp": { + "enabled": true + } + } + }, + "meta": { + "lastTouchedVersion": "2026.6.9", + "lastTouchedAt": "2026-06-23T00:31:04.678Z" + }, + "wizard": { + "lastRunAt": "2026-05-28T19:12:05.393Z", + "lastRunVersion": "2026.5.27", + "lastRunCommand": "doctor", + "lastRunMode": "local" + }, + "agents": { + "defaults": { + "model": { + "primary": "vllm/qwen3-vl" + }, + "compaction": { + "reserveTokensFloor": 20000, + "mode": "safeguard", + "reserveTokens": 8192 + }, + "models": { + "vllm/qwen3-vl": {} + }, + "sandbox": { + "mode": "off" + }, + "heartbeat": { + "timeoutSeconds": 600, + "every": "0" + }, + "memorySearch": { + "enabled": false + } + } + }, + "models": { + "mode": "merge", + "providers": { + "vllm": { + "baseUrl": "http://10.10.10.8:8000/v1", + "api": "openai-completions", + "apiKey": "vllm-local", + "timeoutSeconds": 300, + "models": [ + { + "id": "qwen3-vl", + "name": "Qwen3-VL 30B FP8 Thinking DGX Vision", + "reasoning": true, + "input": [ + "text", + "image" + ], + "mediaInput": { + "image": { + "maxBytes": 10485760 + } + }, + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 65536, + "maxTokens": 16384 + } + ] + } + } + }, + "auth": { + "profiles": { + "vllm:default": { + "provider": "vllm", + "mode": "api_key" + } + } + }, + "messages": { + "ackReactionScope": "group-mentions" + }, + "session": { + "dmScope": "per-channel-peer" + }, + "plugins": { + "entries": { + "whatsapp": { + "enabled": true + }, + "vllm": { + "enabled": true + }, + "memory-core": { + "config": {} + } + } + }, + "channels": { + "whatsapp": { + "enabled": true, + "configWrites": true, + "sendReadReceipts": true, + "selfChatMode": true, + "debounceMs": 0, + "mediaMaxMb": 50, + "accounts": { + "custom-1": { + "sendReadReceipts": true, + "dmPolicy": "allowlist", + "selfChatMode": true, + "allowFrom": [ + "+33607148216", + "+33614567830", + "+33770213828", + "+33770924400" + ], + "groupPolicy": "allowlist", + "groupAllowFrom": [ + "+33607148216" + ], + "ackReaction": { + "direct": true, + "group": "mentions" + }, + "debounceMs": 0, + "authDir": "/home/node/.openclaw/whatsapp/custom-1" + } + }, + "groups": { + "*": { + "requireMention": true + } + }, + "actions": { + "reactions": true, + "sendMessage": true, + "polls": true + } + } + }, + "tools": { + "media": { + "image": { + "enabled": true + } + } + }, + "mcp": { + "servers": { + "n8n-mcp": { + "command": "npx", + "args": [ + "-y", + "n8n-mcp" + ], + "env": { + "N8N_API_URL": "https://n8n.airtria.pro/api/v1", + "N8N_API_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI4YjllOTU1Mi1jZDc0LTQ4NjMtODJhMy0xNzRiM2IzYmVmYTIiLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwianRpIjoiMGYzZmU4NDAtNGY5Yi00ZDgwLWIzNzctMDRjZmU4ZmE5OWM5IiwiaWF0IjoxNzc4NjMzMzY0fQ.BPypJ7xR_bzVpptZQvD1ZvV9_-CIjKrj5s7r7lt-qGw" + } + } + } + } +}