package memory import ( "context" "errors" "testing" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model" ) func TestManualExtractor_Extract_ParseRemember_正常(t *testing.T) { t.Parallel() ex := NewManualExtractor("persona.a", "role.1") conversation := []model.Message{ model.TextMessage(model.RoleUser, "记住她喜欢喝冰美式"), model.TextMessage(model.RoleAssistant, "好的,我记住了"), model.TextMessage(model.RoleUser, "今天天气不错"), // 无指令 model.TextMessage(model.RoleUser, "请记住周三下午有项目会"), } items, err := ex.Extract(context.Background(), conversation) if err != nil { t.Fatalf("Extract: %v", err) } if len(items) != 2 { t.Fatalf("got %d items, want 2", len(items)) } if items[0].Content != "她喜欢喝冰美式" { t.Errorf("items[0].Content = %q, want the stripped directive", items[0].Content) } if items[0].PersonaID != "persona.a" || items[0].RoleID != "role.1" { t.Errorf("items[0] persona/role = %q/%q, want persona.a/role.1", items[0].PersonaID, items[0].RoleID) } if items[1].Content != "周三下午有项目会" { t.Errorf("items[1].Content = %q, want the 请记住 content", items[1].Content) } } func TestManualExtractor_Extract_NoRemember_正常(t *testing.T) { t.Parallel() ex := NewManualExtractor("persona.a", "role.1") conversation := []model.Message{ model.TextMessage(model.RoleUser, "今天天气不错"), model.TextMessage(model.RoleUser, "记得带伞吗"), model.TextMessage(model.RoleAssistant, "记住是记忆"), // 非用户角色跳过 } items, err := ex.Extract(context.Background(), conversation) if err != nil { t.Fatalf("Extract: %v", err) } if len(items) != 0 { t.Fatalf("got %d items, want 0", len(items)) } } func TestManualExtractor_Extract_Canceled_异常(t *testing.T) { t.Parallel() ex := NewManualExtractor("persona.a", "role.1") ctx, cancel := context.WithCancel(context.Background()) cancel() if _, err := ex.Extract(ctx, []model.Message{model.TextMessage(model.RoleUser, "记住x")}); !errors.Is(err, context.Canceled) { t.Fatalf("Extract with canceled ctx err = %v, want context.Canceled", err) } } func TestStore_RememberManual_正常(t *testing.T) { t.Parallel() ctx := context.Background() s := newTestStore(t) item, err := s.RememberManual(ctx, "persona.a", "role.1", "记住她喜欢喝咖啡") if err != nil { t.Fatalf("RememberManual: %v", err) } // 落库内容保留指令原文;这是手动单条目 // 路径,与会剥离指令的提取器不同。 if item.Content != "记住她喜欢喝咖啡" { t.Fatalf("RememberManual content = %q, want the passed text", item.Content) } if item.PersonaID != "persona.a" || item.Scope != ScopePersona || item.Kind != KindRelationship { t.Fatalf("item persona/scope/kind = %q/%q/%q, want persona.a/persona/relationship", item.PersonaID, item.Scope, item.Kind) } got, err := s.Get(ctx, item.ID) if err != nil { t.Fatalf("Get: %v", err) } if got.Content != item.Content { t.Fatalf("persisted content = %q, want %q", got.Content, item.Content) } } func TestStore_RememberManual_Empty_异常(t *testing.T) { t.Parallel() ctx := context.Background() s := newTestStore(t) for _, text := range []string{"", " "} { if _, err := s.RememberManual(ctx, "persona.a", "role.1", text); !errors.Is(err, ErrMissingContent) { t.Fatalf("RememberManual(%q) err = %v, want ErrMissingContent", text, err) } } }