From c17d72681432edd9204fa1348882dc65432c7ca7 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Thu, 24 Sep 2026 12:00:57 +0200 Subject: [PATCH] Allowed restricting the web search to the past week --- .../WebSearch/WebSearchTool.cs | 12 ++++++++---- .../ToolCalling/WebSearchToolArgumentTests.cs | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/MindWork AI Studio/Tools/ToolCallingSystem/ToolCallingImplementations/WebSearch/WebSearchTool.cs b/app/MindWork AI Studio/Tools/ToolCallingSystem/ToolCallingImplementations/WebSearch/WebSearchTool.cs index d252965b..19975344 100644 --- a/app/MindWork AI Studio/Tools/ToolCallingSystem/ToolCallingImplementations/WebSearch/WebSearchTool.cs +++ b/app/MindWork AI Studio/Tools/ToolCallingSystem/ToolCallingImplementations/WebSearch/WebSearchTool.cs @@ -94,6 +94,7 @@ public sealed class WebSearchTool(IEnumerable backends, WebPa private const string LIMIT_ARGUMENT = "limit"; private const string TIME_RANGE_DAY = "day"; + private const string TIME_RANGE_WEEK = "week"; private const string TIME_RANGE_MONTH = "month"; private const string TIME_RANGE_YEAR = "year"; @@ -101,11 +102,14 @@ public sealed class WebSearchTool(IEnumerable backends, WebPa /// The time ranges a search can be restricted to. /// /// - /// Only those which every service with a time filter understands: SearXNG documents day, month, - /// and year, while Tavily knows a week as well. The schema offers exactly these and the reader - /// checks against them, so the two cannot drift apart. + /// Those which both services with a time filter, SearXNG and Tavily, understand and take as + /// they are. Tavily documents all four. SearXNG's API documentation names no week, but its code accepts + /// one -- read on 2026-09-24 in parse_time_range of searx/webadapter.py. A model asked about + /// "this week" wants exactly that, and without it, it asks for a week again and again.

+ /// The schema offers exactly these and the reader checks against them, so the two cannot drift + /// apart. ///
- private static readonly string[] TIME_RANGES = [TIME_RANGE_DAY, TIME_RANGE_MONTH, TIME_RANGE_YEAR]; + private static readonly string[] TIME_RANGES = [TIME_RANGE_DAY, TIME_RANGE_WEEK, TIME_RANGE_MONTH, TIME_RANGE_YEAR]; /// /// How much of a wrongly passed argument an error message repeats back to the model. diff --git a/app/Tests/Tools/ToolCalling/WebSearchToolArgumentTests.cs b/app/Tests/Tools/ToolCalling/WebSearchToolArgumentTests.cs index 02f8ca19..7e667580 100644 --- a/app/Tests/Tools/ToolCalling/WebSearchToolArgumentTests.cs +++ b/app/Tests/Tools/ToolCalling/WebSearchToolArgumentTests.cs @@ -93,9 +93,22 @@ public sealed class WebSearchToolArgumentTests }); } + [TestCase("day")] + [TestCase("week")] + [TestCase("month")] + [TestCase("year")] + public void EveryOfferedTimeRangeIsAccepted(string timeRange) + { + // + // The week is the one a model asks for when the user says "this week". Both services with + // a time filter understand it, and refusing it only made the model try it again and again. + // + Assert.That(WebSearchTool.ReadTimeRange(Arguments($$"""{"query":"weather","time_range":"{{timeRange}}"}""")), Is.EqualTo(timeRange)); + } + [TestCase("\"\"")] [TestCase("\"Day\"")] - [TestCase("\"week\"")] + [TestCase("\"decade\"")] [TestCase("5")] public void AWrongTimeRangeIsRefusedWithTheValuesThatWouldDo(string value) { @@ -103,7 +116,7 @@ public sealed class WebSearchToolArgumentTests Assert.Multiple(() => { - Assert.That(message, Does.Contain("'time_range'").And.Contain("one of day, month, year")); + Assert.That(message, Does.Contain("'time_range'").And.Contain("one of day, week, month, year")); Assert.That(message, Does.Contain($"but was {value}.")); Assert.That(message, Does.Contain("Leave it out")); });