diff --git a/cmd/core-runtime/main.go b/cmd/core-runtime/main.go index addcd5c..89ffc89 100644 --- a/cmd/core-runtime/main.go +++ b/cmd/core-runtime/main.go @@ -811,6 +811,7 @@ func main() { } learnedLexicon := interactiondomain.TaskLexiconFromHistory(conversationHistory) searchQuery := interactiondomain.SearchQueryWithLexicon(part, learnedLexicon) + searchQuery = interactiondomain.TimeDifferenceResearchQuery(searchQuery) searchQuery = interactiondomain.TravelResearchQuery(searchQuery, conversationHistory, now) // The research capability may try its configured source and a // source-recovery fallback. Its caller must leave enough budget for diff --git a/modules/interaction/domain/chat.go b/modules/interaction/domain/chat.go index 412edf5..9ddc2a7 100644 --- a/modules/interaction/domain/chat.go +++ b/modules/interaction/domain/chat.go @@ -715,6 +715,17 @@ func IsCreativeRequest(message string) bool { return isCreativeRequestTokens(tokens) } +// TimeDifferenceResearchQuery makes the requested measurement explicit for a +// current-data capability. It preserves the user-provided entities and does +// not encode any particular place or time-zone relationship. +func TimeDifferenceResearchQuery(message string) string { + tokens := semanticTokens(StripAssistantVocative(message)) + if containsStemInTokens(tokens, "разниц") && containsStemInTokens(tokens, "времен", "час") && containsToken(tokens, "между") { + return strings.TrimSpace(StripAssistantVocative(message)) + " сколько часов" + } + return strings.TrimSpace(message) +} + // CreativeDeterministicReply intentionally has no example-specific answer // branches. Creative requests must retain their full meaning and go through // cognition; canned object or color answers hide lost attributes. diff --git a/modules/interaction/domain/chat_test.go b/modules/interaction/domain/chat_test.go index 6e2a46a..9d89591 100644 --- a/modules/interaction/domain/chat_test.go +++ b/modules/interaction/domain/chat_test.go @@ -356,6 +356,13 @@ func TestTimeDifferenceRequestIsSemantic(t *testing.T) { } } +func TestTimeDifferenceResearchQueryKeepsEntitiesAndAsksForMeasurement(t *testing.T) { + got := TimeDifferenceResearchQuery("какая разница во времени между Москвой и Шанхаем?") + if got != "какая разница во времени между Москвой и Шанхаем? сколько часов" { + t.Fatalf("time difference query = %q", got) + } +} + func TestDeterministicCandidateKeepsFirstPersonCompletedWorkAsAssertion(t *testing.T) { candidate := BuildDeterministicCandidate("Я всё уже настроил.", "", time.Unix(10, 0).UnixMilli()) if candidate.PrimarySpeechAct != interaction.SpeechActAssertion {