Files
Agent-Native/adapters/native/compact_test.go
T
weichenandCursor 6b7d2432b3
ci / vet-and-test (pull_request) Failing after 2s
ci / docker-checkout-hostgateway (pull_request) Successful in 2s
Serve print, JSON, and RPC modes on AgentSession
Why: The library had no process entry, and the product backend still called the loop directly.
Evidence: go test -count=1 ./...
Impact: exec.Backend keeps the same request and result. Execute now goes through AgentSession. Extensions and packages are not a sandbox.
Refs: feature/pi-headless N6 N7
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 10:16:00 +00:00

73 lines
2.3 KiB
Go

package native
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
"agent-native/exec"
"agent-native/runtime/llm"
)
func TestBackendCompactBeforeRun(t *testing.T) {
dir := t.TempDir()
// 预置一份超阈值的长转录(系统消息 + 12 条历史)。
transcript := filepath.Join(dir, ".agentx", "transcript.jsonl")
if err := os.MkdirAll(filepath.Dir(transcript), 0o755); err != nil {
t.Fatal(err)
}
var b strings.Builder
b.WriteString(`{"role":"system","content":"sys"}` + "\n")
for i := 0; i < 12; i++ {
b.WriteString(`{"role":"user","content":"` + strings.Repeat("x", 400) + `"}` + "\n")
}
if err := os.WriteFile(transcript, []byte(b.String()), 0o644); err != nil {
t.Fatal(err)
}
var sawSummary bool
// 注入式捕获:验证 Run 收到的消息里有摘要标记。
bk2 := New(Options{
Model: "fake",
Stream: captureFirstStream(&sawSummary),
Compact: &CompactConfig{ThresholdChars: 1000, KeepLastN: 3, Summarizer: func(ctx context.Context, messages []llm.Message) (string, error) {
return "预置历史摘要", nil
}},
})
res, err := bk2.Execute(context.Background(), exec.Request{
WorkDir: dir, Prompt: "继续", Targets: []string{"output.md"},
ToolProfile: exec.ToolProfileReasoning,
})
if err != nil {
t.Fatal(err)
}
if res.Success && !sawSummary {
t.Fatal("compaction should have run before the loop")
}
data, _ := os.ReadFile(transcript)
if !strings.Contains(string(data), "预置历史摘要") || !strings.Contains(string(data), `"type":"compaction"`) {
t.Fatalf("transcript should keep history and append a compaction entry, got:\n%.400s", data)
}
if !strings.Contains(string(data), `"role":"system"`) {
t.Fatal("compaction must not rewrite the original transcript")
}
}
func captureFirstStream(saw *bool) llm.StreamFunc {
return func(ctx context.Context, model string, messages []llm.Message, decls []llm.ToolDecl, opts llm.StreamOptions) <-chan llm.Event {
for _, m := range messages {
if strings.Contains(m.Content, "[conversation summary]") {
*saw = true
}
}
ch := make(chan llm.Event, 4)
go func() {
defer close(ch)
ch <- llm.Event{Kind: llm.KindMessageEnd, Message: llm.Message{Role: llm.RoleAssistant, Content: "压缩后续写完成", StopReason: llm.StopEnd}}
}()
return ch
}
}