Avec REASONING_ECHO, tout 400/500 dont le corps contenait « thinking » passait
pour un refus du raisonnement renvoyé, et ce test passe avant le filet des
outils. Une erreur d'analyse d'appel d'outil cite le texte du modèle : s'il y
écrivait « thinking », le tour était rejoué sans raisonnement et, si la
relance passait par chance, la clé était coupée pour ce modèle jusqu'au
redémarrage.
- « Failed to parse input … » (appel d'outil mal formé) n'est jamais un refus
du gabarit : le filet des outils s'en charge, comme sans la clé.
- « thinking » ne compte que dans une erreur du gabarit (jinja, template) ;
raise_exception et les messages invalides restent reconnus.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Les gabarits Qwen3.5/3.6 rendent <think>…</think> pour chaque message
assistant après la dernière question : c'est leur format entraîné. Loki ne
gardait que le texte et les appels, donc à chaque étape d'une boucle d'outils
le modèle relisait ses étapes précédentes avec des blocs vides, et le moteur
recalculait le dernier message. Nouvelle clé REASONING_ECHO (off par défaut) :
avec on, le raisonnement séparé par le serveur est gardé avec chaque message
et renvoyé au même modèle. Sans la clé, rien n'est capturé ni envoyé : la
requête est identique à l'octet près (testé).
- Message.ReasoningContent (reasoning_content) + ReasoningModel, persistés ;
seulement depuis reasoning_content du flux, jamais depuis le découpage
« </think> » fait chez nous (rendu en double)
- un seul point de sortie (echoMessages) : étiquette toujours retirée,
raisonnement retiré pour une API externe, un autre modèle, un message sans
texte ni appel, ou si la sonde dit que le gabarit ne le rend jamais
- comptage : estimateTokens/compactBounds comptent ce qui part et que le
gabarit rend (passé seulement si la sonde dit qu'il le garde, ou l'ignore) ;
ctxAfter ne retire plus un raisonnement renvoyé
- débordement : relance d'abord sans raisonnement, avant toute compaction ;
shrinkToFit retire le raisonnement le plus ancien avant tout le reste ;
le torse compacté le perd comme le résumé
- erreur de gabarit (raise_exception, thinking, Failed to parse messages) :
relance une fois sans raisonnement avant tool_choice none / outils coupés ;
retenu pour le modèle si la relance passe
- runBuilderTurn applique enfin NewHistory comme generate (compaction perdue
pendant une passe de correction) ; forwardStream affiche la bannière
- sonde de gabarit : nouveau verdict renders_reasoning
- REASONING_PRESERVE (lot 1) inchangée, son interaction documentée
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>