mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Une compaction, un dernier message rendu autrement au tour suivant ou une tâche planifiée qui a pris le slot laissent au message suivant un recalcul inévitable : des secondes sur un 27B, des dizaines sur un MoE aux experts en RAM, avant le premier mot. Nouvelle clé PREWARM (off par défaut) : dès que le moteur local est libre, Loki lui envoie la requête du prochain tour suivie d'un message utilisateur « . », max_tokens 1, sans flux. Le moteur calcule le préfixe et pose un point de reprise au début de ce message ; le vrai tour ne calcule plus que le sien. Sans la clé, aucune requête de plus (testé). - assemblage partagé, contenu vivant : turnViewDry (même code que turnView, sans rien toucher à la discussion, décision PROJ_SNAPSHOT via projSnapDecide), wireMessages, turnReasoning et buildChatPayload, extraits de runChat ; corps identique à l'octet près à celui d'avant (matrice d'options et de modes, testée contre une copie de l'ancien code) - jamais devant un vrai travail : toute requête de Loki l'annule au départ (compteur de llm_slots.go, sous son verrou), sauf un tour de chat dont les messages sérialisés, outils et arguments du gabarit prolongent exactement le préfixe préchauffé - moteur local, un seul slot (/props total_slots), pas pendant un tour, une tâche, un bench, un travail annexe ni une requête en vol ; un seul à la fois ; pas si le prochain tour compactera, ni à moins de 10 min de minuit - requête brute : ni compaction, ni relance, ni effort appris, ni CtxUsed, ni stats ; erreurs lâchées (une ligne de journal par statut) ; rien persisté - déclencheurs : fin de tour sans file d'attente, fin de tâche (projet forcé levé, slot effacé) ; full = aussi changement de discussion après 3 s - capacités du dernier tour gardées en mémoire par discussion ; mode Code = rôle d'un message ordinaire, une demande de plan diverge et annule - télémétrie kind=prewarm ; la vérification du cache RAM après une tâche se fait sur lui Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.0 KiB
Go
59 lines
2.0 KiB
Go
package loki
|
|
|
|
// code_roles.go — registre des rôles du mode code. Chaque rôle est un prompt
|
|
// Markdown EMBARQUÉ dans le binaire (agents/*.md), comme le catalogue MCP :
|
|
// pas d'appel réseau, pour en changer on édite le fichier et on recompile.
|
|
// Démarche reprise du registre d'agents d'OpenFox (builder/planner/explorer/
|
|
// verifier/code-reviewer — voir NOTICE.md), prompts réécrits COURTS : un
|
|
// préambule verbeux fait sur-raisonner les modèles locaux (voir le commentaire
|
|
// de baseSystemPrompt).
|
|
|
|
import (
|
|
"embed"
|
|
"strings"
|
|
)
|
|
|
|
//go:embed agents/*.md
|
|
var rolesFS embed.FS
|
|
|
|
// roleNames : les rôles connus. builder et verifier sont pilotés par la boucle
|
|
// du mode code (code_verify.go) ; planner s'active quand l'utilisateur demande
|
|
// un plan ; explorer et code-reviewer sont disponibles pour des passes
|
|
// manuelles futures.
|
|
var roleNames = []string{"builder", "planner", "explorer", "verifier", "code-reviewer"}
|
|
|
|
// rolePrompt renvoie le prompt d'un rôle, "" si inconnu.
|
|
func rolePrompt(name string) string {
|
|
b, err := rolesFS.ReadFile("agents/" + name + ".md")
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(string(b))
|
|
}
|
|
|
|
// planIntentRe-like : l'utilisateur demande-t-il un PLAN plutôt qu'une
|
|
// implémentation ? Heuristique simple sur le début du message.
|
|
func wantsPlan(text string) bool {
|
|
low := strings.ToLower(text)
|
|
for _, kw := range []string{"fais un plan", "fait un plan", "propose un plan", "planifie", "plan d'implémentation", "plan d'action", "make a plan", "plan first"} {
|
|
if strings.Contains(low, kw) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// withTurnRole fige le rôle d'un tour du mode Code d'après son message : plan
|
|
// demandé → planner, sinon builder. Un rôle déjà choisi par le client est gardé.
|
|
// Partagé par StartTurn et le préchauffage (chat_prewarm.go), qui prévoit le
|
|
// rôle le plus probable du prochain message.
|
|
func withTurnRole(caps Caps, text string) Caps {
|
|
if caps.Code && caps.Role == "" {
|
|
caps.Role = "builder"
|
|
if wantsPlan(text) {
|
|
caps.Role = "planner"
|
|
}
|
|
}
|
|
return caps
|
|
}
|