# RUNBOOK — Appels LLM depuis nœuds Code n8n : passer par Bifrost obligatoirement **Date** : 2026-06-17 **Découvert lors** : Migration OpenCode Go veille IA — workflow VEILLE | Monitoring sources IA --- ## Problème Les nœuds **Code** n8n (JavaScript) ne peuvent **pas** appeler `opencode.ai` directement. Le container n8n est sur le réseau Docker `n8n` et n'a pas de connectivité sortante vers `opencode.ai`. **Symptôme trompeur** : l'appel HTTPS semble réussir (pas de timeout, pas de `NET_ERR`), mais `choices[0].message.content` est vide ou `null`. Résultat : `JSON.parse("")` → `Unexpected end of JSON input`. Le workflow passe en `success` car le catch absorbe l'erreur silencieusement. **Ce qui NE fonctionne PAS** depuis un nœud Code n8n : - `https://opencode.ai/zen/go/v1/chat/completions` → contenu vide silencieux - Tout endpoint LLM externe (openrouter, etc.) potentiellement concerné --- ## Solution **Toujours passer par Bifrost** (réseau Docker interne, accessible depuis n8n) : ```javascript const http = require('http'); const BIFROST_VK = 'bfk-e5832bfebd22e9d8252a426d0734ed5f2d923204c8033d6d'; // Nabil-Key const body = JSON.stringify({ model: 'deepseek-v4-flash', // sans préfixe OpenRouter max_tokens: 400, stream: false, temperature: 0.1, messages: [{ role: 'user', content: '...' }] }); const options = { hostname: 'bifrost', // nom du container Docker port: 8080, path: '/v1/chat/completions', method: 'POST', headers: { 'Content-Type': 'application/json', 'x-bf-vk': BIFROST_VK, // header Bifrost (PAS Authorization Bearer) 'Content-Length': Buffer.byteLength(body) }, timeout: 60000 }; const req = http.request(options, (res) => { ... }); ``` **Points critiques** : - Utiliser `http` (pas `https`) car Bifrost est en HTTP interne - Header : `x-bf-vk` (pas `Authorization: Bearer`) → 401 sinon - Modèle : `deepseek-v4-flash` sans préfixe `deepseek/` (format OpenCode, pas OpenRouter) - `stream: false` obligatoire --- ## Modèles disponibles via Bifrost | Modèle | Notes | |--------|-------| | `deepseek-v4-flash` | ✅ Confirmé fonctionnel, rapide, JSON fiable | | `deepseek-v4-pro` | ✅ Plus puissant | | `glm-5.1` | ⚠️ Fait du chain-of-thought avant le JSON → tronque avec max_tokens bas | | `kimi-k2.6` | ❌ Provider Moonshot AI down (521) au 17/06/2026 | | `qwen3.7-plus` | ✅ Disponible | --- ## VKs Bifrost (SQLite `/volume1/docker/bifrost/data/config.db`) | Nom | VK | |-----|----| | Nabil-Key | `bfk-e5832bfebd22e9d8252a426d0734ed5f2d923204c8033d6d` | | Yesmine-Key | `bfk-1eb77f96379622db7264ae6692980e4cb81cde9e7435f66a` | --- ## Rappel : nœuds HTTP Request n8n natifs Les nœuds **HTTP Request** (non-Code) utilisent les credentials n8n et peuvent avoir une connectivité différente. Le workflow VEILLE | Enrichissement articles utilise un nœud HTTP Request natif vers `http://bifrost:8080/v1/chat/completions` avec une credential `httpHeaderAuth` → fonctionne. --- ## Ce qui NE fonctionne PAS - `opencode.ai` direct depuis nœud Code n8n → contenu vide silencieux - `kimi-k2.6` via Bifrost → provider Moonshot AI en panne (code 521) - `glm-5.1` pour JSON avec max_tokens < 800 → chain-of-thought tronque avant le JSON - Préfixe `deepseek/deepseek-v4-flash` (format OpenRouter) sur OpenCode Go → 400 ou réponse sans choices