Merge pull request 'Allow research source recovery to complete' (#390) from codex/household-travel-query-fix into main

Reviewed-on: #390
This commit is contained in:
m
2026-08-25 20:47:18 +00:00
2 changed files with 65 additions and 3 deletions
+52 -2
View File
@@ -824,7 +824,7 @@ func main() {
PropositionKey: fmt.Sprintf("question:%s:%d", utterance.ID, index), Query: searchQuery,
})
cancelResearch()
reply, backed := renderResearchReply(part, result, researchErr)
reply, backed := renderResearchReply(searchQuery, result, researchErr)
if backed {
researchBacked = true
}
@@ -1824,13 +1824,63 @@ func researchFindingMatchesIntent(query string, finding epistemics.ResearchFindi
finding.Statement,
finding.Excerpt.Text,
}, " "))
return strings.Contains(evidence, "рейс") ||
travelEvidence := strings.Contains(evidence, "рейс") ||
strings.Contains(evidence, "вылет") ||
strings.Contains(evidence, "авиабил") ||
strings.Contains(evidence, "аэропорт") ||
strings.Contains(evidence, "самолет") ||
strings.Contains(evidence, "самолёт") ||
strings.Contains(evidence, "расписан")
if !travelEvidence {
return false
}
routeTerms := nearestFlightRouteTerms(query)
if len(routeTerms) < 2 {
return true
}
for _, term := range routeTerms {
if !strings.Contains(evidence, term) {
return false
}
}
return true
}
// nearestFlightRouteTerms retains only the two endpoint-shaped terms from a
// structured flight search. It has no city or provider vocabulary: endpoint
// relevance is determined from the request itself.
func nearestFlightRouteTerms(query string) []string {
fields := regexp.MustCompile(`[\p{L}]{4,}`).FindAllString(strings.ToLower(query), -1)
ignored := []string{"ближай", "авиарейс", "сегодня", "самолет", "самолёт", "вылет", "рейс", "пункт", "отправлен"}
terms := make([]string, 0, 2)
for _, field := range fields {
skip := false
for _, prefix := range ignored {
if strings.HasPrefix(field, prefix) {
skip = true
break
}
}
if skip {
continue
}
prefixLength := 4
if len([]rune(field)) < prefixLength {
prefixLength = len([]rune(field))
}
term := string([]rune(field)[:prefixLength])
already := false
for _, current := range terms {
if current == term {
already = true
break
}
}
if !already {
terms = append(terms, term)
}
}
return terms
}
func containsFlightTimeEvidence(value string) bool {
+13 -1
View File
@@ -40,12 +40,24 @@ func TestNearestFlightReplyFiltersUnrelatedSearchSnippets(t *testing.T) {
{State: epistemics.FindingSupported, Source: epistemics.Source{Locator: "https://naidy.example", Title: "Мебельная фурнитура"}, Excerpt: epistemics.SourceExcerpt{Text: "Комплектующие для мебели оптом и в розницу."}},
{State: epistemics.FindingSupported, Source: epistemics.Source{Locator: "https://rasp.example", Title: "Рейсы Москва — Казань"}, Excerpt: epistemics.SourceExcerpt{Text: "Расписание самолётов Москва — Казань, время вылета и прилёта."}},
}}
reply, backed := renderResearchReply("найди ближайший самолет до Казани сегодня пункт отправления: Москва", result, nil)
reply, backed := renderResearchReply("ближайшие авиарейсы Москва Казань сегодня", result, nil)
if !backed || !strings.Contains(reply, "Рейсы Москва") || strings.Contains(reply, "Мебельная") {
t.Fatalf("unrelated source leaked into flight reply: %q", reply)
}
}
func TestNearestFlightEvidenceRequiresBothRouteEndpointsWhenKnown(t *testing.T) {
query := "ближайшие авиарейсы Москва Казань сегодня"
matched := epistemics.ResearchFinding{Source: epistemics.Source{Title: "Рейсы Москва — Казань"}, Excerpt: epistemics.SourceExcerpt{Text: "Расписание авиарейсов из Москвы в Казань."}}
if !researchFindingMatchesIntent(query, matched) {
t.Fatal("route evidence with both endpoints was rejected")
}
unrelated := epistemics.ResearchFinding{Source: epistemics.Source{Title: "Ближайшие города к Казани"}, Excerpt: epistemics.SourceExcerpt{Text: "Авиабилеты и расстояние до Казани."}}
if researchFindingMatchesIntent(query, unrelated) {
t.Fatal("one-ended travel evidence was accepted")
}
}
func TestResponseReviewPreservesAttemptedResearchOutcome(t *testing.T) {
if reviewMayReplacePlanningReply(false, true, false, "Уточните аэропорт.", "Пока не смог получить проверяемый ответ.") {
t.Fatal("review replaced an honest unbacked research outcome")