6.2 KiB
Correctif routage Bifrost -> OpenCode Go & raccordement hermes-tt/hermes-nabil/DSH (07/09/2026)
1. Contexte
Le 07/09/2026, Nabil (au travail, sans acces Gemini) signale trois pannes simultanees :
- hermes-tt et hermes-nabil : "provider failed after retries"
- hermes-nyora : bascule silencieuse sur le modele de secours (deepseek-v4-flash via opencode-go -> openrouter)
- DSH :
400 MissingSessionIDa chaque tour
Diagnostic mene et corrige en direct par Claude (intervention SMART justifiee par l'absence de Gemini, cf. hermes-platform.md).
2. Cause racine n°1 : chemin cassé sur le provider opencode de Bifrost
config.json de Bifrost (providers.opencode.network_config.base_url) pointait vers http://opencode-proxy:8080/zen/go.
Ce chemin est un residu de la tentative de sidecar local du 04/09/2026, deja abandonnee a l'epoque a cause du validateur SSRF interne de Bifrost qui bloque toute IP privee (voir migration-vps-bifrost-stub-forwarder-20260904.md, section 5). En plus d'etre la mauvaise approche, la valeur etait meme cassee techniquement : opencode-proxy (VPS) n'ecoute reellement que sur le port 8902, pas 8080 -> connexion refusee a chaque appel.
Consequence : tout appel provider=opencode via Bifrost echouait systematiquement. hermes-nyora/perso (qui ont un fallback configure) basculaient silencieusement sur un modele degrade sans que Nabil s'en rende compte immediatement ; hermes-tt (sans fallback) et tout consommateur direct echouaient dur.
Correctif applique
Retour a la solution native documentee le 04/09 (relais d'en-tete x-bf-eh-x-opencode-session par bifrost-proxy, pas de sidecar) :
base_url: https://opencode.ai/zen/go
Attention : pas de /v1 a la fin. Bifrost ajoute lui-meme /v1/chat/completions sur les providers OpenAI-compatibles ; un base_url finissant deja par /v1 produit un double /v1 et une 404 HTML (page opencode.ai, pas une erreur JSON API) — piege facile a mal diagnostiquer.
Procedure
# Sur le VPS, dans le conteneur bifrost (root)
docker exec -u 0 bifrost sh -c "cp /app/data/config.json /app/data/config.json.bak-<date>"
docker exec -u 0 bifrost sh -c "sed -i 's#ANCIENNE_VALEUR#https://opencode.ai/zen/go#' /app/data/config.json"
# Valider le JSON avant de redemarrer (le conteneur bifrost n'a ni python3 ni node)
docker run --rm -v /home/dsh-agent/bifrost/data:/data:ro alpine:3.20 sh -c 'apk add -q jq; jq empty /data/config.json && echo VALID_JSON'
docker restart bifrost
Test de validation (depuis le NAS, via bifrost-proxy)
curl -s -X POST http://localhost:3086/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <VIRTUAL_KEY>" \
-d '{"model":"opencode/mimo-v2.5","messages":[{"role":"user","content":"ping"}],"max_tokens":10}'
Une reponse JSON chat.completion valide confirme le bon fonctionnement (teste avec succes pour vk-hermes-nyora, vk-hermes-perso, vk-hermes-tt, vk-hermes-nabil, vk-dsh-vps le 07/09/2026).
3. Cause racine n°2 : hermes-tt, hermes-nabil et DSH jamais raccordes au pattern bifrost-proxy
Ces trois consommateurs appelaient OpenCode Go en direct (https://opencode.ai/zen/go/v1 ou provider opencode-go/opencode-direct sans passer par bifrost-proxy), donc sans l'injection de x-opencode-session -> MissingSessionID systematique, sans le filet de securite qu'offre Bifrost (fallback, tracking cout, whitelist par cle).
hermes-tt (NAS, hermes-agent-tt, /opt/data/config.yaml)
Avant :
model:
provider: opencode-go
base_url: ''
api_key: ''
fallback_providers: []
Apres (aligne sur hermes-nyora/perso) :
model:
provider: custom
base_url: http://bifrost-proxy/v1
api_key: sk-bf-26694aba-54d0-4d03-8c4c-a6e3830b6cbe # vk-hermes-tt (existait deja depuis le 18/07, jamais utilisee)
fallback_providers:
- provider: opencode-go
model: mimo-v2.5
key_env: OPENCODE_GO_API_KEY
hermes-nabil (VPS, /data/config.yaml)
Avant : base_url: https://opencode.ai/zen/go/v1, cle OpenCode Go brute.
Apres :
model:
provider: custom
base_url: http://100.86.197.88:3086/v1 # IP Tailscale du NAS, port publie de bifrost-proxy (le hostname docker "bifrost-proxy" n'existe que sur le reseau n8n du NAS, injoignable depuis le VPS)
api_key: sk-bf-eb2e9179-c646-4e84-afe7-bc7c61b16f59 # vk-hermes-nabil, creee le 07/09/2026
Nouvelle cle virtuelle creee via l'API Bifrost (POST /api/governance/virtual-keys sur localhost:3085, meme structure provider_configs que vk-hermes-perso : google/groq/nvidia_nim/opencode/openrouter). Piege confirme une fois de plus (voir migration-vps-bifrost-stub-forwarder-20260904.md section 4) : l'API cree la cle avec allow_all_keys=false malgre le payload envoye a true — patch SQL obligatoire puis restart :
UPDATE governance_virtual_key_provider_configs SET allow_all_keys=1 WHERE virtual_key_id='<id>';
DSH (VPS, /home/dsh-agent/.dsh/settings.yaml)
Cas different : le provider bifrost etait deja correctement configure (baseURL http://100.86.197.88:3086/v1, BIFROST_API_KEY = vk-dsh-vps deja valide cote Bifrost) mais agent-default-model.provider restait sur opencode-direct. Il manquait aussi l'entree opencode/mimo-v2.5 dans le catalogue de modeles du provider bifrost (seuls deepseek-v4-flash/gemini/gemma/qwen y figuraient).
Correctif : bascule de provider: opencode-direct -> provider: bifrost, model: mimo-v2.5 -> model: opencode/mimo-v2.5, ajout de l'entree modele manquante.
4. Perimetre restant (non traite dans cette session)
Le volet nyora-doc-api/nyora-convert-api du ticket infra-2026-09-023 (bascule des appels NAS vers les instances VPS pour tous les assistants) n'a pas ete traite ici — uniquement le volet routage LLM/Bifrost.
5. Lecon a capitaliser
Ne jamais faire confiance a un base_url existant dans config.json sans verifier qu'il correspond a une architecture actuellement valide — un residu d'une tentative abandonnee (meme documentee comme abandonnee ailleurs) peut rester en config sans lever d'alerte jusqu'a ce qu'un consommateur sans fallback tombe dessus. Toujours re-tester en conditions reelles (requete complete, pas juste /health) apres toute correction de routage LLM.