mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-01-16 08:21:55 +00:00
更新版本至0.7.5,修复洞察模型错误,并在CHANGELOG中记录相关更改。
This commit is contained in:
parent
36778565cd
commit
0f04b3c413
@ -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"
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user