feat(FN-3901): add builtin research web-search provider as default

The merge adds a builtin web-search research provider as the default, replacing the need for external research provider configuration and removing the setup gate for builtin defaults. Dashboard settings UX for research defaults was aligned (ResearchView, SettingsModal), CLI research commands were up

Fusion-Task-Id: FN-3901
This commit is contained in:
Fusion
2026-05-09 19:37:31 -07:00
committed by gsxdsm
parent 1caed5c586
commit d25e8cbfa9
21 changed files with 493 additions and 187 deletions

View File

@@ -95,6 +95,14 @@ describe("resolveResearchSettings", () => {
expect(resolved.searchProvider).toBe("brave");
});
it("honors explicit legacy global search provider opt-out", () => {
const resolved = resolveResearchSettings({
researchGlobalWebSearchProvider: "none",
});
expect(resolved.searchProvider).toBe("none");
});
it("supports null-as-delete semantics for researchSettings object", () => {
const resolved = resolveResearchSettings({
researchGlobalDefaults: {
@@ -123,6 +131,7 @@ describe("resolveResearchSettings", () => {
expect(fromLegacyGlobalTimeout.limits.maxConcurrentRuns).toBe(9);
const hardcodedFallback = resolveResearchSettings({});
expect(hardcodedFallback.searchProvider).toBe("builtin");
expect(hardcodedFallback.limits.maxDurationMs).toBe(300000);
expect(hardcodedFallback.limits.requestTimeoutMs).toBe(30000);
expect(hardcodedFallback.defaultExportFormat).toBe("markdown");

View File

@@ -20,6 +20,8 @@ export interface ResolvedResearchSettings {
defaultExportFormat: "markdown" | "json";
}
const DEFAULT_SEARCH_PROVIDER = "builtin";
const FALLBACK_SOURCES: ResearchEnabledSources = {
webSearch: true,
pageFetch: true,
@@ -34,7 +36,11 @@ export function resolveResearchSettings(settings: Partial<Settings> | undefined)
return {
enabled: projectSettings?.enabled ?? settings?.researchEnabled ?? settings?.researchGlobalEnabled ?? true,
searchProvider: projectSettings?.searchProvider ?? globalDefaults?.searchProvider,
searchProvider:
projectSettings?.searchProvider ??
globalDefaults?.searchProvider ??
settings?.researchGlobalWebSearchProvider ??
DEFAULT_SEARCH_PROVIDER,
synthesisProvider: projectSettings?.synthesisProvider ?? globalDefaults?.synthesisProvider,
synthesisModelId: projectSettings?.synthesisModelId ?? globalDefaults?.synthesisModelId,
enabledSources: {

View File

@@ -104,7 +104,7 @@ export const DEFAULT_GLOBAL_SETTINGS = {
researchGlobalDefaultTimeout: 300000,
researchGlobalMaxSourcesPerRun: 20,
researchGlobalMaxSynthesisRounds: 2,
researchGlobalWebSearchProvider: "none",
researchGlobalWebSearchProvider: "builtin",
researchGlobalSearxngUrl: undefined,
researchGlobalBraveApiKey: undefined,
researchGlobalGoogleSearchApiKey: undefined,

View File

@@ -1449,7 +1449,7 @@ export interface DaemonTokenSettings {
* The dashboard UI shows these under a "Global" section.
*/
/** Web search backend for auto-research provider. */
export type WebSearchBackend = "searxng" | "brave" | "google" | "tavily" | "none";
export type WebSearchBackend = "builtin" | "searxng" | "brave" | "google" | "tavily" | "none";
export interface ResearchEnabledSources {
webSearch: boolean;
@@ -1767,7 +1767,7 @@ export interface GlobalSettings {
/** Default maximum number of synthesis rounds per run.
* Default: 2. */
researchGlobalMaxSynthesisRounds?: number;
/** Web search backend for auto-research. Default: "none" (disabled). */
/** Web search backend for auto-research. Default: "builtin". */
researchGlobalWebSearchProvider?: WebSearchBackend;
/** SearXNG instance URL (required when researchGlobalWebSearchProvider is "searxng"). */
researchGlobalSearxngUrl?: string;