Files
Loki/internal/loki/llm_steer_test.go
T
Loki 73196a1ff6 Erreur 500 : la consigne de repli ne doit pas casser le gabarit du modèle
Après un 500 de llama-server, l'amont relance le tour sans outils en ajoutant
une consigne système À LA FIN de la conversation. Or plusieurs gabarits
exigent que le message système soit le PREMIER : gpt-oss (rôle « developer »)
lève « System message must be at the beginning ». La tentative de
récupération produisait donc elle-même un 500, et cette exception Jinja
remplaçait l'erreur d'origine sous les yeux de l'utilisateur.

steerSystem fusionne désormais la consigne dans le message système de tête,
ou la pose en première position s'il n'y en a pas — jamais ailleurs. La liste
de l'appelant n'est pas modifiée.

Tests : fusion sans ajout de message, création en tête quand il n'y a pas de
système, et non-modification de la liste d'origine.
2026-08-15 14:36:04 +00:00

52 lines
1.8 KiB
Go

package loki
import "testing"
// Plusieurs gabarits de conversation exigent que le message système soit le
// PREMIER — gpt-oss lève « System message must be at the beginning ». La
// consigne posée en cours de tour (repli après un 500) ne doit donc jamais
// arriver en fin de liste, sinon la tentative de récupération échoue à son tour
// et masque l'erreur d'origine.
func TestSteerSystemResteEnTete(t *testing.T) {
hint := "N'appelle plus d'outil."
t.Run("fusionne dans le système existant", func(t *testing.T) {
msgs := []Message{
{Role: "system", Content: "Tu es Loki."},
{Role: "user", Content: "bonjour"},
{Role: "assistant", Content: "salut"},
}
out := steerSystem(msgs, hint)
if len(out) != len(msgs) {
t.Fatalf("%d messages, attendu %d : aucun message ne doit être ajouté", len(out), len(msgs))
}
if got := out[0].Content.(string); got != "Tu es Loki.\n\n"+hint {
t.Fatalf("consigne non fusionnée en tête : %q", got)
}
for i, m := range out[1:] {
if m.Role == "system" {
t.Fatalf("message système en position %d — il doit rester unique et en tête", i+1)
}
}
})
t.Run("sans système existant, il est posé en tête", func(t *testing.T) {
msgs := []Message{{Role: "user", Content: "bonjour"}}
out := steerSystem(msgs, hint)
if out[0].Role != "system" || out[0].Content.(string) != hint {
t.Fatalf("premier message = %+v, attendu le système", out[0])
}
if out[1].Role != "user" {
t.Fatalf("la conversation d'origine doit suivre, obtenu %+v", out[1])
}
})
t.Run("ne modifie pas la liste d'origine", func(t *testing.T) {
msgs := []Message{{Role: "system", Content: "Tu es Loki."}, {Role: "user", Content: "bonjour"}}
_ = steerSystem(msgs, hint)
if got := msgs[0].Content.(string); got != "Tu es Loki." {
t.Fatalf("liste d'appelant modifiée : %q", got)
}
})
}