feat(rag): replace LiteParse flows with LightRAG provider

This commit is contained in:
lix-2026
2026-06-07 01:10:31 +08:00
parent f46c2fb5d0
commit 1f25364374
40 changed files with 7232 additions and 2350 deletions
@@ -421,70 +421,77 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
}
async function runLocalOcrForDetail(detail, trigger) {
var sourceRootRelativePath = localOcrSourceRelativePath(detail);
var rootUri = localOcrRootUri(detail, trigger);
var documentId = String(detail && detail.documentId || currentDocumentId() || '').trim();
if (!sourceRootRelativePath || !rootUri || !documentId) {
throw new Error('缺少 OCR 来源、rootUri 或 owner documentId');
}
if (!isLocalOcrSourceFileName(String(detail && (detail.title || detail.fileName) || sourceRootRelativePath))) {
throw new Error('OCR 仅支持图片和 PDF');
}
var provider = localOcrProvider();
var body = {
rootUri: rootUri,
documentId: documentId,
sourceRootRelativePath: sourceRootRelativePath,
provider: provider
};
if (provider === 'mock') {
body.mockMarkdown = '# OCR Result\n\n' + (detail.title || sourceRootRelativePath) + ' OCR menu smoke text';
}
document.documentElement.setAttribute('data-mnote-local-ocr-menu-status', 'running');
var response = await fetch('/api/local-folder/ocr/jobs', {
var payload = await ingestKnowledgeRagForDetail(detail, trigger).catch(function(error) {
document.documentElement.setAttribute('data-mnote-local-ocr-menu-status', 'failed');
throw error;
});
var sourceRootRelativePath = localOcrSourceRelativePath(detail)
|| String(detail && (detail.localRelativePath || detail.path || detail.title) || '').trim();
var rootUri = localOcrRootUri(detail, trigger);
var status = payload && payload.retryRequired ? 'retry' : 'done';
document.documentElement.setAttribute('data-mnote-local-ocr-menu-status', status);
document.documentElement.setAttribute('data-mnote-local-ocr-menu-path', sourceRootRelativePath);
window.dispatchEvent(new CustomEvent('mnote:local-ocr-job-updated', {
detail: { status: status, job: payload, rootUri: rootUri, sourceRootRelativePath: sourceRootRelativePath }
}));
return payload;
}
async function ingestKnowledgeRagForDetail(detail, trigger) {
var sourceRootRelativePath = localOcrSourceRelativePath(detail)
|| String(detail && (detail.localRelativePath || detail.path || detail.title) || '').trim();
var rootUri = localOcrRootUri(detail, trigger);
if (!sourceRootRelativePath || !rootUri) {
throw new Error('缺少资料库来源或 rootUri');
}
var workspaceId = String(detail && detail.workspaceId || resolveWorkspaceId(document.body) || '').trim();
document.documentElement.setAttribute('data-mnote-knowledge-rag-menu-status', 'running');
document.documentElement.setAttribute('data-mnote-knowledge-rag-menu-path', sourceRootRelativePath);
var response = await fetch('/api/knowledge-rag/ingest', {
method: 'POST',
headers: { 'content-type': 'application/json', accept: 'application/json' },
body: JSON.stringify(body)
body: JSON.stringify({
workspaceId: workspaceId,
rootUri: rootUri,
sources: [{ sourcePath: sourceRootRelativePath }]
})
});
var payload = await response.json().catch(function() { return null; });
if (!response.ok || !payload || payload.ok !== true) {
var message = payload && payload.error && payload.error.message ? payload.error.message : 'OCR 生成失败';
document.documentElement.setAttribute('data-mnote-local-ocr-menu-status', 'failed');
if (!response.ok || !payload || payload.ok === false) {
var message = payload && payload.message ? payload.message : '资料库索引失败';
document.documentElement.setAttribute('data-mnote-knowledge-rag-menu-status', 'failed');
throw new Error(message);
}
var job = payload.job || {};
document.documentElement.setAttribute('data-mnote-local-ocr-menu-status', String(job.status || 'done'));
if (job.ocrRootRelativePath) {
document.documentElement.setAttribute('data-mnote-local-ocr-menu-path', String(job.ocrRootRelativePath));
if (typeof openLocalResourceInActiveTab === 'function') {
await openLocalResourceInActiveTab({
path: String(job.ocrRootRelativePath),
title: String(job.ocrRootRelativePath).split('/').filter(Boolean).pop() || 'OCR',
kind: 'markdown',
assetId: 'local-ocr:' + String(job.ocrRootRelativePath),
documentId: documentId,
workspaceId: String(detail && detail.workspaceId || resolveWorkspaceId(document.body) || '').trim(),
rootUri: rootUri
});
}
}
window.dispatchEvent(new CustomEvent('mnote:local-ocr-job-updated', {
detail: { status: String(job.status || 'done'), job: job, rootUri: rootUri, sourceRootRelativePath: sourceRootRelativePath }
document.documentElement.setAttribute('data-mnote-knowledge-rag-menu-status', payload.retryRequired ? 'retry' : 'done');
window.dispatchEvent(new CustomEvent('mnote:knowledge-rag-source-updated', {
detail: { rootUri: rootUri, workspaceId: workspaceId, sourceRootRelativePath: sourceRootRelativePath, result: payload }
}));
return job;
return payload;
}
function handleTreeContextMenuAction(action, detail, trigger) {
closeTreeContextMenu();
detail = detail || {};
if (action === 'local-ocr') {
recordFileTreeAction('local-ocr', detail);
recordFileTreeAction('knowledge-rag-index', detail);
recordFileTreeActionStatus('pending', detail);
void runLocalOcrForDetail(detail, trigger).then(function(job) {
recordFileTreeActionStatus(String(job && job.status || 'done'), detail);
recordFileTreeActionStatus(job && job.retryRequired ? 'retry' : 'done', detail);
}).catch(function(error) {
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
window.alert(error && error.message ? error.message : 'OCR 生成失败');
window.alert(error && error.message ? error.message : '资料库索引失败');
});
return;
}
if (action === 'knowledge-rag-index') {
recordFileTreeAction('knowledge-rag-index', detail);
recordFileTreeActionStatus('pending', detail);
void ingestKnowledgeRagForDetail(detail, trigger).then(function() {
recordFileTreeActionStatus('done', detail);
}).catch(function(error) {
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
window.alert(error && error.message ? error.message : '资料库索引失败');
});
return;
}
@@ -1010,10 +1017,10 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
{ separator: true },
{ action: 'delete-trash', icon: 'delete', label: '删除', shortcut: 'Del', danger: true, destructive: true, requiresApproval: true, when: '!workspace.readonly && !editor.dirty' }
];
if (localOcrSupported) {
var ocrItem = { action: 'local-ocr', icon: 'auto_awesome', label: '生成 OCR', when: '!workspace.readonly' };
var insertAt = isAttachment ? 11 : isAsset ? 3 : -1;
if (insertAt >= 0) items.splice(insertAt, 0, ocrItem);
if (currentSourceKind() === 'local_folder' && detail.rowKind !== 'index') {
var ragItem = { action: 'knowledge-rag-index', icon: 'travel_explore', label: '加入资料库索引', when: '!workspace.readonly' };
var insertAt = isAttachment ? 11 : isAsset ? 3 : 3;
if (insertAt >= 0) items.splice(insertAt, 0, ragItem);
}
items.forEach(function(item) {
if (item.when !== undefined && !evaluateSidebarFileTreeWhen(ctx, item.when)) {