diff --git a/cmd/core-runtime/main.go b/cmd/core-runtime/main.go index ef391e3..b86a35f 100644 --- a/cmd/core-runtime/main.go +++ b/cmd/core-runtime/main.go @@ -1671,7 +1671,7 @@ func renderResearchReply(query string, result epistemics.ResearchResult, researc if finding.State != epistemics.FindingSupported || strings.TrimSpace(finding.Excerpt.Text) == "" || strings.TrimSpace(finding.Source.Locator) == "" { continue } - excerpt := strings.TrimSpace(finding.Excerpt.Text) + excerpt := humanResearchExcerpt(query, finding.Excerpt.Text) limit := 180 if index > 0 { limit = 100 @@ -1687,7 +1687,7 @@ func renderResearchReply(query string, result epistemics.ResearchResult, researc if len(lines) == 0 { return "Проверяемых данных пока не найдено. Могу повторить поиск или уточнить, что именно проверить.", false } - reply := strings.Join(lines, "\n") + reply := "Нашёл проверяемые данные:\n\n" + strings.Join(lines, "\n\n") lowerQuery := strings.ToLower(query) if (strings.Contains(lowerQuery, "цен") || strings.Contains(lowerQuery, "стоим")) && !containsPriceEvidence(reply) { reply = "Актуальная цена в найденных фрагментах не указана, поэтому не буду придумывать сумму. Вот страницы, где её можно проверить:\n" + reply @@ -1695,6 +1695,26 @@ func renderResearchReply(query string, result epistemics.ResearchResult, researc return reply, true } +func humanResearchExcerpt(query, raw string) string { + text := strings.Join(strings.Fields(strings.TrimSpace(raw)), " ") + if text == "" { + return text + } + parts := strings.Split(text, " — ") + if len(parts) < 2 { + return text + } + lowerQuery := strings.ToLower(query) + for index := len(parts) - 1; index >= 0; index-- { + candidate := strings.TrimSpace(parts[index]) + lower := strings.ToLower(candidate) + if len([]rune(candidate)) >= 24 && (strings.Contains(lower, "сейчас") || strings.Contains(lower, "температур") || strings.Contains(lower, "цена") || strings.Contains(lower, "стоим") || strings.Contains(lower, "рейс") || strings.Contains(lower, "вылет") || strings.Contains(lowerQuery, "найди")) { + return candidate + } + } + return text +} + func containsPriceEvidence(value string) bool { pricePattern := regexp.MustCompile(`(?i)(\d[\d\s.,]{2,})(?:\s*(?:₽|руб\.?|р\.?|usd|\$|€))`) return pricePattern.MatchString(value) diff --git a/cmd/core-runtime/main_test.go b/cmd/core-runtime/main_test.go index 0e40a9b..c329620 100644 --- a/cmd/core-runtime/main_test.go +++ b/cmd/core-runtime/main_test.go @@ -15,6 +15,13 @@ import ( interactiondomain "git.cin.su/m/Assistant/modules/interaction/domain" ) +func TestHumanResearchExcerptRemovesSearchResultHeading(t *testing.T) { + got := humanResearchExcerpt("погода в Санкт-Петербурге", "Погода в Санкт-Петербурге — Прогноз погоды — Сейчас пасмурно, температура +14°") + if got != "Сейчас пасмурно, температура +14°" || strings.Contains(got, "Прогноз погоды") { + t.Fatalf("human research excerpt = %q", got) + } +} + func TestBearerTokenRequiresBearerScheme(t *testing.T) { request := httptest.NewRequest("GET", "/", nil) request.Header.Set("Authorization", "Basic value")