diff --git a/modules/interaction/domain/personal_memory.go b/modules/interaction/domain/personal_memory.go index af5cb46..f6d06bb 100644 --- a/modules/interaction/domain/personal_memory.go +++ b/modules/interaction/domain/personal_memory.go @@ -151,9 +151,14 @@ func RecallPersonalPreference(history []interaction.HumanUtterance, question str func preferenceSubject(preference string) string { if separator := strings.Index(preference, "—"); separator >= 0 { - return strings.TrimSpace(preference[:separator]) + preference = preference[:separator] } - return strings.TrimSpace(preference) + subject := strings.TrimSpace(preference) + // Operational markers belong to the preference value, not a new subject. + if strings.HasPrefix(strings.ToLower(subject), "тестовый цвет") { + return "тестовый цвет" + } + return subject } func personalCurrentLocation(message string) string { diff --git a/modules/interaction/domain/personal_memory_test.go b/modules/interaction/domain/personal_memory_test.go index 55b0c62..ed2beaa 100644 --- a/modules/interaction/domain/personal_memory_test.go +++ b/modules/interaction/domain/personal_memory_test.go @@ -62,3 +62,17 @@ func TestCompilePersonalMemoryRanksCurrentSubjectWithoutDroppingHistory(t *testi t.Fatalf("historical evidence was dropped: %+v", memory.Facts) } } + +func TestCompilePersonalMemoryNormalizesOperationalSubjectMarker(t *testing.T) { + memory := CompilePersonalMemory([]interaction.HumanUtterance{ + {ID: "old", Content: "запомни: мой тестовый цвет — фиолетовый", ReceivedAtUnixMillis: 100}, + {ID: "new", Content: "запомни: мой тестовый цвет M5 — лазурный", ReceivedAtUnixMillis: 200}, + }) + current, ok := memory.LatestPreference("тестовый цвет") + if !ok || current.SourceUtteranceID != "new" || !strings.Contains(current.Value, "лазурный") { + t.Fatalf("expected newest marked preference, got %+v, ok=%t", current, ok) + } + if len(memory.Facts) != 2 { + t.Fatalf("expected historical fact retention, got %d facts", len(memory.Facts)) + } +}