From 20b18de60a6bfc712d2937c384d26ef827379be4 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Tue, 25 Aug 2026 10:46:33 +0300 Subject: [PATCH] Clarify missing price evidence --- cmd/core-runtime/main.go | 17 ++++++++++++++--- cmd/core-runtime/main_test.go | 9 +++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/cmd/core-runtime/main.go b/cmd/core-runtime/main.go index 3419160..9774aed 100644 --- a/cmd/core-runtime/main.go +++ b/cmd/core-runtime/main.go @@ -30,6 +30,7 @@ import ( "log" "net/http" "os" + "regexp" "sort" "strconv" "strings" @@ -747,7 +748,7 @@ func main() { PropositionKey: fmt.Sprintf("question:%s:%d", utterance.ID, index), Query: part, }) cancelResearch() - reply, backed := renderResearchReply(result, researchErr) + reply, backed := renderResearchReply(part, result, researchErr) if backed { researchBacked = true } @@ -1625,7 +1626,7 @@ func hasCapabilityHint(hints []string, wanted string) bool { return false } -func renderResearchReply(result epistemics.ResearchResult, researchErr error) (string, bool) { +func renderResearchReply(query string, result epistemics.ResearchResult, researchErr error) (string, bool) { if researchErr != nil { return "Сейчас не удалось получить данные из подключённого источника. Попробую снова через доступный маршрут.", false } @@ -1650,7 +1651,17 @@ func renderResearchReply(result epistemics.ResearchResult, researchErr error) (s if len(lines) == 0 { return "Проверяемых данных пока не найдено. Могу повторить поиск или уточнить, что именно проверить.", false } - return strings.Join(lines, "\n"), true + reply := strings.Join(lines, "\n") + lowerQuery := strings.ToLower(query) + if (strings.Contains(lowerQuery, "цен") || strings.Contains(lowerQuery, "стоим")) && !containsPriceEvidence(reply) { + reply = "Актуальная цена в найденных фрагментах не указана, поэтому не буду придумывать сумму. Вот страницы, где её можно проверить:\n" + reply + } + return reply, true +} + +func containsPriceEvidence(value string) bool { + pricePattern := regexp.MustCompile(`(?i)(\d[\d\s.,]{2,})(?:\s*(?:₽|руб\.?|р\.?|usd|\$|€))`) + return pricePattern.MatchString(value) } func reviewPreservesResearchEvidence(reviewed, draft string) bool { diff --git a/cmd/core-runtime/main_test.go b/cmd/core-runtime/main_test.go index 9f37a35..ce57e5b 100644 --- a/cmd/core-runtime/main_test.go +++ b/cmd/core-runtime/main_test.go @@ -48,6 +48,15 @@ func TestHumanMemoryInventoryUsesNewestPreference(t *testing.T) { } } +func TestContainsPriceEvidenceDistinguishesLinksFromPrices(t *testing.T) { + if containsPriceEvidence("RTX 4090 — market.yandex.ru") { + t.Fatal("a product link is not price evidence") + } + if !containsPriceEvidence("Цена: 189 990 ₽") { + t.Fatal("expected a currency amount to count as price evidence") + } +} + func TestCognitiveChannelQuestionUsesHumanSafeHealthReply(t *testing.T) { reply := humanCognitiveChannelReply(interaction.InformationRequestCognitiveChannelStatus, interaction.SpeechActQuestion, capability.Health{State: capability.HealthAvailable, CapabilityID: "provider-secret-model"}, nil) if !strings.Contains(reply, "доступен") || strings.Contains(reply, "provider-secret-model") { -- 2.54.0