Merge pull request 'Improve semantic travel research queries' (#369) from codex/household-travel-query-fix into main
CI / test (push) Successful in 1m14s

Reviewed-on: #369
This commit was merged in pull request #369.
This commit is contained in:
m
2026-08-25 16:26:24 +00:00
2 changed files with 34 additions and 3 deletions
+8 -1
View File
@@ -162,11 +162,18 @@ func TestTravelSearchQueryCarriesNearestFlightDate(t *testing.T) {
func TestTravelResearchQueryUsesKnownOriginForDistance(t *testing.T) {
history := []interaction.HumanUtterance{{Content: "я сейчас в Москве"}}
got := TravelResearchQuery("сколько километров до Сочи?", history, time.Time{})
if !strings.Contains(got, "точка отправления: Москве") || !strings.Contains(got, "расстояние по прямой и по дороге") {
if got != "расстояние между Москве и Сочи в километрах по прямой и по дороге" {
t.Fatalf("distance query lost route context: %q", got)
}
}
func TestTravelRouteWithKnownOriginDoesNotAskForTicketDate(t *testing.T) {
history := []interaction.HumanUtterance{{Content: "я сейчас в Москве"}}
if got := TravelSearchClarification("как можно добраться до Сочи?", history); got != "" {
t.Fatalf("general route was incorrectly reduced to ticket clarification: %q", got)
}
}
func TestInterpretUtteranceDirectiveRecordsOutcomeWithoutExecution(t *testing.T) {
result := interpretForTest(t, "Поменяй базу на УПО1.", activeFocus("upo", "УПО"), "")
if result.Interpretation.SpeechAct != interaction.SpeechActDirective {
+26 -2
View File
@@ -27,11 +27,20 @@ func TravelSearchQuery(message string, now time.Time) string {
func TravelResearchQuery(message string, history []interaction.HumanUtterance, now time.Time) string {
query := TravelSearchQuery(message, now)
tokens := semanticTokens(StripAssistantVocative(message))
if containsStemInTokens(tokens, "расстоян", "километр", "добрат", "маршрут") {
if origin := travelContextOrigin(history); origin != "" && !containsStemInTokens(tokens, "из", "откуда", "от") {
if containsStemInTokens(tokens, "расстоян", "километр") {
origin := travelContextOrigin(history)
destination := travelContextDestinationFromTokens(tokens)
if origin != "" && destination != "" {
return "расстояние между " + origin + " и " + destination + " в километрах по прямой и по дороге"
}
if origin != "" && !containsStemInTokens(tokens, "из", "откуда", "от") {
query += " точка отправления: " + origin
}
query += " расстояние по прямой и по дороге"
} else if containsStemInTokens(tokens, "добрат", "маршрут") {
if origin := travelContextOrigin(history); origin != "" && !containsStemInTokens(tokens, "из", "откуда", "от") {
query += " отправление из " + origin
}
}
return query
}
@@ -234,6 +243,9 @@ func TravelSearchClarification(message string, history []interaction.HumanUttera
return "Из какого города вылетать?"
}
if destination && !date {
if !ticketRequest {
return ""
}
return "На какую дату нужны билеты?"
}
return "Уточните маршрут и дату: откуда, куда и на какой день нужны билеты?"
@@ -267,6 +279,18 @@ func destinationLabel(current []string, history []interaction.HumanUtterance) st
return "пункт назначения"
}
func travelContextDestinationFromTokens(tokens []string) string {
for index, token := range tokens {
if token != "до" && token != "в" && token != "к" {
continue
}
if index+1 < len(tokens) && len([]rune(tokens[index+1])) >= 3 {
return capitalizeWord(tokens[index+1])
}
}
return ""
}
func travelContextDestination(history []interaction.HumanUtterance) string {
for index := len(history) - 1; index >= 0; index-- {
tokens := semanticTokens(history[index].Content)