ollie/cmd/olliesrv/internal/agent/history_summary_test.go

116 lines
3.8 KiB
Go

package agent
import (
"context"
"fmt"
"strings"
"testing"
"ollie/cmd/olliesrv/internal/backend"
)
func TestParseColdSummariesJSON(t *testing.T) {
got, err := parseColdSummaries(`{"0":"summary","1":"another"}`)
if err != nil {
t.Fatal(err)
}
if got["0"] != "summary" || got["1"] != "another" {
t.Fatalf("unexpected summaries: %#v", got)
}
}
func TestParseColdSummariesFencedJSON(t *testing.T) {
got, err := parseColdSummaries("```json\n{\"0\":\"summary\"}\n```")
if err != nil {
t.Fatal(err)
}
if got["0"] != "summary" {
t.Fatalf("unexpected summaries: %#v", got)
}
}
func TestParseColdSummariesRejectsInvalidJSON(t *testing.T) {
if _, err := parseColdSummaries("not JSON"); err == nil {
t.Fatal("parseColdSummaries accepted invalid JSON")
}
}
func TestStripColdSkipsAlreadySummarized(t *testing.T) {
b := &summaryBackend{}
h := newHistory("test")
for i := 0; i < 9; i++ {
m := backend.Message{Role: "user", Content: "hot"}
if i == 0 {
m = backend.Message{Role: "tool", ToolCallID: fmt.Sprintf("tc-%d", i), Content: strings.Repeat("x", 300)}
}
h.messages = append(h.messages, m)
}
ctx := context.Background()
if _, _ = h.stripCold(ctx, b); b.calls != 1 {
t.Fatalf("first stripCold calls = %d, want 1", b.calls)
}
if _, _ = h.stripCold(ctx, b); b.calls != 1 {
t.Fatalf("second stripCold calls = %d, want 1", b.calls)
}
}
func TestStripColdReusesSummaryCache(t *testing.T) {
b := &summaryBackend{}
h := newHistory("test")
for i := 0; i < 9; i++ {
m := backend.Message{Role: "user", Content: "hot"}
if i < 1 {
m = backend.Message{Role: "tool", ToolCallID: "tc-0", Content: strings.Repeat("same result ", 30)}
}
h.messages = append(h.messages, m)
}
if _, _ = h.stripCold(context.Background(), b); b.calls != 1 {
t.Fatalf("first stripCold calls = %d, want 1", b.calls)
}
original := strings.Repeat("same result ", 30)
h.messages[0].Content = original
h.messages[0].SummaryApplied = false
if _, _ = h.stripCold(context.Background(), b); b.calls != 1 {
t.Fatalf("cached stripCold calls = %d, want 1", b.calls)
}
if !h.messages[0].SummaryApplied || h.messages[0].Content != "summary" {
t.Fatalf("cached summary was not applied: %#v", h.messages[0])
}
}
func TestStripColdSkipsAlreadySummarizedAfterRestore(t *testing.T) {
b := &summaryBackend{}
h := RestoreHistoryFromMessages([]backend.Message{
{Role: "tool", ToolCallID: "tc-0", Content: strings.Repeat("summary ", 30), SummaryApplied: true},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
{Role: "user", Content: "hot"},
})
if _, _ = h.stripCold(context.Background(), b); b.calls != 0 {
t.Fatalf("restored summarized history calls = %d, want 0", b.calls)
}
}
type summaryBackend struct{ calls int }
func (b *summaryBackend) ChatStream(_ context.Context, messages []backend.Message, _ []backend.Tool, _ backend.GenerationParams) (<-chan backend.StreamEvent, error) {
b.calls++
if len(messages) != 1 || !strings.Contains(messages[0].Content, "id=tool:tc-0:") {
return nil, fmt.Errorf("summary request did not use stable message ID")
}
out := make(chan backend.StreamEvent, 1)
out <- backend.StreamEvent{Content: `{"tool:tc-0":"summary"}`, Done: true}
close(out)
return out, nil
}
func (b *summaryBackend) Name() string { return "test" }
func (b *summaryBackend) DefaultModel() string { return "test" }
func (b *summaryBackend) Model() string { return "test" }
func (b *summaryBackend) SetModel(string) {}
func (b *summaryBackend) ContextLength(context.Context) int { return 128000 }
func (b *summaryBackend) Models(context.Context) []string { return []string{"test"} }