From 4e5bb9abc9f0e9e42a04ce7a35896d05b34b79fc Mon Sep 17 00:00:00 2001 From: Mikhail Date: Tue, 25 Aug 2026 23:39:05 +0300 Subject: [PATCH] Form nearest flight searches from route context --- cmd/core-runtime/main.go | 5 ----- modules/interaction/domain/semantics_test.go | 4 ++-- modules/interaction/domain/travel.go | 23 +++++++++++++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/cmd/core-runtime/main.go b/cmd/core-runtime/main.go index 2ac7adb..150ade8 100644 --- a/cmd/core-runtime/main.go +++ b/cmd/core-runtime/main.go @@ -534,10 +534,6 @@ func main() { } conversationHistory = append(conversationHistory, recentUserHistory...) personalMemory := interactiondomain.CompilePersonalMemory(conversationHistory) - // Context selection must stay observable without logging the user's - // message or personal fact values. These flags let an operator distinguish - // a missing derived fact from a later routing or clarification decision. - personalMemoryHasCurrentLocation := personalMemory.CurrentLocation() != "" if !creativeUserRequest && locationReply == "" { if continuation := interactiondomain.ContinueLocalSearch(effectiveTaskMessage, conversationHistory); continuation != "" { continuationMessage = continuation @@ -654,7 +650,6 @@ func main() { deterministicSpeechAct := semantic.Interpretation.SpeechAct deterministicReply := semantic.Reply routePlan := buildChatRoutePlan(semantic) - log.Printf("chat context state: current_location=%t research_route=%t clarification=%s", personalMemoryHasCurrentLocation, hasChatRoute(routePlan, chatRouteResearch), semantic.Interpretation.Clarification) cognitiveAttempted := false cognitiveAvailable := true semanticInterpretationRequested := shouldRequestSemanticInterpretation(semantic) diff --git a/modules/interaction/domain/semantics_test.go b/modules/interaction/domain/semantics_test.go index 3e1a49c..0abeaa5 100644 --- a/modules/interaction/domain/semantics_test.go +++ b/modules/interaction/domain/semantics_test.go @@ -209,8 +209,8 @@ func TestNearestPlaneUsesTravelContextAndCurrentDay(t *testing.T) { now := time.Date(2026, time.August, 25, 18, 0, 0, 0, time.UTC) history := []interaction.HumanUtterance{{Content: "я сейчас в Москве", ReceivedAtUnixMillis: 100}} query := TravelResearchQuery("найди ближайший самолет до Казани", history, now) - if !strings.Contains(query, "сегодня 25.08.2026") || !strings.Contains(query, "пункт отправления: Москве") { - t.Fatalf("nearest plane query lost current context: %q", query) + if query != "ближайшие авиарейсы Москве Казани сегодня 25.08.2026" { + t.Fatalf("nearest plane search formulation lost current context: %q", query) } if got := TravelSearchClarification("найди ближайший самолет до Казани", history); got != "" { t.Fatalf("known origin and nearest-time meaning should proceed, got %q", got) diff --git a/modules/interaction/domain/travel.go b/modules/interaction/domain/travel.go index 022202f..7dd0011 100644 --- a/modules/interaction/domain/travel.go +++ b/modules/interaction/domain/travel.go @@ -47,7 +47,12 @@ func TravelResearchQuery(message string, history []interaction.HumanUtterance, n query += " отправление из " + origin } } else if travelCue(tokens) && !containsStemInTokens(tokens, "из", "откуда", "от") { - if origin := travelContextOrigin(history); origin != "" { + origin := travelContextOrigin(history) + destination := travelContextDestinationFromTokens(tokens) + if nearestAirTravelRequest(tokens) && origin != "" && destination != "" { + return nearestAirTravelSearchQuery(origin, destination, now) + } + if origin != "" { // Preserve the remembered location as an explicit search parameter // instead of guessing its grammatical form in the user's language. query += " пункт отправления: " + origin @@ -56,6 +61,18 @@ func TravelResearchQuery(message string, history []interaction.HumanUtterance, n return query } +// nearestAirTravelSearchQuery is a capability-local search formulation, not a +// provider or place lookup. It removes conversational imperatives while +// preserving the two user-derived route endpoints and the implicit current-day +// meaning of "ближайший". +func nearestAirTravelSearchQuery(origin, destination string, now time.Time) string { + query := "ближайшие авиарейсы " + origin + " " + destination + " сегодня" + if !now.IsZero() { + query += " " + now.Format("02.01.2006") + } + return query +} + // StripAssistantVocative removes a leading assistant name used as an address. // The original utterance remains the historical source; this value is only for // interpretation, cognitive prompts and external queries. @@ -371,6 +388,10 @@ func travelCue(tokens []string) bool { return containsStemInTokens(tokens, "билет", "рейс", "самолет", "самолёт", "вылет", "поезд", "автобус", "перелет", "перелёт") } +func nearestAirTravelRequest(tokens []string) bool { + return containsStemInTokens(tokens, "ближ") && containsStemInTokens(tokens, "самолет", "самолёт", "авиарейс", "перелет", "перелёт") +} + func travelFollowUpCue(tokens []string) bool { return containsStemInTokens(tokens, "куда", "откуда", "маршрут", "летим", "дата", "число") } -- 2.54.0