mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-24 15:38:12 +02:00
Cache : KEEP_TURN_IMAGES garde les images d'outils et NUDGE_IN_TOOL range le rappel de budget, en opt-in
Une capture ou une image vue par see_image ne vivait que le temps du tour : au tour suivant elle manquait à l'historique, le préfixe en cache divergeait à elle et toute la boucle d'outils qui suivait était recalculée. Sur Qwen3.5, le rappel de budget en message user faisait de même pour le tour en cours : le nouveau message devient la « dernière question » et tout le tour est rendu autrement. Deux clés, off par défaut et étiquetées zone grise ; sans elles, requêtes identiques à l'octet près (testé). - KEEP_TURN_IMAGES : image gardée par référence (chatimg, chiffrée si la mémoire l'est), relue à l'identique avant d'être gardée, vision active revérifiée à chaque tour ; preset externe seulement s'il déclare la vision - coût mesuré par le moteur (écart de prompt_tokens moins le texte ajouté) ; image non mesurable = éphémère comme avant ; total sous 10 % de la fenêtre, la première qui dépasse et les suivantes du tour restent éphémères - compaction, réduction forcée et début ou milieu de tour au seuil retirent ces images d'abord (légende et imageLostMarker gardés), le résumé ne suit que s'il reste nécessaire ; clé retirée ou vision perdue : retirées au tour - relais marqué ImgRelay (persisté, retiré à l'envoi) : ni demande réinjectée ni preuve de demande servie, fil rouvert compris ; une image non gardée n'entre plus dans l'historique par une compaction en cours de tour - discussion seulement (ni tâche, ni sous-agent, ni vérification) ; fichier d'image rafraîchi à chaque usage, l'élagage de 24 h ne le prend pas - NUDGE_IN_TOOL : rappel de budget au bout du dernier résultat d'outil, même message persisté ; moteur local, sonde de gabarit « préfixe instable » pour ce modèle ; sinon, ou forme inattendue, message à part comme avant Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b0c53e32af
commit
f74f64ed90
9 files changed
+1153
-5
No files matched your search
@@ -55,6 +55,11 @@ func isLokiInjected(m Message) bool {
|
||||
if m.Role != "user" {
|
||||
return false
|
||||
}
|
||||
// Relais d'image d'un outil gardé dans l'historique (KEEP_TURN_IMAGES) :
|
||||
// une image montrée par loki, pas une demande. Jamais posé sans la clé.
|
||||
if m.ImgRelay {
|
||||
return true
|
||||
}
|
||||
s, ok := m.Content.(string)
|
||||
if !ok {
|
||||
return false
|
||||
@@ -156,3 +161,54 @@ func withTrailingHint(msgs []Message, hint string) []Message {
|
||||
// Dernier message d'une autre forme (cas théorique) : un message à part.
|
||||
return append(out, Message{Role: "user", Content: lokiNotePrefix + hint})
|
||||
}
|
||||
|
||||
// nudgeInToolOn : NUDGE_IN_TOOL (opt-in, off par défaut, ZONE GRISE). Sur un
|
||||
// gabarit dont le rendu d'un tour d'outil change dès qu'un message `user`
|
||||
// s'ajoute (Qwen3.5 : le nouveau message devient la « dernière question », et
|
||||
// tous les messages assistant du tour sont rendus autrement), le rappel de
|
||||
// budget en message à part fait recalculer toute la boucle d'outils du tour.
|
||||
// Posé au bout du dernier résultat d'outil, il ne coûte que lui-même.
|
||||
//
|
||||
// Le prix : une consigne glissée dans une sortie d'outil, que les modèles
|
||||
// entraînés contre l'injection de prompt peuvent suivre moins bien — d'où
|
||||
// l'opt-in, à n'activer qu'après avoir comparé l'obéissance aux rappels.
|
||||
//
|
||||
// Moteur local seulement, et seulement si la sonde de gabarit
|
||||
// (chat_tplprobe.go) a conclu « préfixe instable » pour CE modèle : « inconnu »
|
||||
// ou un autre modèle laissent le message à part.
|
||||
func nudgeInToolOn(cfg map[string]string, ep chatEndpoint) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(cfg["NUDGE_IN_TOOL"])) {
|
||||
case "on", "1", "true", "yes", "oui":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
if ep.External {
|
||||
return false
|
||||
}
|
||||
r, ok := tplCapsCurrent()
|
||||
return ok && r.PrefixStable == tplNo && r.Model != "" && r.Model == reasoningEchoModel(cfg)
|
||||
}
|
||||
|
||||
// nudgeIntoTool ajoute le rappel au bout du dernier résultat d'outil, dans la
|
||||
// vue du modèle ET dans l'historique — le même message, modifié des deux côtés
|
||||
// à l'identique, pour que le tour suivant rejoue les mêmes octets. Ce résultat
|
||||
// n'est pas encore parti au moteur : rien de ce qu'il a en cache ne bouge.
|
||||
// ok=false (dernier message d'une autre forme, historique réécrit entre-temps
|
||||
// par une compaction) : l'appelant passe par appendNudge. Copies, jamais de
|
||||
// modification en place.
|
||||
func nudgeIntoTool(messages, extra []Message, text string) ([]Message, []Message, bool) {
|
||||
n, e := len(messages), len(extra)
|
||||
if n == 0 || e == 0 {
|
||||
return messages, extra, false
|
||||
}
|
||||
last, kept := messages[n-1], extra[e-1]
|
||||
s, ok := last.Content.(string)
|
||||
ks, kok := kept.Content.(string)
|
||||
if !ok || !kok || s != ks || last.Role != "tool" || kept.Role != "tool" || last.ToolCallID != kept.ToolCallID {
|
||||
return messages, extra, false
|
||||
}
|
||||
last.Content = s + "\n\n" + text
|
||||
messages = append(messages[:n-1:n-1], last)
|
||||
extra = append(extra[:e-1:e-1], last)
|
||||
return messages, extra, true
|
||||
}
|
||||
Reference in new issue
Block a user