This commit is contained in:
@@ -771,10 +771,11 @@ func main() {
|
||||
replies = append(replies, "По запросу «"+part+"»: "+clarification)
|
||||
continue
|
||||
}
|
||||
searchQuery := interactiondomain.TravelSearchQuery(part, now)
|
||||
researchCtx, cancelResearch := context.WithTimeout(r.Context(), 8*time.Second)
|
||||
result, researchErr := researchClient.SearchWeb(researchCtx, epistemics.WebSearchRequest{
|
||||
Plan: epistemics.ResearchPlan{ID: epistemics.ResearchPlanID(fmt.Sprintf("plan:%s:%d", planID, index)), Question: part, SourceClasses: []string{"web-search"}, FreshnessPolicy: "current"},
|
||||
PropositionKey: fmt.Sprintf("question:%s:%d", utterance.ID, index), Query: part,
|
||||
Plan: epistemics.ResearchPlan{ID: epistemics.ResearchPlanID(fmt.Sprintf("plan:%s:%d", planID, index)), Question: searchQuery, SourceClasses: []string{"web-search"}, FreshnessPolicy: "current"},
|
||||
PropositionKey: fmt.Sprintf("question:%s:%d", utterance.ID, index), Query: searchQuery,
|
||||
})
|
||||
cancelResearch()
|
||||
reply, backed := renderResearchReply(part, result, researchErr)
|
||||
@@ -821,7 +822,9 @@ func main() {
|
||||
var reminder *continuity.ProspectiveItem
|
||||
var generatedImage capability.MultimodalResponse
|
||||
mediaHandled := false
|
||||
mediaAttempted := false
|
||||
if hasChatRoute(routePlan, chatRouteMedia) && semantic.Interpretation.Clarification != interaction.ClarificationRequired {
|
||||
mediaAttempted = true
|
||||
imageCtx, cancelImage := context.WithTimeout(r.Context(), 15*time.Minute)
|
||||
generatedImage, err = cognitiveClient.GenerateImage(imageCtx, effectiveTaskMessage, "")
|
||||
cancelImage()
|
||||
@@ -920,7 +923,7 @@ func main() {
|
||||
ConfidenceMillis: semantic.Interpretation.ConfidenceMillis,
|
||||
})
|
||||
cancelReview()
|
||||
stableSemanticReply := mediaHandled || identityReply != "" || creativeReply != "" || (creativeFallbackReply != "" && !cognitiveAvailable) || semantic.InformationRequestKind != "" || locationReply != "" || deterministicSpeechAct == interaction.SpeechActConversational || deterministicSpeechAct == interaction.SpeechActConfirmation || deterministicSpeechAct == interaction.SpeechActRejection
|
||||
stableSemanticReply := mediaAttempted || identityReply != "" || creativeReply != "" || (creativeFallbackReply != "" && !cognitiveAvailable) || 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)) {
|
||||
@@ -929,7 +932,7 @@ func main() {
|
||||
log.Printf("cognitive response review proposed stable semantic rewrite; preserving semantic reply")
|
||||
}
|
||||
}
|
||||
if !mediaHandled && identityReply == "" && creativeReply == "" && creativeFallbackReply == "" {
|
||||
if !mediaAttempted && !mediaHandled && identityReply == "" && creativeReply == "" && creativeFallbackReply == "" {
|
||||
stableAct := interactiondomain.ClassifySpeechAct(utterance.Content, utterance.CorrectsUtteranceID)
|
||||
travelClarification := ""
|
||||
if !creativeRequest {
|
||||
|
||||
@@ -149,6 +149,16 @@ func TestTravelSearchClarification(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTravelSearchQueryCarriesNearestFlightDate(t *testing.T) {
|
||||
now := time.Date(2026, time.August, 25, 18, 0, 0, 0, time.UTC)
|
||||
if got := TravelSearchQuery("какой ближайший рейс из Москвы в Казань", now); got != "какой ближайший рейс из Москвы в Казань сегодня 25.08.2026" {
|
||||
t.Fatalf("nearest flight query=%q", got)
|
||||
}
|
||||
if got := TravelSearchQuery("рейс из Москвы в Казань завтра", now); got != "рейс из Москвы в Казань завтра" {
|
||||
t.Fatalf("explicit date was changed: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterpretUtteranceDirectiveRecordsOutcomeWithoutExecution(t *testing.T) {
|
||||
result := interpretForTest(t, "Поменяй базу на УПО1.", activeFocus("upo", "УПО"), "")
|
||||
if result.Interpretation.SpeechAct != interaction.SpeechActDirective {
|
||||
|
||||
@@ -2,10 +2,25 @@ package domain
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.cin.su/m/Assistant/contracts/interaction"
|
||||
)
|
||||
|
||||
// TravelSearchQuery carries the implicit current-day meaning of a nearest
|
||||
// flight request into the research adapter.
|
||||
func TravelSearchQuery(message string, now time.Time) string {
|
||||
cleaned := strings.TrimSpace(StripAssistantVocative(message))
|
||||
tokens := semanticTokens(cleaned)
|
||||
if !travelCue(tokens) || !containsStemInTokens(tokens, "ближ") || isTravelDateSpecified(tokens) {
|
||||
return cleaned
|
||||
}
|
||||
if now.IsZero() {
|
||||
return cleaned + " сегодня"
|
||||
}
|
||||
return cleaned + " сегодня " + now.Format("02.01.2006")
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -159,7 +174,7 @@ func TravelSearchClarification(message string, history []interaction.HumanUttera
|
||||
}
|
||||
origin := containsStemInTokens(current, "из", "откуда", "от")
|
||||
destination := containsStemInTokens(current, "в", "куда", "до")
|
||||
date := containsStemInTokens(current, "сегодня", "завтра", "послезавтр", "январ", "феврал", "март", "апрел", "мая", "июн", "июл", "август", "сентябр", "октябр", "ноябр", "декабр")
|
||||
date := isTravelDateSpecified(current)
|
||||
if containsStemInTokens(current, "ближ") {
|
||||
date = true
|
||||
}
|
||||
@@ -209,6 +224,18 @@ func TravelSearchClarification(message string, history []interaction.HumanUttera
|
||||
return "Уточните маршрут и дату: откуда, куда и на какой день нужны билеты?"
|
||||
}
|
||||
|
||||
func isTravelDateSpecified(tokens []string) bool {
|
||||
if containsStemInTokens(tokens, "сегодня", "завтра", "послезавтр", "январ", "феврал", "март", "апрел", "мая", "июн", "июл", "август", "сентябр", "октябр", "ноябр", "декабр") {
|
||||
return true
|
||||
}
|
||||
for _, token := range tokens {
|
||||
if hasDigit(token) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isTravelDateWord(value string) bool {
|
||||
return containsStem(value, "сегодня", "завтра", "послезавтр", "январ", "феврал", "март", "апрел", "мая", "июн", "июл", "август", "сентябр", "октябр", "ноябр", "декабр")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user