using AIStudio.Tools.PluginSystem; using AIStudio.Tools.ToolCallingSystem.ToolCallingImplementations.WebSearch; namespace AIStudio.Tools.ToolCallingSystem; /// /// Lists of settings options the app already knows, so a tool definition can point at one /// instead of spelling it out. /// /// /// A tool setting may declare a fixed list of values through its enum field. That works for a /// handful of values, but not for lists the app maintains elsewhere: repeating every language in /// every tool definition would mean the list exists twice and drifts apart. It also leaves the /// user with raw values in the dropdown, because a plain enum entry carries no readable name. /// An option source solves both — the values come from one place in the code, together with the /// translated names. /// public static class ToolSettingsOptionSources { private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ToolSettingsOptionSources).Namespace, nameof(ToolSettingsOptionSources)); /// /// The languages a search or translation setting can be set to, as IETF language tags. /// public const string COMMON_LANGUAGES = "common_languages"; /// /// The safe search policies of a search engine. /// public const string SAFE_SEARCH = "safe_search"; /// /// The value asking a search engine not to restrict results to one language. /// /// /// This is SearXNG's own wording for it, and the reason the language list here is not simply /// the common languages: those offer "do not change" and "other", which a search engine /// cannot act on.

/// A search backend whose service words it differently, or which cannot search without a /// language at all, recognizes the value by this constant and says in its result what it /// did instead. ///
public const string ANY_LANGUAGE = "all"; /// /// The search services the web search tool can be pointed at. /// /// /// The values are the names of the backend enum members, which is also how a chosen service /// is stored and how an organization's configuration addresses one. /// public const string WEB_SEARCH_BACKENDS = "web_search_backends"; /// /// The ways the web search tool can use several configured search services. /// public const string WEB_SEARCH_BACKEND_STRATEGY = "web_search_backend_strategy"; public static bool IsKnown(string optionSource) => optionSource is COMMON_LANGUAGES or SAFE_SEARCH or WEB_SEARCH_BACKENDS or WEB_SEARCH_BACKEND_STRATEGY; /// /// Resolves one option source to its current values and names. /// /// /// The names are translated, so this must be called when the dialog renders, not cached. /// public static IReadOnlyList Resolve(string optionSource) => optionSource switch { COMMON_LANGUAGES => BuildLanguageOptions(), SAFE_SEARCH => [ new(nameof(SafeSearchPolicy.OFF), TB("Off")), new(nameof(SafeSearchPolicy.MODERATE), TB("Moderate")), new(nameof(SafeSearchPolicy.STRICT), TB("Strict")), ], // // Product names, so they come from the backend enum itself rather than from a // translation. Adding a search service therefore adds it to this list, and to the // dropdown offering it, without a line of code here: // WEB_SEARCH_BACKENDS => Enum.GetValues().Select(backend => new ToolSettingsOption(backend.ToString(), backend.ToName())).ToList(), WEB_SEARCH_BACKEND_STRATEGY => [ new(nameof(WebSearchBackendStrategy.FAILOVER), TB("One after another, until one answers")), new(nameof(WebSearchBackendStrategy.PARALLEL), TB("All of them at once, results combined")), new(nameof(WebSearchBackendStrategy.SPECIFIC), TB("Only the preferred one")), ], _ => [], }; /// /// The values an option source accepts, for validating what was stored. /// public static IReadOnlySet GetValues(string optionSource) => Resolve(optionSource) .Select(option => option.Value) .ToHashSet(StringComparer.Ordinal); private static List BuildLanguageOptions() { List options = [new(ANY_LANGUAGE, TB("Any language"))]; foreach (var language in Enum.GetValues()) { // // Only languages with a real tag: AS_IS and OTHER exist for the assistants, where the // user may keep a text as it is or type a language of their own. A search engine needs // a concrete tag, and ANY_LANGUAGE above already covers "no preference". // var tag = language.ToIETFTag(); if (!string.IsNullOrWhiteSpace(tag)) options.Add(new(tag, language.Name())); } return options; } }