---
title: Codex CLI Integration
url: https://blog.guigpap.com/fr/workflows/codex-cli-integration/
url_md: https://blog.guigpap.com/fr/workflows/codex-cli-integration.md
category: automation
date: '2026-05-19'
maturite: production
techno:
- n8n
- telegram
- claude
application:
- automation
- operations
---
# Codex CLI Integration
> Famille de workflows N8N qui supervisent l'authentification Codex CLI, relancent le device-code et streament la progression vers Telegram
## 1. Quoi ? — Définition et contexte
La **Codex CLI Integration** est une famille de quatre workflows N8N qui industrialisent l'usage du CLI Codex d'OpenAI au sein de la stack `ai-stack/cli-ollama`. Codex est devenu le provider par défaut de CLI Ollama (commit `195d432`) : sans automatisation autour de son authentification et de son streaming, le tooling AI casserait silencieusement à la première expiration de session OAuth.
> **Note - Pourquoi une famille de workflows ?**
>
> Codex CLI s'authentifie via OAuth device-code. La session se rafraîchit en lisant `~/.codex/auth.json`, mais expire après plusieurs jours d'inactivité. Une seule expiration silencieuse coupe tous les agents Telegram, l'IA Router, les sub-workflows d'approbation et la chaîne MCP. La famille existe pour détecter, relancer, confirmer et streamer Codex de bout en bout.
### Périmètre
| Workflow | ID | Nodes | Trigger | Rôle |
|----------|----|-------|---------|------|
| **Codex Auth Watchdog** | `PaBIkK76OPcHQr53` | 5 | Schedule (6h) | Surveille la fraîcheur de `auth.json` et alerte via Notification Hub |
| **Codex Reauth Flow** | `sLAIrqJDGRUE6Jmj` | 5 | Execute Workflow | Démarre une session device-auth et envoie URL + code via Telegram |
| **Codex Reauth Callback Actions** | `xpHr32uMtdEE0M3Q` | 8 | Execute Workflow | Traite les boutons `[Done]` / `[Cancel]` après réauth |
| **Codex Progress Handler** | `w8r9JcpArIElZxRe` | 11 | Webhook `/codex-progress` | Buffer le streaming Codex et édite le message Telegram |
### Endpoints CLI Ollama consommés
| Endpoint | Méthode | Consommé par |
|----------|---------|--------------|
| `/api/codex/auth/status` | GET | Auth Watchdog |
| `/api/codex/reauth` | POST | Reauth Flow |
| `/api/codex/reauth/{id}/status` | GET | Callback Actions ([Done]) |
| `/api/codex/reauth/{id}` | DELETE | Callback Actions ([Cancel]) |
| `/webhook/codex-progress` (N8N) | POST | Codex provider (streaming) |
### Architecture visuelle
```mermaid
flowchart TD
subgraph Watch["Codex Auth Watchdog · 5 nodes"]
direction TB
Sched["Schedule 6h"]
Fetch["Get Codex Auth Status"]
Eval["Evaluate Auth Health"]
IfAlert["IF Should Alert"]
Hub["Call Notification Hub"]
end
subgraph Reauth["Codex Reauth Flow · 5 nodes"]
direction TB
RTrig["Execute Workflow Trigger"]
Start["Start Reauth Session"]
Fmt["Format Reauth Message"]
Send["Send Reauth Prompt"]
Done["Return Reauth Started"]
end
subgraph CB["Codex Reauth Callback Actions · 8 nodes"]
direction TB
CTrig["Execute Workflow Trigger"]
Ack["Answer Callback"]
SwAct["Switch Action"]
CheckS["Check Reauth Status"]
Cancel["Cancel Reauth Session"]
Edit["Edit Original Message"]
end
subgraph Prog["Codex Progress Handler · 11 nodes"]
direction TB
PHook["Webhook /codex-progress"]
Parse["Parse Body"]
Buf["DT Get Buffer"]
Decide["Code Decide"]
EditMsg["Edit Message"]
NewMsg["Send New Message"]
Upd["DT Update Buffer"]
end
CLI["cli-ollama
FastAPI · /api/codex/*"]
TG["Telegram bot
chat utilisateur"]
Watch --> Hub --> TG
Watch -.->|HTTP GET /auth/status| CLI
Reauth -->|HTTP POST /reauth| CLI
Reauth --> TG
TG -->|callback Done / Cancel| CB
CB -->|HTTP GET /reauth/id/status| CLI
CB -->|HTTP DELETE /reauth/id| CLI
CB --> TG
CLI -->|POST /webhook/codex-progress| Prog
Prog --> TG
```
---
## 2. Pourquoi ? — Enjeux et motivations
### Problèmes résolus
| Problème | Sans la famille | Avec la famille |
|----------|-----------------|------------------|
| **Expiration silencieuse** | Toutes les requêtes AI échouent sans signal | Watchdog alerte à J-2 et J-0 de l'expiration |
| **Réauth manuelle SSH** | Connexion VPS + `docker exec` + copier-coller du code | Bouton Telegram + device-code envoyé en push |
| **Spawn hors conteneur** | Codex CLI lancé sur l'hôte écrit dans le mauvais `~/.codex` | Spawn in-container, écrit dans `/home/cli/.codex/auth.json` |
| **Erreurs typées floues** | « subprocess failed » non actionnable | Erreur `auth_expired` détectée côté CLI Ollama |
| **Streaming Codex perdu** | Long run = silence radio Telegram pendant 30s+ | Edit-in-place du message via buffer DT |
| **Annulation impossible** | Session device-auth zombie en cas d'abandon | `[Cancel]` tue le subprocess via `DELETE /reauth/{id}` |
### Pourquoi un Watchdog et pas une alerte à la première erreur ?
Découvrir l'expiration au moment d'un appel utilisateur dégrade l'UX : le message Telegram retourne une erreur cryptique et l'utilisateur doit ouvrir la documentation. Le Watchdog tourne toutes les 6 heures et anticipe :
| Seuil | Sévérité | Action |
|-------|----------|--------|
| `auth.json` absent | `critical` | Alerte immédiate avec commande `codex login --device-auth` |
| `age > 8 jours` | `critical` | Re-auth fortement recommandée |
| `age > 6 jours` | `warning` | Surveillance, re-auth proche |
| `last_refresh` illisible | `warning` | Fichier corrompu à inspecter |
Les seuils 6/8 jours offrent une fenêtre confortable (~48h) entre la première alerte et la vraie panne.
### Pourquoi extraire le Callback Handler du Reauth Flow ?
Le Reauth Flow envoie le message Telegram, mais le callback `[Done]` / `[Cancel]` est asynchrone : l'utilisateur peut cliquer 10 minutes plus tard. Le séparer en sub-workflow dédié (8 nodes) suit la même logique que `NH Callback Handler` (#276) : routage précoce via le Telegram Orchestrator, bypass de la dedup, pas d'état partagé.
### Évolutions récentes
| Commit | Apport |
|--------|--------|
| `edfcf79` | Erreur typée `auth_expired` côté CLI Ollama (détection au lieu de subprocess error) |
| `9771a97` | Spawn device-auth in-container + détection `auth missing` |
| `ba0f7ae` | Bump n8n-exports avec corrections de reauth |
| `32c3282` | Webhook streaming `/webhook/codex-progress` côté provider |
| `7ee7dbd` | Chat Codex edit-in-place + streaming temps réel Telegram |
---
## 3. Comment ? — Mise en œuvre technique
### Composants
| Workflow | ID | Nodes | Rôle |
|----------|----|-------|------|
| Codex Auth Watchdog | `PaBIkK76OPcHQr53` | 5 | Cron 6h, check `/api/codex/auth/status`, alerte Hub |
| Codex Reauth Flow | `sLAIrqJDGRUE6Jmj` | 5 | Spawn device-auth, push Telegram avec URL + code |
| Codex Reauth Callback Actions | `xpHr32uMtdEE0M3Q` | 8 | Switch sur callback, confirme ou annule la session |
| Codex Progress Handler | `w8r9JcpArIElZxRe` | 11 | Buffer DT + edit-in-place du message Telegram |
### Codex Auth Watchdog (5 nodes)
Chaîne linéaire : `Schedule 6h` → `Get Codex Auth Status` (HTTP GET) → `Evaluate Auth Health` (Code) → `IF Should Alert` → `Call Notification Hub` (Execute Workflow).
Le node `Evaluate Auth Health` applique deux seuils :
```javascript
var WARNING_AGE = 6 * 86400; // 6 jours
var CRITICAL_AGE = 8 * 86400; // 8 jours
if (!s.exists) {
severity = 'critical';
title = 'Codex auth manquante';
} else if (age > CRITICAL_AGE) {
severity = 'critical';
} else if (age > WARNING_AGE) {
severity = 'warning';
}
```
L'appel au [Notification Hub](/fr/workflows/notification-hub/) délègue ensuite la dédup, les quiet hours et le routage Telegram. Le watchdog ne se préoccupe que de l'évaluation, jamais du transport.
> **Tip - Schedule trigger à 6 heures**
>
> Un cron toutes les 6h offre 4 contrôles par jour. Cumulé avec le seuil à 6 jours, l'utilisateur reçoit au moins 8 alertes `warning` avant que `auth.json` n'atteigne 8 jours et bascule en `critical` — laissant ~48h de marge pour ouvrir un terminal.
### Codex Reauth Flow (5 nodes)
Déclenché par Execute Workflow (depuis un agent conversationnel ou un alias `/codex-reauth`). Le node `Start Reauth Session` fait un `POST http://cli-ollama:11434/api/codex/reauth` :
```json
{
"reauth_id": "rau_xxx",
"device_url": "https://auth.openai.com/device",
"user_code": "ABCD-EFGH",
"host_command": "docker exec -it cli-ollama codex login --device-auth",
"ttl_seconds": 600
}
```
Le node `Format Reauth Message` construit un message Telegram avec inline keyboard `[Ouvrir l'URL]` `[Done]` `[Cancel]`. `Send Reauth Prompt` envoie le message, `Return Reauth Started` retourne le `reauth_id` au workflow appelant pour qu'il puisse corréler le callback ultérieur.
### Codex Reauth Callback Actions (8 nodes)
Routé depuis le Telegram Orchestrator quand `callback_data` commence par `codex_reauth_`. Chaîne :
1. `Execute Workflow Trigger` — reçoit `chatId`, `messageId`, `callbackData`, `reauthId`.
2. `Answer Callback` — ferme le spinner Telegram immédiatement.
3. `Switch Action` — `done` vs `cancel`.
4. Branche `done` → `Check Reauth Status` (GET `/api/codex/reauth/{id}/status`) → `Format Done Result`.
5. Branche `cancel` → `Cancel Reauth Session` (DELETE `/api/codex/reauth/{id}`) → `Format Cancel Result`.
6. Convergence sur `Edit Original Message` (Telegram edit) qui remplace le prompt par le résultat.
> **Caution - Idempotence du Cancel**
>
> Le `DELETE /api/codex/reauth/{id}` tue le subprocess Codex CLI. Si l'utilisateur clique `[Done]` après avoir cliqué `[Cancel]`, le `GET /status` retournera `404 reauth_session_not_found`. Le node `Format Done Result` doit gérer ce cas pour ne pas re-throw.
### Codex Progress Handler (11 nodes)
Quand le provider Codex (`cli-ollama/app/services/providers/codex.py`) émet un événement de progression, il fait un `POST` vers `http://n8n:5678/webhook/codex-progress` avec :
```json
{
"chatId": "5883063462",
"messageId": 12345,
"sessionId": "tg_xxx",
"progressText": "Reading 3 files...",
"isFinal": false
}
```
Chaîne du handler :
1. `Webhook Trigger` (path `codex-progress`).
2. `Parse Body` — extrait `chatId`, `messageId`, `progressText`.
3. `DT Get Buffer` — Data Table indexée par `messageId` (état de l'édition).
4. `IF Buffer Exists` — première progression ou suite ?
5. `Code Decide` — décide entre `edit` (append au buffer), `split` (nouveau message si > limite Telegram) ou `skip`.
6. `IF Should Edit` / `IF Need Split` — routage selon la décision.
7. `Edit Message` (Telegram) ou `Send New Message`.
8. `Prep DT Update` + `DT Update Buffer` — persiste le nouvel état pour la prochaine progression.
Le buffer évite l'enchaînement d'éditions Telegram bloquant (rate-limit) et permet l'effet « live » sans saturer l'API.
### Sécurité
| Surface | Protection |
|---------|------------|
| `/api/codex/*` | Endpoint interne du réseau `ai-internal`, non exposé via Caddy |
| `/webhook/codex-progress` | Webhook N8N interne, bloqué par Caddy depuis l'extérieur |
| Spawn `codex login --device-auth` | Exécuté dans le conteneur `cli-ollama` avec `~/.codex` isolé du host |
| Session reauth TTL | 600 secondes — au-delà le subprocess est tué automatiquement |
---
## 4. Et si ? — Perspectives et limites
### Limites actuelles
| Limite | Impact | Mitigation |
|--------|--------|------------|
| **Watchdog mono-instance** | Une seule installation Codex surveillée | Suffisant pour un usage solo VPS |
| **Pas de re-auth automatique** | L'utilisateur doit toujours cliquer | Sécurité OAuth : le device-code exige une interaction humaine |
| **Buffer DT non sharded** | Une seule conversation Codex active recommandée | Pour multi-utilisateur, partitionner par `chatId + messageId` |
| **Pas de métrique Prometheus** | Pas de dashboard Grafana sur la santé Codex | TODO : exporter `codex_auth_age_seconds` depuis CLI Ollama |
| **Cancel best-effort** | Si le subprocess est déjà bloqué sur stdin, le SIGTERM peut prendre quelques secondes | TTL 600s garantit la libération |
### Scénarios d'évolution
**Si plusieurs providers à surveiller** :
- Généraliser le Watchdog en `AI Auth Watchdog` paramétré (`provider=codex|gemini|claude`)
- Endpoints unifiés `/api/auth/status?provider=...`
- Un cron unique pour tous les providers
**Si besoin de pré-auth proactif** :
- Tâche cron à J-1 qui démarre déjà la session device-auth et envoie le code en avance
- L'utilisateur prépare la re-auth sans urgence
**Si volume de progressions explose** :
- Throttle côté provider (1 update toutes les 2s minimum)
- Aggrégation Redis (clé `progress:{messageId}`) puis flush périodique
- Sortie alternative `ntfy` pour les longs runs en arrière-plan
**Si multi-utilisateur** :
- Data Table `codex_sessions` indexée par `chatId`
- Chaque utilisateur a son propre `auth.json` (impossible avec le CLI actuel)
- Workaround : un compte Codex partagé + traçabilité par session_id Redis
---
## Pages liées
### Infrastructure
- [N8N en mode Queue](/fr/infrastructure/n8n-queue-mode/) — Backend qui exécute la famille
- [Notify Stack](/fr/infrastructure/notify-stack/) — DIUN et ntfy en aval du Watchdog
### Workflows
- [Notification Hub](/fr/workflows/notification-hub/) — Cible des alertes du Watchdog
- [Telegram Orchestrator](/fr/workflows/telegram-orchestrator/) — Route les callbacks `codex_reauth_*`
- [Système conversationnel](/fr/workflows/systeme-conversationnel/) — Consommateur principal du provider Codex
- [Question Hub](/fr/workflows/question-hub/) — Modèle d'interaction Telegram asynchrone
### Référence
- [Glossaire](/fr/reference/glossary/) — Device-code, Webhook, Buffer
## Metadonnees agent
- Cet article est issu du blog GuiGPaP Lab.
- Contexte global du blog: https://blog.guigpap.com/llms.txt
- Contact auteur: https://odoo.guigpap.com/mon-cv
- Licence: CC-BY-SA 4.0