diff --git a/modules/interaction/domain/semantics_test.go b/modules/interaction/domain/semantics_test.go index add22e4..93b1cb8 100644 --- a/modules/interaction/domain/semantics_test.go +++ b/modules/interaction/domain/semantics_test.go @@ -178,6 +178,20 @@ func TestTravelRouteWithKnownOriginDoesNotAskForTicketDate(t *testing.T) { } } +func TestTravelContextUsesNewestLocationRegardlessOfRepositoryOrder(t *testing.T) { + history := []interaction.HumanUtterance{ + {Content: "я сейчас в Санкт-Петербурге", ReceivedAtUnixMillis: 200}, + {Content: "я сейчас в Москве", ReceivedAtUnixMillis: 300}, + {Content: "я сейчас в Казани", ReceivedAtUnixMillis: 100}, + } + if got := TravelSearchClarification("какой ближайший рейс до Сочи?", history); got != "" { + t.Fatalf("newest remembered origin was not applied: %q", got) + } + if got := TravelResearchQuery("какой ближайший рейс до Сочи?", history, time.Time{}); !strings.Contains(got, "из Москве") { + t.Fatalf("newest origin missing from travel research query: %q", got) + } +} + func TestInterpretUtteranceDirectiveRecordsOutcomeWithoutExecution(t *testing.T) { result := interpretForTest(t, "Поменяй базу на УПО1.", activeFocus("upo", "УПО"), "") if result.Interpretation.SpeechAct != interaction.SpeechActDirective { diff --git a/modules/interaction/domain/travel.go b/modules/interaction/domain/travel.go index 763a60c..d9d15da 100644 --- a/modules/interaction/domain/travel.go +++ b/modules/interaction/domain/travel.go @@ -46,6 +46,10 @@ func TravelResearchQuery(message string, history []interaction.HumanUtterance, n if origin != "" && !containsStemInTokens(tokens, "из", "откуда", "от") { query += " отправление из " + origin } + } else if travelCue(tokens) && !containsStemInTokens(tokens, "из", "откуда", "от") { + if origin := travelContextOrigin(history); origin != "" { + query += " из " + origin + } } return query } @@ -215,13 +219,7 @@ func TravelSearchClarification(message string, history []interaction.HumanUttera } } } - if origin && destination && date { - return "" - } ticketRequest := containsStemInTokens(current, "билет", "рейс", "самолет", "самолёт", "вылет") - if !ticketRequest && origin && destination { - return "" - } if !destination { if contextDestination := travelContextDestination(history); contextDestination != "" { destination = true @@ -238,6 +236,9 @@ func TravelSearchClarification(message string, history []interaction.HumanUttera origin = true } } + if origin && destination && (date || !ticketRequest) { + return "" + } if destination && !origin && !date { if !ticketRequest { return "Из какого города выезжать в " + destinationLabel(current, history) + "? Подберу самолёт, поезд, автобус или машину." @@ -297,8 +298,10 @@ func travelContextDestinationFromTokens(tokens []string) string { } func travelContextDestination(history []interaction.HumanUtterance) string { - for index := len(history) - 1; index >= 0; index-- { - tokens := semanticTokens(history[index].Content) + latestAt := int64(-1) + latest := "" + for _, utterance := range history { + tokens := semanticTokens(utterance.Content) if !travelContextCue(tokens) { continue } @@ -307,26 +310,36 @@ func travelContextDestination(history []interaction.HumanUtterance) string { continue } if tokenIndex+1 < len(tokens) && len([]rune(tokens[tokenIndex+1])) >= 3 { - return capitalizeWord(tokens[tokenIndex+1]) + if utterance.ReceivedAtUnixMillis >= latestAt { + latestAt = utterance.ReceivedAtUnixMillis + latest = capitalizeWord(tokens[tokenIndex+1]) + } + break } } } - return "" + return latest } func travelContextOrigin(history []interaction.HumanUtterance) string { - for index := len(history) - 1; index >= 0; index-- { - tokens := semanticTokens(history[index].Content) + latestAt := int64(-1) + latest := "" + for _, utterance := range history { + tokens := semanticTokens(utterance.Content) if len(tokens) < 3 || tokens[0] != "я" || !containsStemInTokens(tokens, "сейчас", "нахож", "жив") { continue } for tokenIndex, token := range tokens { if (token == "в" || token == "из") && tokenIndex+1 < len(tokens) { - return capitalizeWord(tokens[tokenIndex+1]) + if utterance.ReceivedAtUnixMillis >= latestAt { + latestAt = utterance.ReceivedAtUnixMillis + latest = capitalizeWord(tokens[tokenIndex+1]) + } + break } } } - return "" + return latest } func travelContextCue(tokens []string) bool {