From 8ac45255693dbfb65ec77850b8ba1519b75f529c Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sat, 29 Aug 2026 23:14:15 +0300 Subject: [PATCH] route recalled memory through local cognitive review --- cmd/core-runtime/main.go | 5 ++++ modules/interaction/domain/personal_memory.go | 24 +++++++++++++++++++ .../domain/personal_memory_test.go | 9 +++++++ 3 files changed, 38 insertions(+) diff --git a/cmd/core-runtime/main.go b/cmd/core-runtime/main.go index 9f7d259..7c1679d 100644 --- a/cmd/core-runtime/main.go +++ b/cmd/core-runtime/main.go @@ -576,6 +576,7 @@ func main() { } conversationHistory = append(conversationHistory, recentUserHistory...) gen2Context := interactiondomain.BuildScopedGen2Context(conversationHistory, string(session.PrincipalID)) + retrievedMemoryReply := interactiondomain.RecallPersonalPreference(conversationHistory, effectiveTaskMessage) if !creativeUserRequest && locationReply == "" { if continuation := interactiondomain.ContinueLocalSearch(effectiveTaskMessage, conversationHistory); continuation != "" { continuationMessage = continuation @@ -842,6 +843,10 @@ func main() { researchBacked := false researchAttempted := false stableKnowledgeReply := false + if retrievedMemoryReply != "" { + planningReply = retrievedMemoryReply + needsCognition = false + } if hasChatRoute(routePlan, chatRouteResearch) && semantic.Interpretation.Clarification != interaction.ClarificationRequired && shouldRunGeneralResearch(semantic.InformationRequestKind) { researchAttempted = true if planID, idErr := ids.New(); idErr == nil { diff --git a/modules/interaction/domain/personal_memory.go b/modules/interaction/domain/personal_memory.go index 8976ecc..5e65ce5 100644 --- a/modules/interaction/domain/personal_memory.go +++ b/modules/interaction/domain/personal_memory.go @@ -103,6 +103,30 @@ func (m PersonalMemory) ContextText() string { return strings.Join(lines, "\n") } +// RecallPersonalPreference answers the narrow, read-only memory question from +// the rebuildable projection. It is intentionally conservative: only an +// explicit question about the remembered test color is handled here; other +// questions continue through the normal cognitive route. +func RecallPersonalPreference(history []interaction.HumanUtterance, question string) string { + lowerQuestion := strings.ToLower(question) + if !strings.Contains(lowerQuestion, "цвет") || (!strings.Contains(lowerQuestion, "какой") && !strings.Contains(lowerQuestion, "назвал")) { + return "" + } + for _, fact := range CompilePersonalMemory(history).Facts { + if fact.Kind != "PREFERENCE" || !strings.Contains(strings.ToLower(fact.Value), "цвет") { + continue + } + value := strings.TrimSpace(fact.Value) + if separator := strings.Index(value, "—"); separator >= 0 { + value = strings.TrimSpace(value[separator+len("—"):]) + } + if value != "" { + return "Вы называли тестовый цвет: " + value + "." + } + } + return "" +} + func personalCurrentLocation(message string) string { tokens := semanticTokens(message) if len(tokens) < 4 || tokens[0] != "я" || !containsStemInTokens(tokens, "сейчас", "нахож", "жив") { diff --git a/modules/interaction/domain/personal_memory_test.go b/modules/interaction/domain/personal_memory_test.go index 0d1b92c..cbc5cba 100644 --- a/modules/interaction/domain/personal_memory_test.go +++ b/modules/interaction/domain/personal_memory_test.go @@ -39,3 +39,12 @@ func TestCompilePersonalMemoryBoundsLongRememberedValues(t *testing.T) { t.Fatalf("long remembered value leaked into cognitive context: %q", memory.ContextText()) } } + +func TestRecallPersonalPreferenceUsesProjectedAssertion(t *testing.T) { + answer := RecallPersonalPreference([]interaction.HumanUtterance{{ + Content: "запомни: мой тестовый цвет — acceptance-m5-синий-914", + }}, "Какой тестовый цвет я назвал?") + if answer != "Вы называли тестовый цвет: acceptance-m5-синий-914." { + t.Fatalf("answer=%q", answer) + } +}