mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-21 05:58:13 +02:00
Contexte : PROJ_SNAPSHOT fige le bloc projet par discussion, ses changements arrivent en mise à jour, en opt-in
Le contexte du projet (description, index mémoire, trackers, AGENTS.md) part en tête du premier message utilisateur, reconstruit à chaque tour : une page créée ou une valeur de tracker notée faisait recalculer toute la conversation derrière lui, 10 à 45k tokens. Nouvelle clé PROJ_SNAPSHOT (off par défaut) : avec on, chaque discussion garde une copie datée du bloc, renvoyée à l'octet près, et les changements arrivent en tête du message suivant dans un bloc <context_update from="loki">, rangé dans l'historique. Sans la clé, la requête est identique à l'octet près (testé contre l'ancien assemblage). - en-têtes figés « as of <date> » pour l'index mémoire et les trackers, sans « answer straight from this » ; ligne fixe du système, seulement avec la clé - mises à jour par type : +/~/- par page (clé « ](fichier) »), une ligne complète par tracker (clé = slug), texte COMPLET pour la description, AGENTS.md, ou un index dont la prose a changé — jamais de diff de prose - état annoncé structuré et persisté (ProjSnap, omitempty), instantané pris sur marqueur explicite : la première page d'un projet vide arrive en mise à jour, le premier message ne bouge pas - rafraîchi (blocs retirés de tout l'historique) quand le prompt change de toute façon : compaction début/fin/manuelle, compaction ou réduction en cours de tour (bloc vivant aussitôt, rangé comme instantané : pas de recalcul de plus), système ou outils modifiés, redémarrage de Loki, réglage moteur ou modèle, projet, nom, mode mémoire, mode Code, dépôt, textes des en-têtes ; et au-delà d'un seuil de mises à jour accumulées - mise à jour posée sous c.mu avec l'epoch, après la compaction de début de tour ; texte ou multimodal ; retirée du titre, de l'export JSON, de l'entrée du résumeur et de la tâche du vérificateur - loadFrom, Reset et le chargement remettent l'instantané à zéro ; clé retirée = nettoyage ; agent off = rien du projet ; tâches et presets externes inchangés ; un sous-agent ne voit pas le bloc du tour - ordre des trackers déjà déterministe (lot 1, test existant) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7c9aa04fd9
commit
4932999d5c
13 files changed
+1444
-49
No files matched your search
@@ -156,13 +156,13 @@ func (c *Conversation) runBuilderTurn(ctx context.Context, caps Caps, temperatur
|
||||
|
||||
// Même contexte que le tour de build : projet (description, index mémoire,
|
||||
// trackers) et consignes du dépôt. Sans eux, la reprise changeait le début
|
||||
// du premier message utilisateur — tout le cache de prompt à refaire.
|
||||
final := append(projectSystemMessages(), msgs...)
|
||||
if m, ok := codeInstructionsMessage(caps); ok {
|
||||
final = append([]Message{m}, final...)
|
||||
}
|
||||
if sp := readSysPrompt(); sp != "" {
|
||||
final = append([]Message{{Role: "system", Content: sp}}, final...)
|
||||
// du premier message utilisateur — tout le cache de prompt à refaire. Même
|
||||
// assemblage aussi (turnView) : avec PROJ_SNAPSHOT, le bloc figé de la
|
||||
// discussion, et ses changements en tête de la consigne.
|
||||
sent, tools, snapTurn := c.turnView(caps, epoch, msgs, true)
|
||||
runCtx := ctx
|
||||
if snapTurn != nil {
|
||||
runCtx = withProjSnapTurn(ctx, snapTurn)
|
||||
}
|
||||
var content strings.Builder
|
||||
sawUsage := false
|
||||
@@ -171,8 +171,7 @@ func (c *Conversation) runBuilderTurn(ctx context.Context, caps Caps, temperatur
|
||||
// raisonnement de la réponse finale (REASONING_ECHO).
|
||||
var newBase []Message
|
||||
var echo *ReasoningEcho
|
||||
sent, tools := prepareTurn(final, caps)
|
||||
extra, _ := runChatTools(ctx, sent, tools, temperature, caps, func(ev StreamEvent) bool {
|
||||
extra, _ := runChatTools(runCtx, sent, tools, temperature, caps, func(ev StreamEvent) bool {
|
||||
if ev.Stats != nil && ev.Stats.PromptTokensTotal > 0 {
|
||||
sawUsage = true
|
||||
}
|
||||
@@ -206,6 +205,9 @@ func (c *Conversation) runBuilderTurn(ctx context.Context, caps Caps, temperatur
|
||||
if newBase != nil {
|
||||
c.Messages = newBase
|
||||
}
|
||||
if s := snapTurn.takeRefreshed(); s != nil {
|
||||
c.ProjSnap = s // même règle que generate
|
||||
}
|
||||
c.Messages = append(c.Messages, extra...)
|
||||
if s := content.String(); strings.TrimSpace(s) != "" {
|
||||
c.Messages = append(c.Messages, withEcho(Message{Role: "assistant", Content: s}, echo))
|
||||
@@ -300,7 +302,9 @@ func (c *Conversation) forwardStream(ev StreamEvent, epoch int, isolated bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// lastUserText retrouve le dernier message utilisateur du fil (la tâche).
|
||||
// lastUserText retrouve le dernier message utilisateur du fil (la tâche), sans
|
||||
// la mise à jour du projet que Loki a pu poser en tête (PROJ_SNAPSHOT) : le
|
||||
// vérificateur la prendrait pour une partie de la demande.
|
||||
func (c *Conversation) lastUserText() string {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
@@ -309,7 +313,8 @@ func (c *Conversation) lastUserText() string {
|
||||
if c.Messages[i].Role != "user" || isLokiInjected(c.Messages[i]) {
|
||||
continue
|
||||
}
|
||||
if s, ok := c.Messages[i].Content.(string); ok {
|
||||
m, _ := withoutCtxUpdate(c.Messages[i])
|
||||
if s, ok := m.Content.(string); ok {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user