From 582bd27e482d1efac4d249eaaec4d53e1bc44da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peer=20Sch=C3=BCtt?= <20603780+peerschuett@users.noreply.github.com> Date: Mon, 13 Apr 2026 18:37:23 +0200 Subject: [PATCH] The tools web_search and read_web_content are now working! They still need to be finetuned and better harnessed. --- .../Assistants/I18N/allTexts.lua | 78 +++++++++---------- app/MindWork AI Studio/Chat/ChatThread.cs | 31 ++++---- app/MindWork AI Studio/Program.cs | 2 +- app/MindWork AI Studio/Tools/HTMLParser.cs | 34 +++++++- 4 files changed, 85 insertions(+), 60 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua index 63b84a0e..8bb52092 100644 --- a/app/MindWork AI Studio/Assistants/I18N/allTexts.lua +++ b/app/MindWork AI Studio/Assistants/I18N/allTexts.lua @@ -6847,104 +6847,104 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SOURCEEXTENSIONS::T4174900468"] = "Sources pro -- Sources provided by the AI UI_TEXT_CONTENT["AISTUDIO::TOOLS::SOURCEEXTENSIONS::T4261248356"] = "Sources provided by the AI" --- Current Weather", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetDescription() => I18N.I.T("Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Demo Label", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::GETCURRENTWEATHERTOOL::T1597702905"] = "Current Weather\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetDescription() => I18N.I.T(\"Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Demo Label\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" - --- Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Demo Label", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::GETCURRENTWEATHERTOOL::T2152408159"] = "Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Demo Label\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" - --- Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::GETCURRENTWEATHERTOOL::T25380508"] = "Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" - --- Demo Label", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::GETCURRENTWEATHERTOOL::T3346467484"] = "Demo Label\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" - -- Tool UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T3517012711"] = "Tool" -- Tool description UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::ITOOLIMPLEMENTATION::T4056470505"] = "Tool description" +-- Current Weather", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetDescription() => I18N.I.T("Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Demo Label", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::GETCURRENTWEATHERTOOL::T1597702905"] = "Current Weather\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetDescription() => I18N.I.T(\"Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Demo Label\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" + +-- Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Demo Label", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::GETCURRENTWEATHERTOOL::T2152408159"] = "Use this demo tool to retrieve the current weather for a given city and state. It is primarily meant to demonstrate tool calling and tool settings in AI Studio.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Demo Label\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" + +-- Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::GETCURRENTWEATHERTOOL::T25380508"] = "Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" + +-- Demo Label", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "demoLabel" => I18N.I.T("Required demo setting for validating tool settings in tests. It does not affect the weather result.", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty("city", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty("state", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty("unit", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not ("celsius" or "fahrenheit +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::GETCURRENTWEATHERTOOL::T3346467484"] = "Demo Label\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"demoLabel\" => I18N.I.T(\"Required demo setting for validating tool settings in tests. It does not affect the weather result.\", typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(GetCurrentWeatherTool).Namespace, nameof(GetCurrentWeatherTool)), }; public Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var city = arguments.TryGetProperty(\"city\", out var cityValue) ? cityValue.GetString() ?? string.Empty : string.Empty; var state = arguments.TryGetProperty(\"state\", out var stateValue) ? stateValue.GetString() ?? string.Empty : string.Empty; var unit = arguments.TryGetProperty(\"unit\", out var unitValue) ? unitValue.GetString() ?? string.Empty : string.Empty; if (unit is not (\"celsius\" or \"fahrenheit" + -- Optional HTTP timeout for loading a web page in seconds.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Optional global truncation limit for extracted Markdown returned to the model.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxContentCharacters", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, "url -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::READWEBPAGETOOL::T1169117578"] = "Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T1169117578"] = "Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" -- Read Web Page", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetDescription() => I18N.I.T("Load a single web page, extract its main HTML content, and return structured working material for the model. Use the result to synthesize a natural-language answer instead of exposing the raw payload to the user.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Maximum Content Characters", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for loading a web page in seconds.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Optional global truncation limit for extracted Markdown returned to the model.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxContentCharacters", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, "url -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::READWEBPAGETOOL::T1310829237"] = "Read Web Page\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetDescription() => I18N.I.T(\"Load a single web page, extract its main HTML content, and return structured working material for the model. Use the result to synthesize a natural-language answer instead of exposing the raw payload to the user.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T1310829237"] = "Read Web Page\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetDescription() => I18N.I.T(\"Load a single web page, extract its main HTML content, and return structured working material for the model. Use the result to synthesize a natural-language answer instead of exposing the raw payload to the user.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" -- Optional global truncation limit for extracted Markdown returned to the model.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxContentCharacters", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, "url -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::READWEBPAGETOOL::T2765372972"] = "Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2765372972"] = "Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" -- Maximum Content Characters", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for loading a web page in seconds.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Optional global truncation limit for extracted Markdown returned to the model.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxContentCharacters", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, "url -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::READWEBPAGETOOL::T2860394705"] = "Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T2860394705"] = "Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" -- Timeout Seconds", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Maximum Content Characters", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for loading a web page in seconds.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Optional global truncation limit for extracted Markdown returned to the model.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxContentCharacters", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, "url -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::READWEBPAGETOOL::T3510104271"] = "Timeout Seconds\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3510104271"] = "Timeout Seconds\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" -- Load a single web page, extract its main HTML content, and return structured working material for the model. Use the result to synthesize a natural-language answer instead of exposing the raw payload to the user.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Maximum Content Characters", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for loading a web page in seconds.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), "maxContentCharacters" => I18N.I.T("Optional global truncation limit for extracted Markdown returned to the model.", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxContentCharacters", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, "url -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::READWEBPAGETOOL::T3614129091"] = "Load a single web page, extract its main HTML content, and return structured working material for the model. Use the result to synthesize a natural-language answer instead of exposing the raw payload to the user.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::READWEBPAGETOOL::T3614129091"] = "Load a single web page, extract its main HTML content, and return structured working material for the model. Use the result to synthesize a natural-language answer instead of exposing the raw payload to the user.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Maximum Content Characters\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for loading a web page in seconds.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), \"maxContentCharacters\" => I18N.I.T(\"Optional global truncation limit for extracted Markdown returned to the model.\", typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(ReadWebPageTool).Namespace, nameof(ReadWebPageTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxContentCharacters\", out _, out var contentError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = contentError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { var urlText = ReadRequiredString(arguments, \"url" -- Default Categories", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T1254458306"] = "Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1254458306"] = "Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T1327402904"] = "Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1327402904"] = "Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T1401266403"] = "Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1401266403"] = "Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T1539252250"] = "Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T1539252250"] = "Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T186659624"] = "Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T186659624"] = "Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Default categories and default engines cannot both be set for the web search tool.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool))); var defaultLimit = ReadOptionalPositiveIntSetting(context.SettingsValues, "maxResults -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2087438861"] = "Default categories and default engines cannot both be set for the web search tool.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool))); var defaultLimit = ReadOptionalPositiveIntSetting(context.SettingsValues, \"maxResults" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2087438861"] = "Default categories and default engines cannot both be set for the web search tool.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool))); var defaultLimit = ReadOptionalPositiveIntSetting(context.SettingsValues, \"maxResults" -- The configured SearXNG URL must start with http:// or https://.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } var basePath = parsedUri.AbsolutePath.TrimEnd('/'); if (basePath.EndsWith("/search", StringComparison.OrdinalIgnoreCase)) basePath = basePath[..^"/search".Length]; var normalizedPath = $"{basePath}/search"; var builder = new UriBuilder(parsedUri) { Path = normalizedPath, Query = string.Empty, Fragment = string.Empty, }; searchUri = builder.Uri; return true; } private static Uri BuildRequestUri(Uri searchUri, IEnumerable> queryParameters) { var builder = new StringBuilder(); foreach (var parameter in queryParameters) { if (builder.Length > 0) builder.Append('&'); builder.Append(WebUtility.UrlEncode(parameter.Key)); builder.Append('='); builder.Append(WebUtility.UrlEncode(parameter.Value)); } var uriBuilder = new UriBuilder(searchUri) { Query = builder.ToString(), }; return uriBuilder.Uri; } private static async Task SendAsync( HttpClient httpClient, HttpRequestMessage request, CancellationToken requestToken, int timeoutSeconds, CancellationToken callerToken) { try { return await httpClient.SendAsync(request, requestToken); } catch (OperationCanceledException) when (!callerToken.IsCancellationRequested) { throw new TimeoutException($"The SearXNG request timed out after {timeoutSeconds} seconds. -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T212620884"] = "The configured SearXNG URL must start with http:// or https://.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } var basePath = parsedUri.AbsolutePath.TrimEnd('/'); if (basePath.EndsWith(\"/search\", StringComparison.OrdinalIgnoreCase)) basePath = basePath[..^\"/search\".Length]; var normalizedPath = $\"{basePath}/search\"; var builder = new UriBuilder(parsedUri) { Path = normalizedPath, Query = string.Empty, Fragment = string.Empty, }; searchUri = builder.Uri; return true; } private static Uri BuildRequestUri(Uri searchUri, IEnumerable> queryParameters) { var builder = new StringBuilder(); foreach (var parameter in queryParameters) { if (builder.Length > 0) builder.Append('&'); builder.Append(WebUtility.UrlEncode(parameter.Key)); builder.Append('='); builder.Append(WebUtility.UrlEncode(parameter.Value)); } var uriBuilder = new UriBuilder(searchUri) { Query = builder.ToString(), }; return uriBuilder.Uri; } private static async Task SendAsync( HttpClient httpClient, HttpRequestMessage request, CancellationToken requestToken, int timeoutSeconds, CancellationToken callerToken) { try { return await httpClient.SendAsync(request, requestToken); } catch (OperationCanceledException) when (!callerToken.IsCancellationRequested) { throw new TimeoutException($\"The SearXNG request timed out after {timeoutSeconds} seconds." +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T212620884"] = "The configured SearXNG URL must start with http:// or https://.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } var basePath = parsedUri.AbsolutePath.TrimEnd('/'); if (basePath.EndsWith(\"/search\", StringComparison.OrdinalIgnoreCase)) basePath = basePath[..^\"/search\".Length]; var normalizedPath = $\"{basePath}/search\"; var builder = new UriBuilder(parsedUri) { Path = normalizedPath, Query = string.Empty, Fragment = string.Empty, }; searchUri = builder.Uri; return true; } private static Uri BuildRequestUri(Uri searchUri, IEnumerable> queryParameters) { var builder = new StringBuilder(); foreach (var parameter in queryParameters) { if (builder.Length > 0) builder.Append('&'); builder.Append(WebUtility.UrlEncode(parameter.Key)); builder.Append('='); builder.Append(WebUtility.UrlEncode(parameter.Value)); } var uriBuilder = new UriBuilder(searchUri) { Query = builder.ToString(), }; return uriBuilder.Uri; } private static async Task SendAsync( HttpClient httpClient, HttpRequestMessage request, CancellationToken requestToken, int timeoutSeconds, CancellationToken callerToken) { try { return await httpClient.SendAsync(request, requestToken); } catch (OperationCanceledException) when (!callerToken.IsCancellationRequested) { throw new TimeoutException($\"The SearXNG request timed out after {timeoutSeconds} seconds." -- Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2170342710"] = "Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2170342710"] = "Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- A SearXNG URL is required.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (!Uri.TryCreate(rawUrl.Trim(), UriKind.Absolute, out var parsedUri)) { error = I18N.I.T("The configured SearXNG URL is not a valid absolute URL.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (parsedUri.Scheme is not ("http" or "https -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2420801571"] = "A SearXNG URL is required.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (!Uri.TryCreate(rawUrl.Trim(), UriKind.Absolute, out var parsedUri)) { error = I18N.I.T(\"The configured SearXNG URL is not a valid absolute URL.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (parsedUri.Scheme is not (\"http\" or \"https" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2420801571"] = "A SearXNG URL is required.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (!Uri.TryCreate(rawUrl.Trim(), UriKind.Absolute, out var parsedUri)) { error = I18N.I.T(\"The configured SearXNG URL is not a valid absolute URL.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (parsedUri.Scheme is not (\"http\" or \"https" -- Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2435794648"] = "Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2435794648"] = "Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Default categories and default engines cannot both be set for the web search tool.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }); } if (!TryReadOptionalPositiveInt(settingsValues, "maxResults", out _, out var maxResultsError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = maxResultsError, }); } if (!TryReadOptionalPositiveInt(settingsValues, "timeoutSeconds", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { context.SettingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out var searchUri, out var uriError); if (!isValidBaseUrl) throw new InvalidOperationException(uriError); var query = ReadRequiredString(arguments, "query -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2471183191"] = "Default categories and default engines cannot both be set for the web search tool.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxResults\", out _, out var maxResultsError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = maxResultsError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { context.SettingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out var searchUri, out var uriError); if (!isValidBaseUrl) throw new InvalidOperationException(uriError); var query = ReadRequiredString(arguments, \"query" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2471183191"] = "Default categories and default engines cannot both be set for the web search tool.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }); } if (!TryReadOptionalPositiveInt(settingsValues, \"maxResults\", out _, out var maxResultsError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = maxResultsError, }); } if (!TryReadOptionalPositiveInt(settingsValues, \"timeoutSeconds\", out _, out var timeoutError)) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = timeoutError, }); } return Task.FromResult(null); } public async Task ExecuteAsync(JsonElement arguments, ToolExecutionContext context, CancellationToken token = default) { context.SettingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out var searchUri, out var uriError); if (!isValidBaseUrl) throw new InvalidOperationException(uriError); var query = ReadRequiredString(arguments, \"query" -- SearXNG URL", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Default Language", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Default Safe Search", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Default Categories", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2707478507"] = "SearXNG URL\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2707478507"] = "SearXNG URL\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2911071656"] = "Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2911071656"] = "Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T2953585467"] = "Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T2953585467"] = "Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Web Search", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetDescription() => I18N.I.T("Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("SearXNG URL", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Default Language", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Default Safe Search", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Default Categories", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T3158851812"] = "Web Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetDescription() => I18N.I.T(\"Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"SearXNG URL\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3158851812"] = "Web Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetDescription() => I18N.I.T(\"Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"SearXNG URL\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T3332435511"] = "Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3332435511"] = "Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- The configured SearXNG URL is not a valid absolute URL.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (parsedUri.Scheme is not ("http" or "https -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T371406570"] = "The configured SearXNG URL is not a valid absolute URL.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (parsedUri.Scheme is not (\"http\" or \"https" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T371406570"] = "The configured SearXNG URL is not a valid absolute URL.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); return false; } if (parsedUri.Scheme is not (\"http\" or \"https" -- Default Safe Search", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Default Categories", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T3780386928"] = "Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T3780386928"] = "Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("SearXNG URL", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Default Language", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Default Safe Search", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Default Categories", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T4262764011"] = "Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"SearXNG URL\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T4262764011"] = "Search the web with a configured SearXNG instance and return candidate URLs for the model. Use Read Web Page on relevant result URLs before answering factual or detailed web questions.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)); public string GetSettingsFieldLabel(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"SearXNG URL\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Default Language", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Default Safe Search", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Default Categories", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Default Engines", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Maximum Results", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Timeout Seconds", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { "baseUrl" => I18N.I.T("Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T54221234"] = "Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T54221234"] = "Default Language\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Default Safe Search\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Default Categories\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Default Engines\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Maximum Results\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Timeout Seconds\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Title, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public string GetSettingsFieldDescription(string fieldName, ToolSettingsFieldDefinition fieldDefinition) => fieldName switch { \"baseUrl\" => I18N.I.T(\"Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultLanguage" => I18N.I.T("Optional fallback language code when the model does not provide a language.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultSafeSearch" => I18N.I.T("Optional safe search policy sent to SearXNG when configured.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultCategories" => I18N.I.T("Optional comma-separated default categories. Do not set this together with default engines.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "defaultEngines" => I18N.I.T("Optional comma-separated default engines. Do not set this together with default categories.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "maxResults" => I18N.I.T("Optional default maximum number of results returned to the model when the model does not provide a limit.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), "timeoutSeconds" => I18N.I.T("Optional HTTP timeout for the search request in seconds.", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue("baseUrl", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault("defaultCategories -UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::SEARXNGWEBSEARCHTOOL::T54269506"] = "Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" +UI_TEXT_CONTENT["AISTUDIO::TOOLS::TOOLCALLINGSYSTEM::TOOLCALLINGIMPLEMENTATIONS::SEARXNGWEBSEARCHTOOL::T54269506"] = "Base URL of the SearXNG instance. You can enter either the instance root URL or the /search endpoint.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultLanguage\" => I18N.I.T(\"Optional fallback language code when the model does not provide a language.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultSafeSearch\" => I18N.I.T(\"Optional safe search policy sent to SearXNG when configured.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultCategories\" => I18N.I.T(\"Optional comma-separated default categories. Do not set this together with default engines.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"defaultEngines\" => I18N.I.T(\"Optional comma-separated default engines. Do not set this together with default categories.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"maxResults\" => I18N.I.T(\"Optional default maximum number of results returned to the model when the model does not provide a limit.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), \"timeoutSeconds\" => I18N.I.T(\"Optional HTTP timeout for the search request in seconds.\", typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), _ => I18N.I.T(fieldDefinition.Description, typeof(SearXNGWebSearchTool).Namespace, nameof(SearXNGWebSearchTool)), }; public Task ValidateConfigurationAsync( ToolDefinition definition, IReadOnlyDictionary settingsValues, CancellationToken token = default) { settingsValues.TryGetValue(\"baseUrl\", out var baseUrl); var isValidBaseUrl = TryNormalizeSearchUri(baseUrl ?? string.Empty, out _, out var uriError); if (!isValidBaseUrl) { return Task.FromResult(new ToolConfigurationState { IsConfigured = false, Message = uriError, }); } var hasDefaultCategories = !string.IsNullOrWhiteSpace(settingsValues.GetValueOrDefault(\"defaultCategories" -- Pandoc Installation UI_TEXT_CONTENT["AISTUDIO::TOOLS::USERFILE::T185447014"] = "Pandoc Installation" diff --git a/app/MindWork AI Studio/Chat/ChatThread.cs b/app/MindWork AI Studio/Chat/ChatThread.cs index 2617d179..2ba1d7d5 100644 --- a/app/MindWork AI Studio/Chat/ChatThread.cs +++ b/app/MindWork AI Studio/Chat/ChatThread.cs @@ -230,22 +230,21 @@ public sealed record ChatThread var normalizedToolIds = ToolSelectionRules.NormalizeSelection(this.RuntimeSelectedToolIds); var hasWebSearch = normalizedToolIds.Contains(ToolSelectionRules.WEB_SEARCH_TOOL_ID); var hasReadWebPage = normalizedToolIds.Contains(ToolSelectionRules.READ_WEB_PAGE_TOOL_ID); - if (!hasWebSearch || !hasReadWebPage) - return string.Empty; - - return """ - Tool usage policy for web research: - - - Use `web_search` to discover relevant candidate URLs. - - Do not answer substantive web questions from search snippets alone when `read_web_page` is available. - - After `web_search`, use `read_web_page` on at least one relevant result before answering questions that require facts, summaries, comparisons, current information, or other page-level details. - - Search snippets alone are only sufficient for simple link-finding or very high-level orientation. - - Prefer answering from the extracted page content when it is available. - - Never expose raw tool outputs, JSON objects, or internal tool payloads to the user unless the user explicitly asks for structured output. - - Summarize tool results in natural language. - - Treat `read_web_page` results as working material for synthesis, not as final answer text. - - Do not paste wrapper fields such as `metadata`, `content_markdown`, or `warnings` verbatim into the final answer. - """; + + if (hasWebSearch && hasReadWebPage) + return """ + Tool usage policy for web search: + - Use the `web_search`-tool to discover relevant candidate URLs. + - Do not answer substantive web questions from search snippets alone when `read_web_page` is available. + - Search snippets alone are only sufficient for simple link-finding or very high-level orientation. + - After `web_search`, use the `read_web_page`-tool on at least one relevant result before answering questions that require facts, summaries, comparisons, current information, or other page-level details. + - Prefer answering from the extracted page content when it is available. + - Summarize tool results in natural language. + - Treat `read_web_page` results as working material for synthesis, not as final answer text. + - Add a sources-section to the end of your answer, where you link the sources that you used. + """; + + return string.Empty; } /// diff --git a/app/MindWork AI Studio/Program.cs b/app/MindWork AI Studio/Program.cs index e83fda0b..0effbcc5 100644 --- a/app/MindWork AI Studio/Program.cs +++ b/app/MindWork AI Studio/Program.cs @@ -5,7 +5,7 @@ using AIStudio.Tools.Databases; using AIStudio.Tools.Databases.Qdrant; using AIStudio.Tools.PluginSystem; using AIStudio.Tools.Services; - +using AIStudio.Tools.ToolCallingSystem.ToolCallingImplementations; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Logging.Console; diff --git a/app/MindWork AI Studio/Tools/HTMLParser.cs b/app/MindWork AI Studio/Tools/HTMLParser.cs index e627c535..56aceee4 100644 --- a/app/MindWork AI Studio/Tools/HTMLParser.cs +++ b/app/MindWork AI Studio/Tools/HTMLParser.cs @@ -1,6 +1,6 @@ using System.Net; using System.Net.Http; -using System.Text; +using System.Net.Http.Headers; using HtmlAgilityPack; @@ -10,6 +10,8 @@ namespace AIStudio.Tools; public sealed class HTMLParser { + private const string USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) MindWorkAIStudio/1.0"; + private static readonly Config MARKDOWN_PARSER_CONFIG = new() { UnknownTags = Config.UnknownTagsOption.Bypass, @@ -43,14 +45,38 @@ public sealed class HTMLParser public async Task LoadWebPageAsync(Uri url, CancellationToken token = default, int timeoutSeconds = 30) { - using var httpClient = new HttpClient + using var handler = new HttpClientHandler + { + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli, + }; + using var httpClient = new HttpClient(handler) { Timeout = Timeout.InfiniteTimeSpan, }; using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(token); timeoutCts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds)); - using var response = await httpClient.GetAsync(url, timeoutCts.Token); - response.EnsureSuccessStatusCode(); + using var request = new HttpRequestMessage(HttpMethod.Get, url); + request.Headers.TryAddWithoutValidation("User-Agent", USER_AGENT); + request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html")); + request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xhtml+xml")); + request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-US")); + request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en", 0.9)); + request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); + request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); + request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("br")); + request.Headers.TryAddWithoutValidation("Upgrade-Insecure-Requests", "1"); + request.Headers.TryAddWithoutValidation("Sec-Fetch-Site", "none"); + request.Headers.TryAddWithoutValidation("Sec-Fetch-Mode", "navigate"); + request.Headers.TryAddWithoutValidation("Sec-Fetch-Dest", "document"); + request.Headers.TryAddWithoutValidation("Sec-Fetch-User", "?1"); + + using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeoutCts.Token); + if (!response.IsSuccessStatusCode) + { + var statusCode = (int)response.StatusCode; + var reasonPhrase = string.IsNullOrWhiteSpace(response.ReasonPhrase) ? "Unknown" : response.ReasonPhrase; + throw new HttpRequestException($"The server returned HTTP {statusCode} ({reasonPhrase}) for '{url}'.", null, response.StatusCode); + } var html = await response.Content.ReadAsStringAsync(token); var document = new HtmlDocument();