refactor: Restructure file search settings

This commit restructures the file search settings. The previously individual settings for file search method, regex search backend, match search backend, and ripgrep path have been grouped into a new filesSearchSettings object.
This commit is contained in:
travertexg 2025-06-10 06:54:25 +00:00
parent a00b640dad
commit f0be561cfc
10 changed files with 63 additions and 28 deletions

View File

@ -611,7 +611,7 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
} }
} }
} else if (toolArgs.type === 'match_search_files') { } else if (toolArgs.type === 'match_search_files') {
const searchBackend = settings.matchSearchBackend const searchBackend = settings.filesSearchSettings.matchBackend
let results: string; let results: string;
if (searchBackend === 'omnisearch') { if (searchBackend === 'omnisearch') {
results = await matchSearchUsingOmnisearch(toolArgs.query, app) results = await matchSearchUsingOmnisearch(toolArgs.query, app)
@ -633,7 +633,7 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
} }
} }
} else if (toolArgs.type === 'regex_search_files') { } else if (toolArgs.type === 'regex_search_files') {
const searchBackend = settings.regexSearchBackend const searchBackend = settings.filesSearchSettings.regexBackend
let results: string; let results: string;
if (searchBackend === 'coreplugin') { if (searchBackend === 'coreplugin') {
results = await regexSearchUsingCorePlugin(toolArgs.regex, app) results = await regexSearchUsingCorePlugin(toolArgs.regex, app)
@ -641,7 +641,7 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
// @ts-expect-error Obsidian API type mismatch // @ts-expect-error Obsidian API type mismatch
const baseVaultPath = String(app.vault.adapter.getBasePath()) const baseVaultPath = String(app.vault.adapter.getBasePath())
const absolutePath = path.join(baseVaultPath, toolArgs.filepath) const absolutePath = path.join(baseVaultPath, toolArgs.filepath)
const ripgrepPath = settings.ripgrepPath const ripgrepPath = settings.filesSearchSettings.ripgrepPath
results = await regexSearchUsingRipgrep(absolutePath, toolArgs.regex, ripgrepPath) results = await regexSearchUsingRipgrep(absolutePath, toolArgs.regex, ripgrepPath)
} }
const formattedContent = `[regex_search_files for '${toolArgs.filepath}'] Result:\n${results}\n`; const formattedContent = `[regex_search_files for '${toolArgs.filepath}'] Result:\n${results}\n`;

View File

@ -367,7 +367,7 @@ const CustomModeView = () => {
{t('prompt.overrideWarning')} <button {t('prompt.overrideWarning')} <button
className="infio-preview-btn" className="infio-preview-btn"
onClick={async () => { onClick={async () => {
let filesSearchMethod = settings.filesSearchMethod let filesSearchMethod = settings.filesSearchSettings.method
if (filesSearchMethod === 'auto' && settings.embeddingModelId && settings.embeddingModelId !== '') { if (filesSearchMethod === 'auto' && settings.embeddingModelId && settings.embeddingModelId !== '') {
filesSearchMethod = 'semantic' filesSearchMethod = 'semantic'
} }

View File

@ -3,6 +3,7 @@ import * as path from 'path'
import { App, normalizePath } from 'obsidian' import { App, normalizePath } from 'obsidian'
import { FilesSearchSettings } from "../../types/settings"
import { import {
CustomModePrompts, CustomModePrompts,
Mode, Mode,
@ -68,6 +69,7 @@ export class SystemPrompt {
cwd: string, cwd: string,
supportsComputerUse: boolean, supportsComputerUse: boolean,
mode: Mode, mode: Mode,
searchSettings: FilesSearchSettings,
filesSearchMethod: string, filesSearchMethod: string,
mcpHub?: McpHub, mcpHub?: McpHub,
diffStrategy?: DiffStrategy, diffStrategy?: DiffStrategy,
@ -105,6 +107,7 @@ ${getSharedToolUseSection()}
${getToolDescriptionsForMode( ${getToolDescriptionsForMode(
mode, mode,
cwd, cwd,
searchSettings,
filesSearchMethod, filesSearchMethod,
supportsComputerUse, supportsComputerUse,
diffStrategy, diffStrategy,
@ -148,6 +151,7 @@ ${await addCustomInstructions(this.app, promptComponent?.customInstructions || m
cwd: string, cwd: string,
supportsComputerUse: boolean, supportsComputerUse: boolean,
mode: Mode = defaultModeSlug, mode: Mode = defaultModeSlug,
searchSettings: FilesSearchSettings,
filesSearchMethod: string = 'regex', filesSearchMethod: string = 'regex',
preferredLanguage?: string, preferredLanguage?: string,
diffStrategy?: DiffStrategy, diffStrategy?: DiffStrategy,
@ -203,6 +207,7 @@ ${customInstructions}`
cwd, cwd,
supportsComputerUse, supportsComputerUse,
currentMode.slug, currentMode.slug,
searchSettings,
filesSearchMethod, filesSearchMethod,
mcpHub, mcpHub,
diffStrategy, diffStrategy,

View File

@ -1,6 +1,7 @@
import { Mode, ModeConfig, getGroupName, getModeConfig, isToolAllowedForMode } from "../../../utils/modes" import { Mode, ModeConfig, getGroupName, getModeConfig, isToolAllowedForMode } from "../../../utils/modes"
import { DiffStrategy } from "../../diff/DiffStrategy" import { DiffStrategy } from "../../diff/DiffStrategy"
import { McpHub } from "../../mcp/McpHub" import { McpHub } from "../../mcp/McpHub"
import { FilesSearchSettings } from "../../../types/settings"
import { getAccessMcpResourceDescription } from "./access-mcp-resource" import { getAccessMcpResourceDescription } from "./access-mcp-resource"
import { getAskFollowupQuestionDescription } from "./ask-followup-question" import { getAskFollowupQuestionDescription } from "./ask-followup-question"
@ -40,6 +41,7 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
export function getToolDescriptionsForMode( export function getToolDescriptionsForMode(
mode: Mode, mode: Mode,
cwd: string, cwd: string,
searchSettings: FilesSearchSettings,
searchTool: string, searchTool: string,
supportsComputerUse: boolean, supportsComputerUse: boolean,
diffStrategy?: DiffStrategy, diffStrategy?: DiffStrategy,
@ -51,6 +53,7 @@ export function getToolDescriptionsForMode(
const config = getModeConfig(mode, customModes) const config = getModeConfig(mode, customModes)
const args: ToolArgs = { const args: ToolArgs = {
cwd, cwd,
searchSettings,
searchTool, searchTool,
supportsComputerUse, supportsComputerUse,
diffStrategy, diffStrategy,

View File

@ -1,5 +1,4 @@
import { ToolArgs } from "./types" import { ToolArgs } from "./types"
import { useSettings } from '../../../contexts/SettingsContext'
export function getSearchFilesDescription(args: ToolArgs): string { export function getSearchFilesDescription(args: ToolArgs): string {
if (args.searchTool === 'match') { if (args.searchTool === 'match') {
@ -34,9 +33,8 @@ Example: Requesting to search for all Markdown files containing 'test' in the cu
} }
export function getRegexSearchFilesDescription(args: ToolArgs): string { export function getRegexSearchFilesDescription(args: ToolArgs): string {
const { settings } = useSettings()
let regex_syntax: string; let regex_syntax: string;
switch (settings.regexSearchBackend) { switch (args.searchSettings.regexBackend) {
case 'coreplugin': case 'coreplugin':
regex_syntax = "ECMAScript (JavaScript)"; regex_syntax = "ECMAScript (JavaScript)";
break; break;

View File

@ -1,8 +1,10 @@
import { FilesSearchSettings } from "../../../types/settings"
import { DiffStrategy } from "../../diff/DiffStrategy" import { DiffStrategy } from "../../diff/DiffStrategy"
import { McpHub } from "../../mcp/McpHub" import { McpHub } from "../../mcp/McpHub"
export type ToolArgs = { export type ToolArgs = {
cwd: string cwd: string
searchSettings: FilesSearchSettings,
searchTool?: string, searchTool?: string,
supportsComputerUse: boolean supportsComputerUse: boolean
diffStrategy?: DiffStrategy diffStrategy?: DiffStrategy

View File

@ -156,11 +156,14 @@ export class InfioSettingTab extends PluginSettingTab {
.addOption('semantic', t('settings.FilesSearch.semantic')) .addOption('semantic', t('settings.FilesSearch.semantic'))
.addOption('regex', t('settings.FilesSearch.regex')) .addOption('regex', t('settings.FilesSearch.regex'))
.addOption('match', t('settings.FilesSearch.match')) .addOption('match', t('settings.FilesSearch.match'))
.setValue(this.plugin.settings.filesSearchMethod) .setValue(this.plugin.settings.filesSearchSettings.method)
.onChange(async (value) => { .onChange(async (value) => {
await this.plugin.setSettings({ await this.plugin.setSettings({
...this.plugin.settings, ...this.plugin.settings,
filesSearchMethod: value as 'match' | 'regex' | 'semantic' | 'auto', filesSearchSettings: {
...this.plugin.settings.filesSearchSettings,
method: value as 'match' | 'regex' | 'semantic' | 'auto',
}
}) })
}), }),
) )
@ -171,11 +174,14 @@ export class InfioSettingTab extends PluginSettingTab {
dropdown dropdown
.addOption('ripgrep', t('settings.FilesSearch.ripgrep')) .addOption('ripgrep', t('settings.FilesSearch.ripgrep'))
.addOption('coreplugin', t('settings.FilesSearch.coreplugin')) .addOption('coreplugin', t('settings.FilesSearch.coreplugin'))
.setValue(this.plugin.settings.regexSearchBackend) .setValue(this.plugin.settings.filesSearchSettings.regexBackend)
.onChange(async (value) => { .onChange(async (value) => {
await this.plugin.setSettings({ await this.plugin.setSettings({
...this.plugin.settings, ...this.plugin.settings,
regexSearchBackend: value as 'ripgrep' | 'coreplugin', filesSearchSettings: {
...this.plugin.settings.filesSearchSettings,
regexBackend: value as 'ripgrep' | 'coreplugin',
}
}) })
}), }),
) )
@ -186,11 +192,14 @@ export class InfioSettingTab extends PluginSettingTab {
dropdown dropdown
.addOption('coreplugin', t('settings.FilesSearch.coreplugin')) .addOption('coreplugin', t('settings.FilesSearch.coreplugin'))
.addOption('omnisearch', t('settings.FilesSearch.omnisearch')) .addOption('omnisearch', t('settings.FilesSearch.omnisearch'))
.setValue(this.plugin.settings.matchSearchBackend) .setValue(this.plugin.settings.filesSearchSettings.matchBackend)
.onChange(async (value) => { .onChange(async (value) => {
await this.plugin.setSettings({ await this.plugin.setSettings({
...this.plugin.settings, ...this.plugin.settings,
matchSearchBackend: value as 'coreplugin' | 'omnisearch', filesSearchSettings: {
...this.plugin.settings.filesSearchSettings,
matchBackend: value as 'coreplugin' | 'omnisearch',
}
}) })
}), }),
) )
@ -200,11 +209,14 @@ export class InfioSettingTab extends PluginSettingTab {
.addText((text) => .addText((text) =>
text text
.setPlaceholder('/opt/homebrew/bin/') .setPlaceholder('/opt/homebrew/bin/')
.setValue(this.plugin.settings.ripgrepPath) .setValue(this.plugin.settings.filesSearchSettings.ripgrepPath)
.onChange(async (value) => { .onChange(async (value) => {
await this.plugin.setSettings({ await this.plugin.setSettings({
...this.plugin.settings, ...this.plugin.settings,
ripgrepPath: value, filesSearchSettings: {
...this.plugin.settings.filesSearchSettings,
ripgrepPath: value,
}
}) })
}), }),
) )

View File

@ -12,9 +12,12 @@ describe('parseSmartCopilotSettings', () => {
infioApiKey: '', infioApiKey: '',
openAIApiKey: '', openAIApiKey: '',
anthropicApiKey: '', anthropicApiKey: '',
filesSearchMethod: 'auto', filesSearchSettings: {
regexSearchBackend: 'ripgrep', method: 'auto',
matchSearchBackend: 'coreplugin', regexBackend: 'ripgrep',
matchBackend: 'coreplugin',
ripgrepPath: '',
},
fuzzyMatchThreshold: 0.85, fuzzyMatchThreshold: 0.85,
geminiApiKey: '', geminiApiKey: '',
groqApiKey: '', groqApiKey: '',
@ -100,7 +103,6 @@ describe('parseSmartCopilotSettings', () => {
defaultMention: 'none', defaultMention: 'none',
removeDuplicateMathBlockIndicator: true, removeDuplicateMathBlockIndicator: true,
removeDuplicateCodeBlockIndicator: true, removeDuplicateCodeBlockIndicator: true,
ripgrepPath: '',
serperApiKey: '', serperApiKey: '',
serperSearchEngine: 'google', serperSearchEngine: 'google',
ignoredFilePatterns: '**/secret/**\n', ignoredFilePatterns: '**/secret/**\n',
@ -197,9 +199,12 @@ describe('settings migration', () => {
infioApiKey: '', infioApiKey: '',
openAIApiKey: '', openAIApiKey: '',
anthropicApiKey: '', anthropicApiKey: '',
filesSearchMethod: 'auto', filesSearchSettings: {
regexSearchBackend: 'ripgrep', method: 'auto',
matchSearchBackend: 'coreplugin', regexBackend: 'ripgrep',
matchBackend: 'coreplugin',
ripgrepPath: '',
},
fuzzyMatchThreshold: 0.85, fuzzyMatchThreshold: 0.85,
geminiApiKey: '', geminiApiKey: '',
groqApiKey: '', groqApiKey: '',
@ -285,7 +290,6 @@ describe('settings migration', () => {
defaultMention: 'none', defaultMention: 'none',
removeDuplicateMathBlockIndicator: true, removeDuplicateMathBlockIndicator: true,
removeDuplicateCodeBlockIndicator: true, removeDuplicateCodeBlockIndicator: true,
ripgrepPath: '',
serperApiKey: '', serperApiKey: '',
serperSearchEngine: 'google', serperSearchEngine: 'google',
ignoredFilePatterns: '**/secret/**\n', ignoredFilePatterns: '**/secret/**\n',

View File

@ -201,6 +201,18 @@ export const triggerSchema = z.object({
} }
}); });
const FilesSearchSettingsSchema = z.object({
method: z.enum(['match', 'regex', 'semantic', 'auto']).catch('auto'),
regexBackend: z.enum(['coreplugin', 'ripgrep']).catch('ripgrep'),
matchBackend: z.enum(['omnisearch', 'coreplugin']).catch('coreplugin'),
ripgrepPath: z.string().catch(''),
}).catch({
method: 'auto',
regexBackend: 'ripgrep',
matchBackend: 'coreplugin',
ripgrepPath: '',
});
export const InfioSettingsSchema = z.object({ export const InfioSettingsSchema = z.object({
// Version // Version
version: z.literal(SETTINGS_SCHEMA_VERSION).catch(SETTINGS_SCHEMA_VERSION), version: z.literal(SETTINGS_SCHEMA_VERSION).catch(SETTINGS_SCHEMA_VERSION),
@ -260,10 +272,7 @@ export const InfioSettingsSchema = z.object({
jinaApiKey: z.string().catch(''), jinaApiKey: z.string().catch(''),
// Files Search // Files Search
filesSearchMethod: z.enum(['match', 'regex', 'semantic', 'auto']).catch('auto'), filesSearchSettings: FilesSearchSettingsSchema,
regexSearchBackend: z.enum(['coreplugin', 'ripgrep']).catch('ripgrep'),
matchSearchBackend: z.enum(['omnisearch', 'coreplugin']).catch('coreplugin'),
ripgrepPath: z.string().catch(''),
/// [compatible] /// [compatible]
// activeModels [compatible] // activeModels [compatible]
@ -365,6 +374,7 @@ export const InfioSettingsSchema = z.object({
}) })
export type InfioSettings = z.infer<typeof InfioSettingsSchema> export type InfioSettings = z.infer<typeof InfioSettingsSchema>
export type FilesSearchSettings = z.infer<typeof FilesSearchSettingsSchema>
type Migration = { type Migration = {
fromVersion: number fromVersion: number

View File

@ -182,7 +182,7 @@ export class PromptGenerator {
}, },
] ]
let filesSearchMethod = this.settings.filesSearchMethod let filesSearchMethod = this.settings.filesSearchSettings.method
if (filesSearchMethod === 'auto' && this.settings.embeddingModelId && this.settings.embeddingModelId !== '') { if (filesSearchMethod === 'auto' && this.settings.embeddingModelId && this.settings.embeddingModelId !== '') {
filesSearchMethod = 'semantic' filesSearchMethod = 'semantic'
} }
@ -520,6 +520,7 @@ export class PromptGenerator {
this.app.vault.getRoot().path, this.app.vault.getRoot().path,
false, false,
mode, mode,
this.settings.filesSearchSettings,
filesSearchMethod, filesSearchMethod,
preferredLanguage, preferredLanguage,
this.diffStrategy, this.diffStrategy,