Mode Code : le compactage garde les fichiers touchés, les erreurs et les critères

Repris du COMPACTION_PROMPT d'OpenFox.

Après un compactage, le builder réécrivait des fichiers déjà faits et
retombait dans des erreurs déjà résolues : le résumé, pensé pour le chat,
ne gardait ni l'un ni l'autre. Et les critères, qui ne vivent pas dans le
fil (seuls les appels à l'outil criteria y passent), disparaissaient avec
le torse résumé.

- En mode Code, le résumé garde aussi chaque fichier créé ou modifié, les
  erreurs rencontrées et leur résolution, et les commandes de build/test.
- L'état des critères est rendu au builder dans le message de résumé — un
  message de toute façon neuf, donc sans cache invalidé en plus.

(Au passage : gofmt sur code_git.go, mal aligné au commit précédent.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5.5 committed 2026-10-02 23:38:07 +02:00
1 parent d5632e3595
commit 15495431fc
3 files changed
+78 -3

No files matched your search

+48
View File
@@ -1,6 +1,10 @@
package loki
import (
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
)
@@ -204,3 +208,47 @@ func TestCompactSansResumeNeDoublePasLaDemande(t *testing.T) {
t.Fatalf("demande en cours présente %d fois après compactage, attendu 1", n)
}
}
// Mode Code : le résumé demande les fichiers touchés et les erreurs, et l'état
// des critères est rendu au builder après compactage.
func TestCompactageModeCodeGardeLEtat(t *testing.T) {
withWorkspace(t)
toolCriteria(map[string]any{"action": "add", "texts": []any{"les tests passent"}}, false)
var sys string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var body struct {
Messages []Message `json:"messages"`
}
_ = json.NewDecoder(r.Body).Decode(&body)
sys = msgText(body.Messages[0])
sendJSON(w, 200, map[string]any{"choices": []any{map[string]any{"message": map[string]any{"content": "- main.go modifié : la fonction parse corrigée, go build et go test passent"}}}})
}))
t.Cleanup(srv.Close)
u, _ := url.Parse(srv.URL)
if err := SetConfigKey("PORT", u.Port()); err != nil {
t.Fatal(err)
}
page := func(n int) Message {
return tm("sortie de commande " + string(rune('a'+n)) + strings.Repeat("x", 400))
}
msgs := []Message{um("corrige le build"), am("ok"), um("continue")}
for i := 0; i < 10; i++ {
msgs = append(msgs, atc("bash"), page(i))
}
out, changed := compactMessages(t.Context(), msgs, Caps{Agent: true, Code: true})
if !changed {
t.Fatal("pas compacté")
}
if !strings.Contains(sys, "CODING session") {
t.Fatal("consigne de résumé du mode Code absente")
}
found := false
for _, m := range out {
if strings.Contains(msgText(m), "Acceptance criteria (current state)") && strings.Contains(msgText(m), "les tests passent") {
found = true
}
}
if !found {
t.Fatal("critères non rendus après compactage")
}
}