Optimize the search view component, add workspace statistics and RAG vector initialization features, update internationalization support, improve user interaction prompts, enhance log output, and ensure better user experience and code readability.

This commit is contained in:
duanfuxiang
2025-07-07 09:47:37 +08:00
parent 51f8620815
commit 3db334c6e8
10 changed files with 1532 additions and 39 deletions

View File

@@ -2,11 +2,13 @@ import { App, TFile } from 'obsidian'
import { QueryProgressState } from '../../components/chat-view/QueryProgress'
import { DBManager } from '../../database/database-manager'
import { Workspace } from '../../database/json/workspace/types'
import { VectorManager } from '../../database/modules/vector/vector-manager'
import { SelectVector } from '../../database/schema'
import { EmbeddingModel } from '../../types/embedding'
import { ApiProvider } from '../../types/llm/model'
import { InfioSettings } from '../../types/settings'
import { getFilesWithTag } from '../../utils/glob-utils'
import { getEmbeddingModel } from './embedding'
@@ -103,6 +105,36 @@ export class RAGEngine {
this.initialized = true
}
async updateWorkspaceIndex(
workspace: Workspace,
options: { reindexAll: boolean },
onQueryProgressChange?: (queryProgress: QueryProgressState) => void,
): Promise<void> {
if (!this.embeddingModel) {
throw new Error('Embedding model is not set')
}
await this.initializeDimension()
await this.vectorManager.updateWorkspaceIndex(
this.embeddingModel,
workspace,
{
chunkSize: this.settings.ragOptions.chunkSize,
batchSize: this.settings.ragOptions.batchSize,
excludePatterns: this.settings.ragOptions.excludePatterns,
includePatterns: this.settings.ragOptions.includePatterns,
reindexAll: options.reindexAll,
},
(indexProgress) => {
onQueryProgressChange?.({
type: 'indexing',
indexProgress,
})
},
)
this.initialized = true
}
async updateFileIndex(file: TFile) {
if (!this.embeddingModel) {
throw new Error('Embedding model is not set')
@@ -185,4 +217,65 @@ export class RAGEngine {
}
return this.embeddingModel.getEmbedding(query)
}
async getWorkspaceStatistics(workspace?: Workspace): Promise<{
totalFiles: number
totalChunks: number
}> {
if (!this.embeddingModel) {
throw new Error('Embedding model is not set')
}
await this.initializeDimension()
return await this.vectorManager.getWorkspaceStatistics(this.embeddingModel, workspace)
}
async getVaultStatistics(): Promise<{
totalFiles: number
totalChunks: number
}> {
if (!this.embeddingModel) {
throw new Error('Embedding model is not set')
}
await this.initializeDimension()
return await this.vectorManager.getVaultStatistics(this.embeddingModel)
}
async clearWorkspaceIndex(workspace?: Workspace): Promise<void> {
if (!this.embeddingModel) {
throw new Error('Embedding model is not set')
}
await this.initializeDimension()
if (workspace) {
// 获取工作区中的所有文件路径
const folders: string[] = []
const files: string[] = []
for (const item of workspace.content) {
if (item.type === 'folder') {
const folderPath = item.content
// 获取文件夹下的所有文件
const folderFiles = this.app.vault.getMarkdownFiles().filter(file =>
file.path.startsWith(folderPath === '/' ? '' : folderPath + '/')
)
files.push(...folderFiles.map(file => file.path))
} else if (item.type === 'tag') {
// 获取标签对应的所有文件
const tagFiles = getFilesWithTag(item.content, this.app)
files.push(...tagFiles)
}
}
// 删除工作区相关的向量
if (files.length > 0) {
// 通过 VectorManager 的私有 repository 访问
await this.vectorManager['repository'].deleteVectorsForMultipleFiles(files, this.embeddingModel)
}
} else {
// 清除所有向量
await this.vectorManager['repository'].clearAllVectors(this.embeddingModel)
}
}
}