mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 17:32:11 +00:00
Removed Categories and Engines from the SearXNG Tool, because they should be steered by the SearXNG instance and not by the LLM
This commit is contained in:
parent
88eccb158c
commit
7a9ab85113
@ -9280,9 +9280,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Maximum Results
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1273024715"] = "Maximum Results"
|
||||
|
||||
-- Optional comma-separated default categories. Do not set this together with default engines.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1342681591"] = "Optional comma-separated default categories. Do not set this together with default engines."
|
||||
|
||||
-- Default Safe Search
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1343180281"] = "Default Safe Search"
|
||||
|
||||
@ -9295,15 +9292,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- A SearXNG URL is required.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1746583720"] = "A SearXNG URL is required."
|
||||
|
||||
-- Default Engines
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1865580137"] = "Default Engines"
|
||||
|
||||
-- Optional fallback language code when the model does not provide a language.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1868101906"] = "Optional fallback language code when the model does not provide a language."
|
||||
|
||||
-- Default Categories
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2053347010"] = "Default Categories"
|
||||
|
||||
-- The total content budget must reserve at least {0} characters for each of up to {1} results.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2124070269"] = "The total content budget must reserve at least {0} characters for each of up to {1} results."
|
||||
|
||||
@ -9352,12 +9343,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Optional safe search policy sent to SearXNG when configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3967748757"] = "Optional safe search policy sent to SearXNG when configured."
|
||||
|
||||
-- Default categories and default engines cannot both be set for the web search tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4009446158"] = "Default categories and default engines cannot both be set for the web search tool."
|
||||
|
||||
-- Optional comma-separated default engines. Do not set this together with default categories.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4108908537"] = "Optional comma-separated default engines. Do not set this together with default categories."
|
||||
|
||||
-- The setting '{0}' must be a positive integer.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4199432074"] = "The setting '{0}' must be a positive integer."
|
||||
|
||||
|
||||
@ -381,11 +381,6 @@ CONFIG["SETTINGS"] = {}
|
||||
-- CONFIG["SETTINGS"]["DataTools.WebSearchDefaultLanguage"] = "de"
|
||||
-- WebSearchDefaultSafeSearch: optional SearXNG safe-search level "0", "1", or "2"; default is empty.
|
||||
-- CONFIG["SETTINGS"]["DataTools.WebSearchDefaultSafeSearch"] = "1"
|
||||
-- WebSearchDefaultCategories: optional comma-separated categories; default is empty.
|
||||
-- WebSearchDefaultEngines: optional comma-separated engines; default is empty.
|
||||
-- Categories and engines cannot both be configured.
|
||||
-- CONFIG["SETTINGS"]["DataTools.WebSearchDefaultCategories"] = "general, science"
|
||||
-- CONFIG["SETTINGS"]["DataTools.WebSearchDefaultEngines"] = ""
|
||||
-- WebSearchMaxResults: positive integer; default 5, effective maximum 20.
|
||||
-- CONFIG["SETTINGS"]["DataTools.WebSearchMaxResults"] = "5"
|
||||
-- WebSearchTimeoutSeconds: positive integer; default 20, effective maximum 60.
|
||||
@ -412,7 +407,7 @@ CONFIG["SETTINGS"] = {}
|
||||
-- operating-system sign-in when integrated authentication is requested, but does not reuse browser cookies.
|
||||
-- CONFIG["SETTINGS"]["DataTools.ReadWebPageAllowedPrivateHosts"] = "dlr.de, *.dlr.de"
|
||||
|
||||
-- The 14 Web Search and Read Web Page settings are locked by default. Add
|
||||
-- The 12 Web Search and Read Web Page settings are locked by default. Add
|
||||
-- ".AllowUserOverride" = true to any of them to provide an editable organization default instead.
|
||||
-- A saved local value then takes precedence.
|
||||
-- CONFIG["SETTINGS"]["DataTools.WebSearchBaseUrl.AllowUserOverride"] = true
|
||||
|
||||
@ -9282,9 +9282,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Maximum Results
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1273024715"] = "Maximale Anzahl an Ergebnissen"
|
||||
|
||||
-- Optional comma-separated default categories. Do not set this together with default engines.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1342681591"] = "Optionale, durch Kommas getrennte Standardkategorien. Nicht zusammen mit Standard-Engines festlegen."
|
||||
|
||||
-- Default Safe Search
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1343180281"] = "Standard-SafeSearch"
|
||||
|
||||
@ -9297,15 +9294,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- A SearXNG URL is required.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1746583720"] = "Eine SearXNG-URL ist erforderlich."
|
||||
|
||||
-- Default Engines
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1865580137"] = "Standard-Engines"
|
||||
|
||||
-- Optional fallback language code when the model does not provide a language.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1868101906"] = "Optionaler Fallback-Sprachcode, wenn das Modell keine Sprache angibt."
|
||||
|
||||
-- Default Categories
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2053347010"] = "Standardkategorien"
|
||||
|
||||
-- The total content budget must reserve at least {0} characters for each of up to {1} results.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2124070269"] = "Das Gesamtinhaltsbudget muss mindestens {0} Zeichen für jeweils bis zu {1} Ergebnisse reservieren."
|
||||
|
||||
@ -9354,12 +9345,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Optional safe search policy sent to SearXNG when configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3967748757"] = "Optionale SafeSearch-Richtlinie, die bei entsprechender Konfiguration an SearXNG gesendet wird."
|
||||
|
||||
-- Default categories and default engines cannot both be set for the web search tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4009446158"] = "Standardkategorien und Standard-Engines können für die Websuche nicht gleichzeitig festgelegt werden."
|
||||
|
||||
-- Optional comma-separated default engines. Do not set this together with default categories.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4108908537"] = "Optionale, durch Kommas getrennte Standard-Engines. Nicht zusammen mit Standardkategorien festlegen."
|
||||
|
||||
-- The setting '{0}' must be a positive integer.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4199432074"] = "Die Einstellung „{0}“ muss eine positive ganze Zahl sein."
|
||||
|
||||
|
||||
@ -9282,9 +9282,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Maximum Results
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1273024715"] = "Maximum Results"
|
||||
|
||||
-- Optional comma-separated default categories. Do not set this together with default engines.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1342681591"] = "Optional comma-separated default categories. Do not set this together with default engines."
|
||||
|
||||
-- Default Safe Search
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1343180281"] = "Default Safe Search"
|
||||
|
||||
@ -9297,15 +9294,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- A SearXNG URL is required.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1746583720"] = "A SearXNG URL is required."
|
||||
|
||||
-- Default Engines
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1865580137"] = "Default Engines"
|
||||
|
||||
-- Optional fallback language code when the model does not provide a language.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1868101906"] = "Optional fallback language code when the model does not provide a language."
|
||||
|
||||
-- Default Categories
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2053347010"] = "Default Categories"
|
||||
|
||||
-- The total content budget must reserve at least {0} characters for each of up to {1} results.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2124070269"] = "The total content budget must reserve at least {0} characters for each of up to {1} results."
|
||||
|
||||
@ -9354,12 +9345,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS:
|
||||
-- Optional safe search policy sent to SearXNG when configured.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3967748757"] = "Optional safe search policy sent to SearXNG when configured."
|
||||
|
||||
-- Default categories and default engines cannot both be set for the web search tool.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4009446158"] = "Default categories and default engines cannot both be set for the web search tool."
|
||||
|
||||
-- Optional comma-separated default engines. Do not set this together with default categories.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4108908537"] = "Optional comma-separated default engines. Do not set this together with default categories."
|
||||
|
||||
-- The setting '{0}' must be a positive integer.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4199432074"] = "The setting '{0}' must be a positive integer."
|
||||
|
||||
|
||||
@ -46,16 +46,6 @@ public sealed class DataTools(Expression<Func<Data, DataTools>>? configSelection
|
||||
x => x.WebSearchDefaultSafeSearch,
|
||||
string.Empty);
|
||||
|
||||
public string WebSearchDefaultCategories { get; set; } = ManagedConfiguration.Register<DataTools>(
|
||||
configSelection,
|
||||
x => x.WebSearchDefaultCategories,
|
||||
string.Empty);
|
||||
|
||||
public string WebSearchDefaultEngines { get; set; } = ManagedConfiguration.Register<DataTools>(
|
||||
configSelection,
|
||||
x => x.WebSearchDefaultEngines,
|
||||
string.Empty);
|
||||
|
||||
public string WebSearchMaxResults { get; set; } = ManagedConfiguration.Register<DataTools>(
|
||||
configSelection,
|
||||
x => x.WebSearchMaxResults,
|
||||
|
||||
@ -210,8 +210,6 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchBaseUrl, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchDefaultLanguage, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchDefaultSafeSearch, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchDefaultCategories, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchDefaultEngines, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchMaxResults, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchTimeoutSeconds, this.Id, settingsTable, dryRun);
|
||||
ManagedConfiguration.TryProcessConfiguration(x => x.Tools, x => x.WebSearchMaxTotalContentCharacters, this.Id, settingsTable, dryRun);
|
||||
|
||||
@ -313,12 +313,6 @@ public static partial class PluginFactory
|
||||
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.Tools, x => x.WebSearchDefaultSafeSearch, AVAILABLE_PLUGINS))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.Tools, x => x.WebSearchDefaultCategories, AVAILABLE_PLUGINS))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.Tools, x => x.WebSearchDefaultEngines, AVAILABLE_PLUGINS))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.Tools, x => x.WebSearchMaxResults, AVAILABLE_PLUGINS))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
|
||||
@ -18,12 +18,6 @@ internal sealed class SearXNGSearchClient
|
||||
new("format", "json"),
|
||||
};
|
||||
|
||||
if (searchRequest.Categories.Count > 0)
|
||||
queryParameters.Add(new KeyValuePair<string, string>("categories", string.Join(",", searchRequest.Categories)));
|
||||
|
||||
if (searchRequest.Engines.Count > 0)
|
||||
queryParameters.Add(new KeyValuePair<string, string>("engines", string.Join(",", searchRequest.Engines)));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchRequest.Language))
|
||||
queryParameters.Add(new KeyValuePair<string, string>("language", searchRequest.Language));
|
||||
|
||||
@ -140,8 +134,6 @@ internal sealed class SearXNGSearchClient
|
||||
OriginalUrls = [originalUrl],
|
||||
Title = ReadNodeString(result["title"]),
|
||||
Snippet = ReadNodeString(result["content"]),
|
||||
Engines = ReadStringValues(result, "engine", "engines"),
|
||||
Categories = ReadStringValues(result, "category", "categories"),
|
||||
PublishedDate = FirstNonEmpty(ReadNodeString(result["publishedDate"]), ReadNodeString(result["published_date"])),
|
||||
};
|
||||
var normalizedUrl = NormalizeUrl(retrievalUrl);
|
||||
@ -156,31 +148,6 @@ internal sealed class SearXNGSearchClient
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static List<string> ReadStringValues(JsonObject source, string singularPropertyName, string pluralPropertyName)
|
||||
{
|
||||
var values = new List<string>();
|
||||
AddNodeStringValues(source[singularPropertyName], values);
|
||||
AddNodeStringValues(source[pluralPropertyName], values);
|
||||
return values
|
||||
.Where(value => !string.IsNullOrWhiteSpace(value))
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static void AddNodeStringValues(JsonNode? node, List<string> values)
|
||||
{
|
||||
if (node is JsonArray array)
|
||||
{
|
||||
foreach (var item in array)
|
||||
AddNodeStringValues(item, values);
|
||||
return;
|
||||
}
|
||||
|
||||
var value = ReadNodeString(node);
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
values.Add(value);
|
||||
}
|
||||
|
||||
private static string ReadNodeString(JsonNode? node) => node is null ? string.Empty : node.ToString().Trim();
|
||||
|
||||
private static bool TryGetScore(JsonObject result, out double score)
|
||||
@ -292,8 +259,6 @@ internal sealed class SearXNGSearchClient
|
||||
internal sealed record SearXNGSearchRequest(
|
||||
Uri SearchUri,
|
||||
string Query,
|
||||
IReadOnlyList<string> Categories,
|
||||
IReadOnlyList<string> Engines,
|
||||
string? Language,
|
||||
string? TimeRange,
|
||||
int? Page,
|
||||
@ -315,10 +280,6 @@ internal sealed class SearchCandidate
|
||||
|
||||
public required string Snippet { get; set; }
|
||||
|
||||
public required List<string> Engines { get; init; }
|
||||
|
||||
public required List<string> Categories { get; init; }
|
||||
|
||||
public required string PublishedDate { get; set; }
|
||||
|
||||
public SearchCandidate Clone() => new()
|
||||
@ -328,8 +289,6 @@ internal sealed class SearchCandidate
|
||||
OriginalUrls = [..this.OriginalUrls],
|
||||
Title = this.Title,
|
||||
Snippet = this.Snippet,
|
||||
Engines = [..this.Engines],
|
||||
Categories = [..this.Categories],
|
||||
PublishedDate = this.PublishedDate,
|
||||
};
|
||||
|
||||
@ -351,8 +310,6 @@ internal sealed class SearchCandidate
|
||||
}
|
||||
|
||||
AddDistinct(this.OriginalUrls, candidate.OriginalUrls, StringComparer.Ordinal);
|
||||
AddDistinct(this.Engines, candidate.Engines, StringComparer.OrdinalIgnoreCase);
|
||||
AddDistinct(this.Categories, candidate.Categories, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static void AddDistinct(List<string> target, IEnumerable<string> values, StringComparer comparer)
|
||||
|
||||
@ -56,8 +56,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
"baseUrl" => TB("SearXNG URL"),
|
||||
"defaultLanguage" => TB("Default Language"),
|
||||
"defaultSafeSearch" => TB("Default Safe Search"),
|
||||
"defaultCategories" => TB("Default Categories"),
|
||||
"defaultEngines" => TB("Default Engines"),
|
||||
"maxResults" => TB("Maximum Results"),
|
||||
"timeoutSeconds" => TB("Timeout Seconds"),
|
||||
"maxTotalContentCharacters" => TB("Maximum Total Content Characters"),
|
||||
@ -72,8 +70,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
"baseUrl" => TB("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint."),
|
||||
"defaultLanguage" => TB("Optional fallback language code when the model does not provide a language."),
|
||||
"defaultSafeSearch" => TB("Optional safe search policy sent to SearXNG when configured."),
|
||||
"defaultCategories" => TB("Optional comma-separated default categories. Do not set this together with default engines."),
|
||||
"defaultEngines" => TB("Optional comma-separated default engines. Do not set this together with default categories."),
|
||||
"maxResults" => TB("Optional default maximum number of results returned to the model when the model does not provide a limit."),
|
||||
"timeoutSeconds" => TB("Optional HTTP timeout for the search request in seconds."),
|
||||
"maxTotalContentCharacters" => TB("Optional total character budget shared by all retrieved pages."),
|
||||
@ -111,17 +107,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
});
|
||||
}
|
||||
|
||||
var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories"));
|
||||
var hasDefaultEngines = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultEngines"));
|
||||
if (hasDefaultCategories && hasDefaultEngines)
|
||||
{
|
||||
return Task.FromResult<ToolConfigurationState?>(new ToolConfigurationState
|
||||
{
|
||||
IsConfigured = false,
|
||||
Message = TB("Default categories and default engines cannot both be set for the web search tool."),
|
||||
});
|
||||
}
|
||||
|
||||
var defaultSafeSearch = settingsValues.GetValueOrDefault("defaultSafeSearch");
|
||||
if (!string.IsNullOrWhiteSpace(defaultSafeSearch) && defaultSafeSearch is not ("0" or "1" or "2"))
|
||||
{
|
||||
@ -207,8 +192,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
throw new InvalidOperationException(uriError);
|
||||
|
||||
var query = ReadRequiredString(arguments, "query");
|
||||
var categories = ReadOptionalStringArray(arguments, "categories");
|
||||
var engines = ReadOptionalStringArray(arguments, "engines");
|
||||
var language = ReadOptionalString(arguments, "language");
|
||||
var timeRange = ReadOptionalString(arguments, "time_range");
|
||||
var page = ReadOptionalPositiveInt(arguments, "page");
|
||||
@ -220,15 +203,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
language = string.IsNullOrWhiteSpace(language) ? context.SettingsValues.GetValueOrDefault("defaultLanguage") : language;
|
||||
var safeSearch = context.SettingsValues.GetValueOrDefault("defaultSafeSearch");
|
||||
|
||||
if (categories.Count == 0)
|
||||
categories = SplitCommaSeparatedValues(context.SettingsValues.GetValueOrDefault("defaultCategories"));
|
||||
|
||||
if (engines.Count == 0)
|
||||
engines = SplitCommaSeparatedValues(context.SettingsValues.GetValueOrDefault("defaultEngines"));
|
||||
|
||||
if (categories.Count > 0 && engines.Count > 0 && !string.IsNullOrWhiteSpace(context.SettingsValues.GetValueOrDefault("defaultCategories")) && !string.IsNullOrWhiteSpace(context.SettingsValues.GetValueOrDefault("defaultEngines")))
|
||||
throw new InvalidOperationException(TB("Default categories and default engines cannot both be set for the web search tool."));
|
||||
|
||||
var defaultLimit = ToolSettingsValueParser.ReadOptionalPositiveInt(context.SettingsValues, "maxResults") ?? DEFAULT_MAX_RESULTS;
|
||||
var effectiveLimit = Math.Min(requestedLimit ?? defaultLimit, MAX_RESULTS);
|
||||
var timeoutSeconds = Math.Min(ToolSettingsValueParser.ReadOptionalPositiveInt(context.SettingsValues, "timeoutSeconds") ?? DEFAULT_TIMEOUT_SECONDS, MAX_TIMEOUT_SECONDS);
|
||||
@ -242,11 +216,9 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
throw new ArgumentException($"Argument 'page' must be less than or equal to {MAX_PAGE}.");
|
||||
|
||||
this.logger.LogInformation(
|
||||
"Starting web search. ToolCallId={ToolCallId}, Query={Query}, Categories=[{Categories}], Engines=[{Engines}], Language={Language}, TimeRange={TimeRange}, Page={Page}, Limit={Limit}",
|
||||
"Starting web search. ToolCallId={ToolCallId}, Query={Query}, Language={Language}, TimeRange={TimeRange}, Page={Page}, Limit={Limit}",
|
||||
context.ToolCallId,
|
||||
FormatQueryForLog(query),
|
||||
string.Join(", ", categories),
|
||||
string.Join(", ", engines),
|
||||
language,
|
||||
timeRange,
|
||||
page,
|
||||
@ -256,8 +228,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
new SearXNGSearchRequest(
|
||||
searchUri,
|
||||
query,
|
||||
categories,
|
||||
engines,
|
||||
language,
|
||||
timeRange,
|
||||
page,
|
||||
@ -326,7 +296,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
{
|
||||
["rank"] = result.Candidate.Rank,
|
||||
["final_url"] = page.FinalUrl.ToString(),
|
||||
["engines"] = BuildJsonArray(result.Candidate.Engines),
|
||||
["published_date"] = result.Candidate.PublishedDate,
|
||||
};
|
||||
var pageContent = new JsonObject
|
||||
@ -390,34 +359,6 @@ public sealed class SearXNGWebSearchTool : IToolImplementation
|
||||
return intValue;
|
||||
}
|
||||
|
||||
private static List<string> ReadOptionalStringArray(JsonElement arguments, string propertyName)
|
||||
{
|
||||
if (!arguments.TryGetProperty(propertyName, out var value) || value.ValueKind is JsonValueKind.Null)
|
||||
return [];
|
||||
|
||||
if (value.ValueKind is not JsonValueKind.Array)
|
||||
throw new ArgumentException($"Argument '{propertyName}' must be an array of strings.");
|
||||
|
||||
var values = new List<string>();
|
||||
foreach (var element in value.EnumerateArray())
|
||||
{
|
||||
if (element.ValueKind is not JsonValueKind.String)
|
||||
throw new ArgumentException($"Argument '{propertyName}' must be an array of strings.");
|
||||
|
||||
var item = element.GetString()?.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(item))
|
||||
values.Add(item);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
private static List<string> SplitCommaSeparatedValues(string? value) => value?
|
||||
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.ToList() ?? [];
|
||||
|
||||
private static string FormatQueryForLog(string query)
|
||||
{
|
||||
var singleLineQuery = query
|
||||
|
||||
@ -13,8 +13,6 @@ public sealed class ToolSettingsService(SettingsManager settingsManager, RustSer
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "baseUrl")] = CreateManagedToolSetting(x => x.WebSearchBaseUrl, (tools, value) => tools.WebSearchBaseUrl = value),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "defaultLanguage")] = CreateManagedToolSetting(x => x.WebSearchDefaultLanguage),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "defaultSafeSearch")] = CreateManagedToolSetting(x => x.WebSearchDefaultSafeSearch),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "defaultCategories")] = CreateManagedToolSetting(x => x.WebSearchDefaultCategories),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "defaultEngines")] = CreateManagedToolSetting(x => x.WebSearchDefaultEngines),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "maxResults")] = CreateManagedToolSetting(x => x.WebSearchMaxResults),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "timeoutSeconds")] = CreateManagedToolSetting(x => x.WebSearchTimeoutSeconds),
|
||||
[(ToolSelectionRules.WEB_SEARCH_TOOL_ID, "maxTotalContentCharacters")] = CreateManagedToolSetting(x => x.WebSearchMaxTotalContentCharacters),
|
||||
|
||||
@ -26,14 +26,6 @@
|
||||
],
|
||||
"secret": false
|
||||
},
|
||||
"defaultCategories": {
|
||||
"type": "string",
|
||||
"secret": false
|
||||
},
|
||||
"defaultEngines": {
|
||||
"type": "string",
|
||||
"secret": false
|
||||
},
|
||||
"maxResults": {
|
||||
"type": "string",
|
||||
"secret": false
|
||||
@ -75,26 +67,6 @@
|
||||
"type": "string",
|
||||
"description": "The search query."
|
||||
},
|
||||
"categories": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"description": "Optional list of categories to use for the search.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"description": "Optional list of specific search engines to use when the user requests them explicitly.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"type": [
|
||||
"string",
|
||||
@ -107,7 +79,7 @@
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"description": "Optional time range filter for search engines that support it.",
|
||||
"description": "Optional time range filter for the search.",
|
||||
"enum": [
|
||||
null,
|
||||
"day",
|
||||
@ -132,8 +104,6 @@
|
||||
},
|
||||
"required": [
|
||||
"query",
|
||||
"categories",
|
||||
"engines",
|
||||
"language",
|
||||
"time_range",
|
||||
"page",
|
||||
|
||||
@ -207,6 +207,8 @@ For tools that perform network requests:
|
||||
|
||||
`web_search` is a combined search-and-retrieve tool. It asks the configured SearXNG instance for ranked candidates, applies the requested result limit, deduplicates equivalent URLs, and then loads the remaining public HTTP or HTTPS pages. Up to four pages are retrieved concurrently. Failed, blocked, unsupported, and empty pages are omitted, while an overall retrieval timeout returns any pages that completed successfully before cancellation.
|
||||
|
||||
Web Search does not send category or engine parameters. The SearXNG instance selects them using its own configuration.
|
||||
|
||||
Page loading and readable Markdown extraction are shared with `read_web_page` through `WebPageRetrievalService`. The service validates DNS results and every redirect target before connecting. `web_search` always uses the public-only policy and never reads private, loopback, link-local, or otherwise non-public targets. `read_web_page` remains the independent single-URL tool and may use its configured private-host allowlist, provider-confidence check, and operating-system sign-in behavior.
|
||||
|
||||
The `web_search` result separates each hit into `search_metadata` and `page`. Top-level counters report how many ranked candidates were considered, how many unique retrievals started, how many final pages were returned, and how many candidates were omitted. Search-result URLs and final redirect URLs are deduplicated separately so metadata from merged candidates is retained with the best rank.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user