Files
Agent-System/internal/ctxmgr/summarizer_test.go
T

110 lines
3.3 KiB
Go

package ctxmgr
import (
"context"
"strings"
"testing"
"time"
)
func TestRollingSummarizer_LifecycleAndFactPreservation(t *testing.T) {
mgr := NewContextManager(nil, nil, DefaultTimeDecayConfig())
ctx := context.Background()
sessID := "sess_sum_test_001"
// 模拟首批 4 条早期消息(将被淘汰出窗口)
batch1 := []ChatMessageRecord{
{
ID: 1,
Role: "user",
Content: "我们准备研发高频超声手术刀系统,请教立项建议",
CreatedAt: time.Now().Add(-10 * time.Minute),
},
{
ID: 2,
Role: "assistant",
Content: "超声手术设备属于二类或三类器械,需着重关注电气安全与空化热效应控制。",
CreatedAt: time.Now().Add(-9 * time.Minute),
},
{
ID: 3,
Role: "user",
Content: "目标市场是国内及欧洲CE,项目预算大约在200万左右,型检周期通常需要多久?",
CreatedAt: time.Now().Add(-8 * time.Minute),
},
{
ID: 4,
Role: "assistant",
Content: "国内型检通常预估4-6个月,需符合GB 9706.1-2020标准。",
CreatedAt: time.Now().Add(-7 * time.Minute),
},
}
sum1, err := mgr.GenerateRollingSummary(ctx, sessID, nil, batch1)
if err != nil {
t.Fatalf("GenerateRollingSummary failed: %v", err)
}
if sum1.CoveredCount != 4 {
t.Errorf("expected covered_count 4, got %d", sum1.CoveredCount)
}
if sum1.Facts["device_type"] != "超声手术设备" {
t.Errorf("expected device_type extracted, got %v", sum1.Facts)
}
if sum1.Facts["target_market"] != "国内及欧洲CE" {
t.Errorf("expected target_market extracted, got %v", sum1.Facts)
}
if sum1.Facts["budget"] != "200万元" {
t.Errorf("expected budget extracted, got %v", sum1.Facts)
}
if len(sum1.OpenQuestions) == 0 {
t.Errorf("expected at least 1 open question extracted")
}
snippet1 := sum1.RenderPromptSnippet()
if !strings.Contains(snippet1, "【早期对话摘要】(已压缩前 4 条对话内容)") {
t.Errorf("snippet missing header: %s", snippet1)
}
if !strings.Contains(snippet1, "device_type=超声手术设备") {
t.Errorf("snippet missing device_type: %s", snippet1)
}
// 模拟第二批消息追加(增量滚动压缩)
batch2 := []ChatMessageRecord{
{
ID: 5,
Role: "user",
Content: "临床评价路径该怎么走?",
CreatedAt: time.Now().Add(-5 * time.Minute),
},
{
ID: 6,
Role: "assistant",
Content: "可优先考虑同品种比对路径以节省费用。",
CreatedAt: time.Now().Add(-4 * time.Minute),
},
}
sum2, err := mgr.GenerateRollingSummary(ctx, sessID, sum1, batch2)
if err != nil {
t.Fatalf("incremental GenerateRollingSummary failed: %v", err)
}
if sum2.CoveredCount != 6 {
t.Errorf("expected covered_count 6, got %d", sum2.CoveredCount)
}
// 验证硬事实依然完整保留(永不丢失)
if sum2.Facts["device_type"] != "超声手术设备" || sum2.Facts["budget"] != "200万元" {
t.Errorf("hard facts lost during incremental roll: %v", sum2.Facts)
}
// 验证 ContextManager 的读取
saved, err := mgr.GetChatSummary(ctx, sessID)
if err != nil || saved == nil {
t.Fatalf("GetChatSummary failed: %v", err)
}
if saved.CoveredCount != 6 {
t.Errorf("saved summary covered count mismatch: %d", saved.CoveredCount)
}
}