Preserve durable conversation identity
CI / test (push) Successful in 1m9s
CI / test (pull_request) Successful in 1m7s

This commit is contained in:
m
2026-08-25 10:39:05 +03:00
parent 1ea2e713d8
commit 61d08fa05a
2 changed files with 47 additions and 13 deletions
+26 -13
View File
@@ -571,7 +571,8 @@ func main() {
semantic.NeedsCognition = false
semantic.Interpretation.NeedsCognition = false
}
if locationReply := interactiondomain.LocationContextReply(utterance.Content); locationReply != "" {
locationReply := interactiondomain.LocationContextReply(utterance.Content)
if locationReply != "" {
semantic.Reply = locationReply
semantic.NeedsCognition = false
semantic.Interpretation.NeedsCognition = false
@@ -584,12 +585,7 @@ func main() {
}
assistantName := interactiondomain.PreferredAssistantName(utterance.Content)
if assistantName == "" {
for index := len(conversationHistory) - 1; index >= 0; index-- {
if name := interactiondomain.PreferredAssistantName(conversationHistory[index].Content); name != "" {
assistantName = name
break
}
}
assistantName = latestAssistantName(conversationHistory)
}
identityReply := ""
log.Printf("interaction identity context: name=%q history=%d", assistantName, len(conversationHistory))
@@ -871,7 +867,7 @@ func main() {
ConfidenceMillis: semantic.Interpretation.ConfidenceMillis,
})
cancelReview()
stableSemanticReply := identityReply != "" || deterministicSpeechAct == interaction.SpeechActConversational || deterministicSpeechAct == interaction.SpeechActConfirmation || deterministicSpeechAct == interaction.SpeechActRejection
stableSemanticReply := identityReply != "" || semantic.InformationRequestKind != "" || locationReply != "" || deterministicSpeechAct == interaction.SpeechActConversational || deterministicSpeechAct == interaction.SpeechActConfirmation || deterministicSpeechAct == interaction.SpeechActRejection
if reviewErr != nil {
log.Printf("cognitive response review unavailable: %v", reviewErr)
} else if !stableSemanticReply && (!researchBacked || reviewPreservesResearchEvidence(reviewedReply, planningReply)) {
@@ -1672,20 +1668,37 @@ func humanMemoryInventory(history []interaction.HumanUtterance, assistantName st
if assistantName != "" {
rows = append(rows, "| Имя помощника | "+assistantName+" |")
}
for index := len(history) - 1; index >= 0; index-- {
message := strings.TrimSpace(history[index].Content)
latestPreferenceAt := int64(-1)
latestPreference := ""
for _, utterance := range history {
message := strings.TrimSpace(utterance.Content)
lower := strings.ToLower(message)
if strings.Contains(lower, "нравится") || strings.Contains(lower, "люблю") {
rows = append(rows, "| Предпочтение пользователя | "+message+" |")
break
if (strings.Contains(lower, "нравится") || strings.Contains(lower, "люблю")) && utterance.ReceivedAtUnixMillis >= latestPreferenceAt {
latestPreferenceAt = utterance.ReceivedAtUnixMillis
latestPreference = message
}
}
if latestPreference != "" {
rows = append(rows, "| Предпочтение пользователя | "+latestPreference+" |")
}
if len(rows) == 0 {
return "| Ячейка памяти | Значение |\n|---|---|\n| — | Сохранённых пользовательских предпочтений пока не найдено. |"
}
return "| Ячейка памяти | Значение |\n|---|---|\n" + strings.Join(rows, "\n")
}
func latestAssistantName(history []interaction.HumanUtterance) string {
latestAt := int64(-1)
latestName := ""
for _, utterance := range history {
if name := interactiondomain.PreferredAssistantName(utterance.Content); name != "" && utterance.ReceivedAtUnixMillis >= latestAt {
latestAt = utterance.ReceivedAtUnixMillis
latestName = name
}
}
return latestName
}
func humanTimeDifferenceReply(message string) string {
lower := strings.ToLower(message)
if strings.Contains(lower, "моск") && strings.Contains(lower, "шанх") {
+21
View File
@@ -27,6 +27,27 @@ func TestBearerTokenRequiresBearerScheme(t *testing.T) {
}
}
func TestLatestAssistantNameUsesNewestDurablePreference(t *testing.T) {
history := []interaction.HumanUtterance{
{Content: "я назову тебя Дед", ReceivedAtUnixMillis: 20},
{Content: "теперь тебя зовут Фея", ReceivedAtUnixMillis: 30},
}
if got := latestAssistantName(history); got != "Фея" {
t.Fatalf("latest assistant name = %q", got)
}
}
func TestHumanMemoryInventoryUsesNewestPreference(t *testing.T) {
history := []interaction.HumanUtterance{
{Content: "мне нравится синий цвет", ReceivedAtUnixMillis: 20},
{Content: "мне нравится красный цвет", ReceivedAtUnixMillis: 30},
}
got := humanMemoryInventory(history, "Фея")
if !strings.Contains(got, "красный") || strings.Contains(got, "синий") {
t.Fatalf("memory inventory did not select newest preference: %q", got)
}
}
func TestCognitiveChannelQuestionUsesHumanSafeHealthReply(t *testing.T) {
reply := humanCognitiveChannelReply(interaction.InformationRequestCognitiveChannelStatus, interaction.SpeechActQuestion, capability.Health{State: capability.HealthAvailable, CapabilityID: "provider-secret-model"}, nil)
if !strings.Contains(reply, "доступен") || strings.Contains(reply, "provider-secret-model") {