Files
nas-runbooks/common/veille-cron-pin-bypass-bifrost-20260910.md
T

4.9 KiB

Job cron veille Nexum : bascule silencieuse sur DeepSeek/OpenRouter par pin de provider bypassant bifrost-proxy

Instance auteur : hermes-nyora Date : 2026-09-10 Tags : [infra, bifrost, opencode-go, cron, hermes-nyora, veille-nexum] Statut : validé


Problème

Nabil signale que les 3 veilles quotidiennes Dr. Nexum (07h/12h/20h Tunis, job veille-ia-nexum-4ee61494) tournent depuis un moment sur DeepSeek V4 Flash via OpenRouter au lieu de MiMo-V2.5 via OpenCode. Aucune erreur visible côté Telegram ou côté site veille.bolbol.tn : le contenu est simplement généré par un modèle différent de celui attendu, sans signal d'échec.


Contexte et contraintes

  • config.yaml de hermes-agent-nyora route par défaut via model.default (provider: custom, base_url: http://bifrost-proxy/v1) avec un fallback_providers (opencode-go/deepseek-v4-flash) puis un fallback_model final (openrouter/deepseek-v4-flash) — une chaîne de secours à 3 niveaux, conçue pour ne jamais bloquer un run, pas pour signaler une dégradation.
  • Depuis la règle du 04/09 (piege-virtual-key-nabil-key-bifrost-hermes-20260904.md), l'API OpenCode Go exige un header x-bf-eh-x-opencode-session, injecté uniquement par bifrost-proxy. Un appel direct à https://opencode.ai/zen/go/v1 sans passer par bifrost-proxy échoue systématiquement.
  • Chaque job cron Hermes peut porter un pin model/provider au niveau du job, qui prend le pas sur model.default de config.yaml.

Ce qui NE fonctionne PAS

Tentative Erreur obtenue Raison de l'échec
Job cron avec pin provider=opencode-go direct HTTP 400 MissingSessionID: Request is missing x-opencode-session Le pin bypass bifrost-proxy, qui est le seul point d'injection du header de session requis par l'API OpenCode Go
fallback_providers: opencode-go/deepseek-v4-flash du job Même erreur MissingSessionID Même chemin direct que ci-dessus, hérite du même défaut

Solution validée

Diagnostic (docker logs hermes-agent-nyora) :

WARNING agent.conversation_loop: API call failed (attempt 1/3) provider=opencode-go base_url=https://opencode.ai/zen/go/v1 model=mimo-v2.5 summary=HTTP 400: Error from provider (Console Go): Request is missing x-opencode-session...
WARNING agent.conversation_loop: API call failed (attempt 1/3) provider=opencode-go base_url=https://opencode.ai/zen/go/v1/ model=deepseek-v4-flash summary=HTTP 400: ...
🔄 Switched to fallback model: deepseek-v4-flash via opencode-go → deepseek/deepseek-v4-flash via openrouter

Comparaison avec hermes cron list / lecture directe de jobs.json : seul veille-ia-nexum-4ee61494 portait un pin model=mimo-v2.5, provider=opencode-go au niveau du job. Le seul autre job actif (35d81e5260bb) avait model=None, provider=None et héritait correctement de config.yaml.

Fix :

docker exec hermes-agent-nyora hermes cron edit veille-ia-nexum-4ee61494 --model "" --provider ""

Cette commande retire le pin ; le job hérite désormais de model.default (custom → bifrost-proxy → mimo-v2.5).


Vérification

docker exec hermes-agent-nyora curl -s -X POST http://bifrost-proxy/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <vk-hermes-nyora>" \
  -d '{"model":"mimo-v2.5","max_tokens":20,"messages":[{"role":"user","content":"Reponds juste: OK"}]}'
# Résultat obtenu : HTTP 200, resolved_model_used: mimo-v2.5, provider: opencode (bifrost-proxy sain et actif)

Job vérifié post-edit : model=None, provider=None dans jobs.json, identique au pattern du job sain.


Pièges spécifiques DSM / NAS

  • Ce mode de panne est silencieux par construction : la chaîne de fallback à 3 niveaux de config.yaml est conçue pour toujours produire une réponse, donc un job cassé au niveau du premier maillon (pin direct opencode-go) continue de délivrer un résultat "normal" en apparence, juste avec un modèle différent et moins cher. Aucune alerte ne se déclenche.
  • Réflexe d'audit : tout job cron / profil Hermes avec un pin provider=opencode-go en direct (au lieu de provider=custom + base_url=http://bifrost-proxy/v1) est suspect. Auditer avec hermes cron list puis vérifier chaque job avec model/provider non-null (jobs.json, champs model/provider/base_url/profile).
  • Un profil Hermes (/opt/data/profiles/<nom>/config.yaml) peut porter le même défaut indépendamment des jobs cron — vérifier aussi ce fichier si un job utilise --profile.
  • Ticket Baserow : infra-2026-09-037.

Références

  • common/piege-virtual-key-nabil-key-bifrost-hermes-20260904.md (règle du header x-opencode-session)
  • common/bifrost-opencode-routing-fix-20260907.md (fix précédent du routage bifrost-proxy → opencode.ai)
  • common/migration-vps-bifrost-stub-forwarder-20260904.md (relocalisation bifrost-proxy VPS)