Flux : corrections de relecture — le « +N » d'une écriture ne recompte plus tout le corps

Chaque événement de frappe (un par ligne) appelait bodyLineCount sur le corps
ENTIER pour remplir body_lines : un reste de coût quadratique, léger mais
inutile, puisque argPreview tient déjà le compte des sauts de ligne.

- argPreview.lineCount : même règle que bodyLineCount (saut de ligne final
  sans ligne de plus), en temps constant.
- Le test de décodage par morceaux vérifie l'égalité avec bodyLineCount à
  chaque préfixe (fuzz compris).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5.5 committed 2026-10-04 01:54:19 +02:00
1 parent f1f6cbe4ea
commit 3dff7e0e04
2 files changed
+19 -1

No files matched your search

+16 -1
View File
@@ -822,6 +822,21 @@ func (a *argPreview) value() string { return a.val.String() }
// done : guillemet fermant reçu.
func (a *argPreview) done() bool { return a.phase == 4 }
// lineCount : bodyLineCount(value()) sans relire la valeur. Recompter les '\n'
// de tout le corps à chaque ligne émise restait quadratique.
func (a *argPreview) lineCount() int {
n := a.val.Len()
switch {
case n == 0:
return 0
case a.val.String()[n-1] != '\n':
return a.lines + 1
case n == 1:
return 0 // "\n" seul : bodyLineCount le compte vide
}
return a.lines
}
// bodyTailLines / bodyTailBytes : ce qu'un événement de frappe montre du corps.
const (
bodyTailLines = 40
@@ -1667,7 +1682,7 @@ func runChatTools(ctx context.Context, messages []Message, tools []Tool, tempera
tu := &ToolUsedEvent{Name: cur.Function.Name, Label: lastPreview, Typing: true}
if full != "" {
tu.Body, tu.BodyTail = bodyTail(full)
tu.BodyLines = bodyLineCount(full)
tu.BodyLines = bodyDec.lineCount()
}
if !scb(StreamEvent{ToolUsed: tu}) {
aborted = true
+3
View File
@@ -54,6 +54,9 @@ func checkArgPreview(t *testing.T, args, key string, chunks []string) {
if n := strings.Count(a.value(), "\n"); n != a.lines {
t.Fatalf("lines=%d, la valeur en compte %d", a.lines, n)
}
if n := bodyLineCount(a.value()); n != a.lineCount() {
t.Fatalf("lineCount=%d, bodyLineCount=%d (valeur %q)", a.lineCount(), n, a.value())
}
}
}