更新版本至0.7.5,修复洞察模型错误,并在CHANGELOG中记录相关更改。

This commit is contained in:
duanfuxiang 2025-07-18 00:50:18 +08:00
parent 36778565cd
commit 0f04b3c413
4 changed files with 91 additions and 88 deletions

View File

@ -1,4 +1,7 @@
releases: releases:
- version: "0.7.5"
features:
- "fix insight model error"
- version: "0.7.4" - version: "0.7.4"
fixes: fixes:
- "fix moonshot provider cors error" - "fix moonshot provider cors error"

View File

@ -1,7 +1,7 @@
{ {
"id": "infio-copilot", "id": "infio-copilot",
"name": "Infio Copilot", "name": "Infio Copilot",
"version": "0.7.4", "version": "0.7.5",
"minAppVersion": "0.15.0", "minAppVersion": "0.15.0",
"description": "A Cursor-inspired AI assistant for notes that offers smart autocomplete and interactive chat with your selected notes", "description": "A Cursor-inspired AI assistant for notes that offers smart autocomplete and interactive chat with your selected notes",
"author": "Felix.D", "author": "Felix.D",

View File

@ -1,6 +1,6 @@
{ {
"name": "obsidian-infio-copilot", "name": "obsidian-infio-copilot",
"version": "0.7.4", "version": "0.7.5",
"description": "A Cursor-inspired AI assistant that offers smart autocomplete and interactive chat with your selected notes", "description": "A Cursor-inspired AI assistant that offers smart autocomplete and interactive chat with your selected notes",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@ -340,7 +340,7 @@ export class TransEngine {
this.llmManager = new LLMManager(settings); this.llmManager = new LLMManager(settings);
this.insightManager = dbManager.getInsightManager(); this.insightManager = dbManager.getInsightManager();
this.embeddingManager = embeddingManager; this.embeddingManager = embeddingManager;
// 初始化 embedding model // 初始化 embedding model
if (settings.embeddingModelId && settings.embeddingModelId.trim() !== '') { if (settings.embeddingModelId && settings.embeddingModelId.trim() !== '') {
try { try {
@ -362,7 +362,7 @@ export class TransEngine {
setSettings(settings: InfioSettings) { setSettings(settings: InfioSettings) {
this.settings = settings; this.settings = settings;
this.llmManager = new LLMManager(settings); this.llmManager = new LLMManager(settings);
// 重新初始化 embedding model // 重新初始化 embedding model
if (settings.embeddingModelId && settings.embeddingModelId.trim() !== '') { if (settings.embeddingModelId && settings.embeddingModelId.trim() !== '') {
try { try {
@ -442,13 +442,13 @@ export class TransEngine {
try { try {
const existingInsights = await this.insightManager.getInsightsBySourcePath(sourcePath, this.embeddingModel); const existingInsights = await this.insightManager.getInsightsBySourcePath(sourcePath, this.embeddingModel);
console.log("existingInsights", existingInsights); console.log("existingInsights", existingInsights);
// 查找匹配的转换类型和修改时间的洞察 // 查找匹配的转换类型和修改时间的洞察
const matchingInsight = existingInsights.find(insight => const matchingInsight = existingInsights.find(insight =>
insight.insight_type === transformationType.toString() && insight.insight_type === transformationType.toString() &&
insight.source_mtime === sourceMtime insight.source_mtime === sourceMtime
); );
if (matchingInsight) { if (matchingInsight) {
// 找到匹配的缓存结果,直接返回 // 找到匹配的缓存结果,直接返回
console.log(`使用缓存的转换结果: ${transformationType} for ${sourcePath}`); console.log(`使用缓存的转换结果: ${transformationType} for ${sourcePath}`);
@ -615,7 +615,7 @@ export class TransEngine {
case 'folder': { case 'folder': {
sourcePath = filePath; sourcePath = filePath;
// 计算文件夹的真实 mtime基于所有子项目的最大 mtime // 计算文件夹的真实 mtime基于所有子项目的最大 mtime
const folderItems = await this.collectFolderItems(filePath); const folderItems = await this.collectFolderItems(filePath);
let maxMtime = 0; let maxMtime = 0;
@ -679,8 +679,8 @@ export class TransEngine {
// 使用默认模型或传入的模型 // 使用默认模型或传入的模型
const llmModel: LLMModel = model || { const llmModel: LLMModel = model || {
provider: this.settings.applyModelProvider, provider: this.settings.insightModelProvider,
modelId: this.settings.applyModelId, modelId: this.settings.insightModelId,
}; };
// 创建 LLM 客户端 // 创建 LLM 客户端
@ -783,7 +783,7 @@ export class TransEngine {
if (directFiles.length > 0) { if (directFiles.length > 0) {
content += `## File Content Summaries\n\n`; content += `## File Content Summaries\n\n`;
const fileSummaries: string[] = []; const fileSummaries: string[] = [];
for (const file of directFiles) { for (const file of directFiles) {
const fileResult = await this.runTransformation({ const fileResult = await this.runTransformation({
filePath: file.path, filePath: file.path,
@ -800,7 +800,7 @@ export class TransEngine {
} }
content += fileSummaries.join('\n\n'); content += fileSummaries.join('\n\n');
if (directSubfolders.length > 0) { if (directSubfolders.length > 0) {
content += '\n\n'; content += '\n\n';
} }
@ -937,7 +937,7 @@ export class TransEngine {
try { try {
// 生成查询向量 // 生成查询向量
const queryVector = await this.embeddingModel.getEmbedding(query) const queryVector = await this.embeddingModel.getEmbedding(query)
// 构建 sourcePaths 过滤条件 // 构建 sourcePaths 过滤条件
let sourcePaths: string[] | undefined let sourcePaths: string[] | undefined
if (scope) { if (scope) {
@ -952,7 +952,7 @@ export class TransEngine {
const folder = this.app.vault.getAbstractFileByPath(normalizePath(folderPath)) const folder = this.app.vault.getAbstractFileByPath(normalizePath(folderPath))
if (folder && folder instanceof TFolder) { if (folder && folder instanceof TFolder) {
// 获取文件夹下的所有 Markdown 文件 // 获取文件夹下的所有 Markdown 文件
const folderFiles = this.app.vault.getMarkdownFiles().filter(file => const folderFiles = this.app.vault.getMarkdownFiles().filter(file =>
file.path.startsWith(folderPath + '/') file.path.startsWith(folderPath + '/')
) )
sourcePaths.push(...folderFiles.map(f => f.path)) sourcePaths.push(...folderFiles.map(f => f.path))
@ -1065,7 +1065,7 @@ export class TransEngine {
// 并行处理直接子文件 // 并行处理直接子文件
if (directFiles.length > 0) { if (directFiles.length > 0) {
const filePromises = directFiles.map(file => const filePromises = directFiles.map(file =>
concurrencyLimiter.execute(async () => { concurrencyLimiter.execute(async () => {
if (signal?.aborted) { if (signal?.aborted) {
throw new Error('Operation was aborted') throw new Error('Operation was aborted')
@ -1087,7 +1087,7 @@ export class TransEngine {
// 并行处理直接子文件夹 // 并行处理直接子文件夹
if (directSubfolders.length > 0) { if (directSubfolders.length > 0) {
const folderPromises = directSubfolders.map(subfolder => const folderPromises = directSubfolders.map(subfolder =>
concurrencyLimiter.execute(async () => { concurrencyLimiter.execute(async () => {
if (signal?.aborted) { if (signal?.aborted) {
throw new Error('Operation was aborted') throw new Error('Operation was aborted')
@ -1225,8 +1225,8 @@ export class TransEngine {
* *
*/ */
private async generateHierarchicalSummary( private async generateHierarchicalSummary(
combinedContent: string, combinedContent: string,
contextLabel: string, contextLabel: string,
llmModel: LLMModel llmModel: LLMModel
): Promise<string> { ): Promise<string> {
const client = new TransformationLLMClient(this.llmManager, llmModel) const client = new TransformationLLMClient(this.llmManager, llmModel)
@ -1313,7 +1313,7 @@ export class TransEngine {
if (workspace) { if (workspace) {
workspaceName = workspace.name workspaceName = workspace.name
// 添加工作区本身的洞察路径 // 添加工作区本身的洞察路径
sourcePaths.push(`workspace:${workspaceName}`) sourcePaths.push(`workspace:${workspaceName}`)
@ -1321,15 +1321,15 @@ export class TransEngine {
for (const contentItem of workspace.content) { for (const contentItem of workspace.content) {
if (contentItem.type === 'folder') { if (contentItem.type === 'folder') {
const folderPath = contentItem.content const folderPath = contentItem.content
// 添加文件夹路径本身 // 添加文件夹路径本身
sourcePaths.push(folderPath) sourcePaths.push(folderPath)
// 获取文件夹下的所有文件 // 获取文件夹下的所有文件
const files = this.app.vault.getMarkdownFiles().filter(file => const files = this.app.vault.getMarkdownFiles().filter(file =>
file.path.startsWith(folderPath === '/' ? '' : folderPath + '/') file.path.startsWith(folderPath === '/' ? '' : folderPath + '/')
) )
// 添加所有文件路径 // 添加所有文件路径
files.forEach(file => { files.forEach(file => {
sourcePaths.push(file.path) sourcePaths.push(file.path)
@ -1341,7 +1341,7 @@ export class TransEngine {
if (dirPath && dirPath !== folderPath) { if (dirPath && dirPath !== folderPath) {
let currentPath = folderPath === '/' ? '' : folderPath let currentPath = folderPath === '/' ? '' : folderPath
const pathParts = dirPath.substring(currentPath.length).split('/').filter(Boolean) const pathParts = dirPath.substring(currentPath.length).split('/').filter(Boolean)
for (let i = 0; i < pathParts.length; i++) { for (let i = 0; i < pathParts.length; i++) {
currentPath += (currentPath ? '/' : '') + pathParts[i] currentPath += (currentPath ? '/' : '') + pathParts[i]
if (!sourcePaths.includes(currentPath)) { if (!sourcePaths.includes(currentPath)) {
@ -1354,16 +1354,16 @@ export class TransEngine {
} else if (contentItem.type === 'tag') { } else if (contentItem.type === 'tag') {
// 获取标签对应的所有文件 // 获取标签对应的所有文件
const tagFiles = this.getFilesByTag(contentItem.content) const tagFiles = this.getFilesByTag(contentItem.content)
tagFiles.forEach(file => { tagFiles.forEach(file => {
sourcePaths.push(file.path) sourcePaths.push(file.path)
// 添加文件所在的文件夹路径 // 添加文件所在的文件夹路径
const dirPath = file.path.substring(0, file.path.lastIndexOf('/')) const dirPath = file.path.substring(0, file.path.lastIndexOf('/'))
if (dirPath) { if (dirPath) {
const pathParts = dirPath.split('/').filter(Boolean) const pathParts = dirPath.split('/').filter(Boolean)
let currentPath = '' let currentPath = ''
for (let i = 0; i < pathParts.length; i++) { for (let i = 0; i < pathParts.length; i++) {
currentPath += (currentPath ? '/' : '') + pathParts[i] currentPath += (currentPath ? '/' : '') + pathParts[i]
if (!sourcePaths.includes(currentPath)) { if (!sourcePaths.includes(currentPath)) {
@ -1378,15 +1378,15 @@ export class TransEngine {
// 处理默认 vault 工作区 - 删除所有洞察 // 处理默认 vault 工作区 - 删除所有洞察
workspaceName = 'vault' workspaceName = 'vault'
sourcePaths.push(`workspace:${workspaceName}`) sourcePaths.push(`workspace:${workspaceName}`)
// 获取所有洞察来确定删除数量 // 获取所有洞察来确定删除数量
const allInsights = await this.insightManager.getAllInsights(this.embeddingModel) const allInsights = await this.insightManager.getAllInsights(this.embeddingModel)
// 对于 vault 工作区,删除所有洞察 // 对于 vault 工作区,删除所有洞察
await this.insightManager.clearAllInsights(this.embeddingModel) await this.insightManager.clearAllInsights(this.embeddingModel)
console.log(`已删除 vault 工作区的所有 ${allInsights.length} 个转换`) console.log(`已删除 vault 工作区的所有 ${allInsights.length} 个转换`)
return { return {
success: true, success: true,
deletedCount: allInsights.length deletedCount: allInsights.length
@ -1395,10 +1395,10 @@ export class TransEngine {
// 去重路径 // 去重路径
const uniquePaths = [...new Set(sourcePaths)] const uniquePaths = [...new Set(sourcePaths)]
// 获取将要删除的洞察数量 // 获取将要删除的洞察数量
const existingInsights = await this.insightManager.getAllInsights(this.embeddingModel) const existingInsights = await this.insightManager.getAllInsights(this.embeddingModel)
const insightsToDelete = existingInsights.filter(insight => const insightsToDelete = existingInsights.filter(insight =>
uniquePaths.includes(insight.source_path) uniquePaths.includes(insight.source_path)
) )
const deletedCount = insightsToDelete.length const deletedCount = insightsToDelete.length
@ -1446,10 +1446,10 @@ export class TransEngine {
try { try {
// 删除工作区本身的洞察 // 删除工作区本身的洞察
const workspaceInsightPath = `workspace:${workspaceName}` const workspaceInsightPath = `workspace:${workspaceName}`
// 获取所有洞察并筛选出该工作区相关的 // 获取所有洞察并筛选出该工作区相关的
const allInsights = await this.insightManager.getAllInsights(this.embeddingModel) const allInsights = await this.insightManager.getAllInsights(this.embeddingModel)
const workspaceInsights = allInsights.filter(insight => const workspaceInsights = allInsights.filter(insight =>
insight.source_path === workspaceInsightPath insight.source_path === workspaceInsightPath
) )
@ -1493,7 +1493,7 @@ export class TransEngine {
try { try {
// 直接按ID删除洞察 // 直接按ID删除洞察
await this.insightManager.deleteInsightById(insightId, this.embeddingModel) await this.insightManager.deleteInsightById(insightId, this.embeddingModel)
console.log(`已删除洞察 ID: ${insightId}`) console.log(`已删除洞察 ID: ${insightId}`)
return { return {
@ -1514,12 +1514,12 @@ export class TransEngine {
*/ */
async initWorkspaceInsight(params: InitWorkspaceInsightParams): Promise<InitWorkspaceInsightResult> { async initWorkspaceInsight(params: InitWorkspaceInsightParams): Promise<InitWorkspaceInsightResult> {
const { workspace, model, onProgress } = params; const { workspace, model, onProgress } = params;
// 统计信息 // 统计信息
let processedFiles = 0; let processedFiles = 0;
let processedFolders = 0; let processedFolders = 0;
let skippedItems = 0; let skippedItems = 0;
try { try {
// 1. 深度分析工作区内容,统计所有需要处理的项目 // 1. 深度分析工作区内容,统计所有需要处理的项目
onProgress?.({ onProgress?.({
@ -1529,7 +1529,7 @@ export class TransEngine {
currentItem: '深度扫描文件和文件夹...', currentItem: '深度扫描文件和文件夹...',
percentage: 0 percentage: 0
}); });
// 收集所有需要处理的项目(深度递归) // 收集所有需要处理的项目(深度递归)
const allItems: Array<{ const allItems: Array<{
type: 'file' | 'folder'; type: 'file' | 'folder';
@ -1537,32 +1537,32 @@ export class TransEngine {
name: string; name: string;
mtime: number; mtime: number;
}> = []; }> = [];
// 收集工作区顶层配置的项目(仅用于最终摘要) // 收集工作区顶层配置的项目(仅用于最终摘要)
const topLevelFiles: Array<{ const topLevelFiles: Array<{
path: string; path: string;
name: string; name: string;
}> = []; }> = [];
const topLevelFolders: Array<{ const topLevelFolders: Array<{
path: string; path: string;
name: string; name: string;
}> = []; }> = [];
// 解析 workspace 的 content 配置 // 解析 workspace 的 content 配置
const seenPaths = new Set<string>(); const seenPaths = new Set<string>();
for (const contentItem of workspace.content) { for (const contentItem of workspace.content) {
if (contentItem.type === 'folder') { if (contentItem.type === 'folder') {
const folderPath = contentItem.content; const folderPath = contentItem.content;
const folderName = folderPath.split('/').pop() || folderPath; const folderName = folderPath.split('/').pop() || folderPath;
// 收集顶层文件夹(用于最终摘要) // 收集顶层文件夹(用于最终摘要)
topLevelFolders.push({ topLevelFolders.push({
path: folderPath, path: folderPath,
name: folderName name: folderName
}); });
// 深度遍历收集所有项目(用于进度统计和处理) // 深度遍历收集所有项目(用于进度统计和处理)
const items = await this.collectFolderItems(folderPath); const items = await this.collectFolderItems(folderPath);
for (const item of items) { for (const item of items) {
@ -1604,12 +1604,12 @@ export class TransEngine {
skippedItems: 0 skippedItems: 0
}; };
} }
// 分离文件和文件夹 // 分离文件和文件夹
const files = allItems.filter(item => item.type === 'file'); const files = allItems.filter(item => item.type === 'file');
const folders = allItems.filter(item => item.type === 'folder'); const folders = allItems.filter(item => item.type === 'folder');
const totalItems = allItems.length; const totalItems = allItems.length;
onProgress?.({ onProgress?.({
stage: '分析完成', stage: '分析完成',
current: 1, current: 1,
@ -1617,15 +1617,15 @@ export class TransEngine {
currentItem: `深度扫描完成:${files.length} 个文件,${folders.length} 个文件夹`, currentItem: `深度扫描完成:${files.length} 个文件,${folders.length} 个文件夹`,
percentage: 5 percentage: 5
}); });
// 用于收集顶层摘要(仅用于工作区摘要) // 用于收集顶层摘要(仅用于工作区摘要)
const topLevelSummaries: string[] = []; const topLevelSummaries: string[] = [];
let currentProgress = 0; let currentProgress = 0;
// 2. 处理所有文件(深度递归的结果) // 2. 处理所有文件(深度递归的结果)
for (const file of files) { for (const file of files) {
currentProgress++; currentProgress++;
onProgress?.({ onProgress?.({
stage: '处理文件', stage: '处理文件',
current: currentProgress, current: currentProgress,
@ -1633,7 +1633,7 @@ export class TransEngine {
currentItem: `📄 ${file.name}`, currentItem: `📄 ${file.name}`,
percentage: Math.round((currentProgress / totalItems) * 90) + 5 // 5-95% percentage: Math.round((currentProgress / totalItems) * 90) + 5 // 5-95%
}); });
try { try {
const fileResult = await this.runTransformation({ const fileResult = await this.runTransformation({
filePath: file.path, filePath: file.path,
@ -1642,7 +1642,7 @@ export class TransEngine {
model: model, model: model,
saveToDatabase: true saveToDatabase: true
}); });
if (fileResult.success && fileResult.result) { if (fileResult.success && fileResult.result) {
// 检查是否是顶层文件(标签文件),如果是则添加到顶层摘要 // 检查是否是顶层文件(标签文件),如果是则添加到顶层摘要
const isTopLevelFile = topLevelFiles.some(f => f.path === file.path); const isTopLevelFile = topLevelFiles.some(f => f.path === file.path);
@ -1667,17 +1667,17 @@ export class TransEngine {
skippedItems++; skippedItems++;
} }
} }
// 3. 处理所有文件夹(深度递归的结果,从最深层开始) // 3. 处理所有文件夹(深度递归的结果,从最深层开始)
const sortedFolders = folders.sort((a, b) => { const sortedFolders = folders.sort((a, b) => {
const depthA = a.path.split('/').length; const depthA = a.path.split('/').length;
const depthB = b.path.split('/').length; const depthB = b.path.split('/').length;
return depthB - depthA; // 深度大的先处理 return depthB - depthA; // 深度大的先处理
}); });
for (const folder of sortedFolders) { for (const folder of sortedFolders) {
currentProgress++; currentProgress++;
onProgress?.({ onProgress?.({
stage: '处理文件夹', stage: '处理文件夹',
current: currentProgress, current: currentProgress,
@ -1685,7 +1685,7 @@ export class TransEngine {
currentItem: `📂 ${folder.name}`, currentItem: `📂 ${folder.name}`,
percentage: Math.round((currentProgress / totalItems) * 90) + 5 // 5-95% percentage: Math.round((currentProgress / totalItems) * 90) + 5 // 5-95%
}); });
try { try {
const folderResult = await this.runTransformation({ const folderResult = await this.runTransformation({
filePath: folder.path, filePath: folder.path,
@ -1694,7 +1694,7 @@ export class TransEngine {
model: model, model: model,
saveToDatabase: true saveToDatabase: true
}); });
if (folderResult.success && folderResult.result) { if (folderResult.success && folderResult.result) {
// 检查是否是顶层文件夹,如果是则添加到顶层摘要 // 检查是否是顶层文件夹,如果是则添加到顶层摘要
const isTopLevelFolder = topLevelFolders.some(f => f.path === folder.path); const isTopLevelFolder = topLevelFolders.some(f => f.path === folder.path);
@ -1719,7 +1719,7 @@ export class TransEngine {
skippedItems++; skippedItems++;
} }
} }
// 4. 生成工作区整体洞察 // 4. 生成工作区整体洞察
onProgress?.({ onProgress?.({
stage: '生成工作区洞察', stage: '生成工作区洞察',
@ -1728,7 +1728,7 @@ export class TransEngine {
currentItem: '汇总分析工作区内容...', currentItem: '汇总分析工作区内容...',
percentage: 95 percentage: 95
}); });
// 构建工作区内容描述 // 构建工作区内容描述
let workspaceContent = `# Workspace: ${workspace.name}\n\n`; let workspaceContent = `# Workspace: ${workspace.name}\n\n`;
@ -1738,10 +1738,10 @@ export class TransEngine {
} else { } else {
workspaceContent += '*No top-level content summaries available.*'; workspaceContent += '*No top-level content summaries available.*';
} }
// 5. 生成工作区的整体洞察 // 5. 生成工作区的整体洞察
const sourcePath = `workspace:${workspace.name}`; const sourcePath = `workspace:${workspace.name}`;
// 计算所有项目的最大 mtime // 计算所有项目的最大 mtime
let maxMtime = 0; let maxMtime = 0;
for (const item of allItems) { for (const item of allItems) {
@ -1750,10 +1750,10 @@ export class TransEngine {
} }
} }
console.log('maxMtime', maxMtime); console.log('maxMtime', maxMtime);
// 如果没有找到任何有效的 mtime使用当前时间 // 如果没有找到任何有效的 mtime使用当前时间
const sourceMtime = maxMtime > 0 ? maxMtime : 0; const sourceMtime = maxMtime > 0 ? maxMtime : 0;
// 验证内容 // 验证内容
const contentValidation = DocumentProcessor.validateContent(workspaceContent); const contentValidation = DocumentProcessor.validateContent(workspaceContent);
if (contentValidation.isErr()) { if (contentValidation.isErr()) {
@ -1766,21 +1766,21 @@ export class TransEngine {
skippedItems skippedItems
}; };
} }
// 处理文档内容(检查 token 数量并截断) // 处理文档内容(检查 token 数量并截断)
const processedDocument = await DocumentProcessor.processContent(workspaceContent); const processedDocument = await DocumentProcessor.processContent(workspaceContent);
// 查询数据库中是否存在工作区洞察 // 查询数据库中是否存在工作区洞察
const cacheCheckResult = await this.checkDatabaseCache( const cacheCheckResult = await this.checkDatabaseCache(
sourcePath, sourcePath,
sourceMtime, sourceMtime,
TransformationType.HIERARCHICAL_SUMMARY TransformationType.HIERARCHICAL_SUMMARY
); );
if (cacheCheckResult.foundCache && cacheCheckResult.result.success) { if (cacheCheckResult.foundCache && cacheCheckResult.result.success) {
// 找到缓存的工作区洞察,直接返回 // 找到缓存的工作区洞察,直接返回
console.log(`使用缓存的工作区洞察: ${workspace.name}`); console.log(`使用缓存的工作区洞察: ${workspace.name}`);
onProgress?.({ onProgress?.({
stage: '使用缓存洞察', stage: '使用缓存洞察',
current: 1, current: 1,
@ -1788,18 +1788,18 @@ export class TransEngine {
currentItem: '已找到缓存的工作区洞察', currentItem: '已找到缓存的工作区洞察',
percentage: 100 percentage: 100
}); });
// 尝试获取洞察ID // 尝试获取洞察ID
let insightId: number | undefined; let insightId: number | undefined;
if (this.insightManager) { if (this.insightManager) {
const recentInsights = await this.insightManager.getInsightsBySourcePath(sourcePath, this.embeddingModel); const recentInsights = await this.insightManager.getInsightsBySourcePath(sourcePath, this.embeddingModel);
const latestInsight = recentInsights.find(insight => const latestInsight = recentInsights.find(insight =>
insight.insight_type === TransformationType.HIERARCHICAL_SUMMARY.toString() && insight.insight_type === TransformationType.HIERARCHICAL_SUMMARY.toString() &&
insight.source_mtime === sourceMtime insight.source_mtime === sourceMtime
); );
insightId = latestInsight?.id; insightId = latestInsight?.id;
} }
return { return {
success: true, success: true,
processedFiles, processedFiles,
@ -1812,13 +1812,13 @@ export class TransEngine {
// 使用默认模型或传入的模型 // 使用默认模型或传入的模型
const llmModel: LLMModel = model || { const llmModel: LLMModel = model || {
provider: this.settings.applyModelProvider, provider: this.settings.insightModelProvider,
modelId: this.settings.applyModelId, modelId: this.settings.insightModelId,
}; };
// 创建 LLM 客户端 // 创建 LLM 客户端
const client = new TransformationLLMClient(this.llmManager, llmModel); const client = new TransformationLLMClient(this.llmManager, llmModel);
// 构建请求消息 // 构建请求消息
const transformationConfig = TRANSFORMATIONS[TransformationType.HIERARCHICAL_SUMMARY]; const transformationConfig = TRANSFORMATIONS[TransformationType.HIERARCHICAL_SUMMARY];
const messages: RequestMessage[] = [ const messages: RequestMessage[] = [
@ -1831,10 +1831,10 @@ export class TransEngine {
content: processedDocument.processedContent content: processedDocument.processedContent
} }
]; ];
// 调用 LLM 执行转换 // 调用 LLM 执行转换
const result = await client.queryChatModel(messages); const result = await client.queryChatModel(messages);
if (result.isErr()) { if (result.isErr()) {
return { return {
success: false, success: false,
@ -1845,10 +1845,10 @@ export class TransEngine {
skippedItems skippedItems
}; };
} }
// 后处理结果 // 后处理结果
const processedResult = this.postProcessResult(result.value, TransformationType.HIERARCHICAL_SUMMARY); const processedResult = this.postProcessResult(result.value, TransformationType.HIERARCHICAL_SUMMARY);
// 6. 保存工作区洞察到数据库 // 6. 保存工作区洞察到数据库
onProgress?.({ onProgress?.({
stage: '保存洞察结果', stage: '保存洞察结果',
@ -1857,9 +1857,9 @@ export class TransEngine {
currentItem: '保存到数据库...', currentItem: '保存到数据库...',
percentage: 98 percentage: 98
}); });
let insightId: number | undefined; let insightId: number | undefined;
try { try {
await this.saveResultToDatabase( await this.saveResultToDatabase(
processedResult, processedResult,
@ -1868,12 +1868,12 @@ export class TransEngine {
sourceMtime, sourceMtime,
'folder' // workspace 在数据库中存储为 folder 类型 'folder' // workspace 在数据库中存储为 folder 类型
); );
// 尝试获取刚保存的洞察ID可选 // 尝试获取刚保存的洞察ID可选
if (this.insightManager) { if (this.insightManager) {
const recentInsights = await this.insightManager.getInsightsBySourcePath(sourcePath, this.embeddingModel); const recentInsights = await this.insightManager.getInsightsBySourcePath(sourcePath, this.embeddingModel);
const latestInsight = recentInsights.find(insight => const latestInsight = recentInsights.find(insight =>
insight.insight_type === TransformationType.HIERARCHICAL_SUMMARY.toString() && insight.insight_type === TransformationType.HIERARCHICAL_SUMMARY.toString() &&
insight.source_mtime === sourceMtime insight.source_mtime === sourceMtime
); );
insightId = latestInsight?.id; insightId = latestInsight?.id;
@ -1882,7 +1882,7 @@ export class TransEngine {
console.warn('保存洞察到数据库失败:', error); console.warn('保存洞察到数据库失败:', error);
// 不影响主流程,仅记录警告 // 不影响主流程,仅记录警告
} }
// 7. 完成 // 7. 完成
onProgress?.({ onProgress?.({
stage: '完成', stage: '完成',
@ -1891,7 +1891,7 @@ export class TransEngine {
currentItem: '工作区洞察初始化完成', currentItem: '工作区洞察初始化完成',
percentage: 100 percentage: 100
}); });
return { return {
success: true, success: true,
processedFiles, processedFiles,
@ -1900,7 +1900,7 @@ export class TransEngine {
skippedItems, skippedItems,
insightId insightId
}; };
} catch (error) { } catch (error) {
return { return {
success: false, success: false,
@ -1955,7 +1955,7 @@ export class TransEngine {
// 收集直接子文件夹 // 收集直接子文件夹
const subfolders = folder.children.filter((child): child is TFolder => child instanceof TFolder); const subfolders = folder.children.filter((child): child is TFolder => child instanceof TFolder);
// 递归处理子文件夹 // 递归处理子文件夹
for (const subfolder of subfolders) { for (const subfolder of subfolders) {
// 递归收集子文件夹中的内容(包含子文件夹本身) // 递归收集子文件夹中的内容(包含子文件夹本身)
@ -1970,7 +1970,7 @@ export class TransEngine {
maxMtime = item.mtime; maxMtime = item.mtime;
} }
} }
items.push({ items.push({
type: 'folder', type: 'folder',
path: folderPath, path: folderPath,