diff --git a/cmd/core-runtime/main.go b/cmd/core-runtime/main.go index f1e7e31..6cdc620 100644 --- a/cmd/core-runtime/main.go +++ b/cmd/core-runtime/main.go @@ -1796,7 +1796,13 @@ func humanMemoryInventory(history []interaction.HumanUtterance, assistantName st lower := strings.ToLower(message) if (strings.Contains(lower, "нравится") || strings.Contains(lower, "люблю")) && utterance.ReceivedAtUnixMillis >= latestPreferenceAt { latestPreferenceAt = utterance.ReceivedAtUnixMillis - latestPreference = message + latestPreference = strings.TrimSpace(message) + for _, prefix := range []string{"запомни:", "запомни", "помни:"} { + if strings.HasPrefix(strings.ToLower(latestPreference), prefix) { + latestPreference = strings.TrimSpace(latestPreference[len(prefix):]) + break + } + } } } if latestPreference != "" { diff --git a/modules/interaction/domain/chat.go b/modules/interaction/domain/chat.go index d939408..62037ed 100644 --- a/modules/interaction/domain/chat.go +++ b/modules/interaction/domain/chat.go @@ -304,6 +304,10 @@ func semanticScores(tokens []string, hasQuestionMark bool, explicitCorrection bo scores[interaction.SpeechActPreference] += 8 scores[interaction.SpeechActAssertion] = 0 } + if containsToken(tokens, "запомни") && containsStemInTokens(tokens, "нрав", "люб", "предпочит") { + scores[interaction.SpeechActPreference] += 6 + scores[interaction.SpeechActAssertion] = 0 + } if len(tokens) >= 2 && tokens[0] == "я" && containsStemInTokens(tokens[1:], "настро", "сдела", "исправ", "удал", "созда", "перезапуст", "поменя", "добави") { scores[interaction.SpeechActAssertion] += 5 } diff --git a/modules/interaction/domain/chat_test.go b/modules/interaction/domain/chat_test.go index 5275d70..ccd696e 100644 --- a/modules/interaction/domain/chat_test.go +++ b/modules/interaction/domain/chat_test.go @@ -254,6 +254,16 @@ func TestMemoryInventoryRequestIsSemantic(t *testing.T) { } } +func TestRememberedPreferenceIsNotRenderedAsIdentity(t *testing.T) { + result := BuildDeterministicCandidate("запомни: мне нравится красный цвет", "", time.Unix(10, 0).UnixMilli()) + if result.PrimarySpeechAct != interaction.SpeechActPreference { + t.Fatalf("expected remembered preference, got %+v", result) + } + if got := semanticReply("запомни: мне нравится красный цвет", SemanticResult{Interpretation: interaction.UtteranceInterpretation{SpeechAct: result.PrimarySpeechAct}}, nil); got != "Хорошо, учту это дальше." { + t.Fatalf("unexpected preference reply %q", got) + } +} + func TestCreativeRequestsDoNotRouteToWebResearch(t *testing.T) { for _, message := range []string{"нарисуй круг", "расскажи сказку о колобке"} { candidate := BuildDeterministicCandidate(message, "", time.Now().UnixMilli())