diff --git a/modules/interaction/domain/gen2_context_test.go b/modules/interaction/domain/gen2_context_test.go index 0d37bf5..937df92 100644 --- a/modules/interaction/domain/gen2_context_test.go +++ b/modules/interaction/domain/gen2_context_test.go @@ -27,3 +27,12 @@ func TestGen2ContextDoesNotProjectAnotherPrincipal(t *testing.T) { t.Fatalf("scoped context=%#v", got) } } + +func TestGen2ContextProjectsExplicitRememberedAssertion(t *testing.T) { + got := domain.BuildScopedGen2Context([]interaction.HumanUtterance{ + {ID: "assertion", PrincipalID: "principal-1", Content: "Для этого разговора запомни: мой тестовый цвет — синий.", ReceivedAtUnixMillis: 1}, + }, "principal-1") + if got.Source != "retrieval:interaction-utterances" || got.UsedPersonalMemoryFallback || !strings.Contains(got.Text, "тестовый цвет — синий") { + t.Fatalf("remembered assertion was not projected: %#v", got) + } +} diff --git a/modules/interaction/domain/personal_memory.go b/modules/interaction/domain/personal_memory.go index e759bd7..7ecd3a0 100644 --- a/modules/interaction/domain/personal_memory.go +++ b/modules/interaction/domain/personal_memory.go @@ -123,5 +123,31 @@ func personalPreference(message string) string { return value } } + // Explicit remembered assertions are still human-provided context, not + // verified facts. Project the compact key/value statement without storing a + // second copy outside the canonical utterance history. + if index := strings.Index(lower, "запомни"); index >= 0 { + remembered := strings.TrimSpace(lower[index+len("запомни"):]) + remembered = strings.TrimLeft(remembered, " :—-") + for _, prefix := range []string{"мой ", "моя ", "моё ", "мое "} { + if !strings.HasPrefix(remembered, prefix) { + continue + } + statement := strings.TrimSpace(remembered[len(prefix):]) + separator := strings.IndexAny(statement, "—-:") + if separator <= 0 || separator >= len(statement)-1 { + continue + } + key := strings.TrimSpace(statement[:separator]) + separatorWidth := 1 + if strings.HasPrefix(statement[separator:], "—") { + separatorWidth = len("—") + } + value := strings.Trim(strings.TrimSpace(statement[separator+separatorWidth:]), " .,!?:;—-") + if key != "" && len([]rune(value)) >= 2 { + return key + " — " + value + } + } + } return "" }