feat(rag): replace LiteParse flows with LightRAG provider
This commit is contained in:
@@ -1373,17 +1373,17 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const statusNode = entry.panel.querySelector('[data-mnote-local-ocr-status-text]');
|
||||
if (statusNode instanceof HTMLElement) {
|
||||
statusNode.textContent = message || (
|
||||
normalizedStatus === 'done' ? 'OCR 已完成'
|
||||
: normalizedStatus === 'running' ? 'OCR 处理中'
|
||||
: normalizedStatus === 'failed' ? 'OCR 失败'
|
||||
: normalizedStatus === 'stale' ? 'OCR 需更新'
|
||||
: 'OCR 未生成'
|
||||
normalizedStatus === 'done' ? '资料库已索引'
|
||||
: normalizedStatus === 'running' ? '资料库索引中'
|
||||
: normalizedStatus === 'failed' ? '资料库索引失败'
|
||||
: normalizedStatus === 'stale' ? '资料库需更新'
|
||||
: '资料库未索引'
|
||||
);
|
||||
}
|
||||
const openButton = entry.panel.querySelector('[data-mnote-local-ocr-action="open"]');
|
||||
if (openButton instanceof HTMLButtonElement) openButton.disabled = !entry.localOcrJob?.ocrRootRelativePath;
|
||||
if (openButton instanceof HTMLButtonElement) openButton.disabled = true;
|
||||
const insertButton = entry.panel.querySelector('[data-mnote-local-ocr-action="insert"]');
|
||||
if (insertButton instanceof HTMLButtonElement) insertButton.disabled = !entry.localOcrJob?.ocrRootRelativePath;
|
||||
if (insertButton instanceof HTMLButtonElement) insertButton.disabled = true;
|
||||
window.dispatchEvent(new CustomEvent('mnote:local-ocr-job-updated', {
|
||||
detail: {
|
||||
status: normalizedStatus,
|
||||
@@ -1394,15 +1394,50 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
}));
|
||||
};
|
||||
|
||||
const knowledgeRagJobFromRegistryEntry = (registryEntry, rootUri) => {
|
||||
if (!registryEntry || typeof registryEntry !== 'object') return null;
|
||||
const sourceRootRelativePath = String(registryEntry.sourceRootRelativePath || registryEntry.source_path || '').trim();
|
||||
if (!sourceRootRelativePath) return null;
|
||||
const indexed = Boolean(registryEntry.indexedAtMs || registryEntry.indexed_at_ms) && Boolean(registryEntry.lightRagDocId || registryEntry.light_rag_doc_id);
|
||||
const failed = registryEntry.deletedAtMs != null || registryEntry.deleted_at_ms != null || registryEntry.stale === true;
|
||||
const status = failed ? 'failed' : indexed ? 'done' : 'running';
|
||||
return {
|
||||
taskKind: 'knowledge_rag',
|
||||
jobId: String(registryEntry.sourceId || registryEntry.source_id || `knowledge-rag:${sourceRootRelativePath}`),
|
||||
sourceRootRelativePath,
|
||||
rootUri: String(registryEntry.rootUri || rootUri || '').trim(),
|
||||
ocrRootRelativePath: '',
|
||||
provider: 'lightrag',
|
||||
status,
|
||||
stageLabel: status === 'done' ? '资料库已索引' : status === 'failed' ? '资料库需重建' : '资料库索引中',
|
||||
stale: registryEntry.stale === true,
|
||||
updatedAtMs: Number(registryEntry.updatedAtMs || registryEntry.updated_at_ms || Date.now()),
|
||||
finishedAtMs: status === 'done' ? Number(registryEntry.indexedAtMs || registryEntry.indexed_at_ms || Date.now()) : null,
|
||||
error: status === 'failed' ? 'knowledge_rag_source_stale_or_deleted' : '',
|
||||
lightRagDocId: String(registryEntry.lightRagDocId || registryEntry.light_rag_doc_id || ''),
|
||||
lightRagFilePath: String(registryEntry.lightRagFilePath || registryEntry.light_rag_file_path || ''),
|
||||
};
|
||||
};
|
||||
|
||||
const knowledgeRagRegistryEntries = (payload) => {
|
||||
const registry = payload && payload.registry && typeof payload.registry === 'object' ? payload.registry : null;
|
||||
return Array.isArray(registry?.entries) ? registry.entries : [];
|
||||
};
|
||||
|
||||
const readLocalOcrStatus = async (entry) => {
|
||||
if (!isLocalOcrSourceEntry(entry)) return null;
|
||||
const url = new URL('/api/local-folder/ocr/status', window.location.origin);
|
||||
const url = new URL('/api/knowledge-rag/status', window.location.origin);
|
||||
url.searchParams.set('rootUri', entry.rootUri);
|
||||
url.searchParams.set('sourceRootRelativePath', entry.path);
|
||||
const workspaceId = String(entry.workspaceId || currentWebShellWorkspaceId() || '').trim();
|
||||
if (workspaceId) url.searchParams.set('workspaceId', workspaceId);
|
||||
const response = await fetch(url.toString(), { cache: 'no-store', headers: { accept: 'application/json' } });
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok || !payload || payload.ok !== true) return null;
|
||||
return payload.job || null;
|
||||
const targetPath = String(entry.path || '').trim().replace(/\\/g, '/').replace(/^\/+/, '');
|
||||
const registryEntry = knowledgeRagRegistryEntries(payload).find((candidate) => {
|
||||
return String(candidate?.sourceRootRelativePath || '').trim().replace(/\\/g, '/').replace(/^\/+/, '') === targetPath;
|
||||
});
|
||||
return knowledgeRagJobFromRegistryEntry(registryEntry, entry.rootUri);
|
||||
};
|
||||
|
||||
const localOcrTaskState = {
|
||||
@@ -1475,7 +1510,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
toggle.addEventListener('click', (event) => {
|
||||
if (toggle.getAttribute('data-mnote-action') === 'open-ocr-settings') {
|
||||
event.preventDefault();
|
||||
window.dispatchEvent(new CustomEvent('mnote:open-local-ocr-settings'));
|
||||
window.dispatchEvent(new CustomEvent('mnote:open-knowledge-rag-settings'));
|
||||
return;
|
||||
}
|
||||
void runManualLocalOcrForActiveTarget(toggle).catch((error) => {
|
||||
@@ -1506,7 +1541,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const statusTextForLocalOcrJob = (job) => {
|
||||
const status = String(job?.status || '').trim();
|
||||
if (job?.stageLabel) return String(job.stageLabel);
|
||||
if (job?.taskKind === 'local_index') {
|
||||
if (job?.taskKind === 'local_index' || job?.taskKind === 'knowledge_rag') {
|
||||
return status === 'done' ? '索引已完成'
|
||||
: status === 'failed' ? '索引失败'
|
||||
: status === 'running' ? '索引中'
|
||||
@@ -1557,20 +1592,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
document.body.appendChild(dock);
|
||||
}
|
||||
let toggle = document.querySelector('[data-testid="mnote-local-ocr-task-toggle"]');
|
||||
if (!(toggle instanceof HTMLButtonElement)) {
|
||||
const actions = document.querySelector('.wolai-topbar-actions');
|
||||
toggle = document.createElement('button');
|
||||
toggle.type = 'button';
|
||||
toggle.className = 'wolai-icon-button mnote-local-ocr-task-toggle';
|
||||
toggle.setAttribute('title', 'OCR 设置');
|
||||
toggle.setAttribute('aria-label', 'OCR 设置');
|
||||
toggle.setAttribute('data-testid', 'mnote-local-ocr-task-toggle');
|
||||
toggle.setAttribute('data-mnote-action', 'open-ocr-settings');
|
||||
toggle.innerHTML = '<span class="material-symbols-outlined" data-icon="document_scanner" aria-hidden="true"></span><span class="mnote-local-ocr-task-badge" data-mnote-local-ocr-task-count hidden>0</span>';
|
||||
if (actions instanceof HTMLElement) actions.appendChild(toggle);
|
||||
else document.body.appendChild(toggle);
|
||||
}
|
||||
bindLocalOcrTopbarAction();
|
||||
if (toggle instanceof HTMLButtonElement) bindLocalOcrTopbarAction();
|
||||
if (dock.getAttribute('data-mnote-local-ocr-bound') === 'true') return dock;
|
||||
dock.setAttribute('data-mnote-local-ocr-bound', 'true');
|
||||
dock.addEventListener('click', (event) => {
|
||||
@@ -1617,23 +1639,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
}
|
||||
const openButton = event.target instanceof Element ? event.target.closest('[data-mnote-local-ocr-task-open]') : null;
|
||||
if (openButton instanceof HTMLElement) {
|
||||
const sourcePath = openButton.getAttribute('data-mnote-local-ocr-task-open') || '';
|
||||
const job = localOcrTaskState.jobsBySource.get(sourcePath) || null;
|
||||
if (job) {
|
||||
void openResourceInActiveTab({
|
||||
kind: 'markdown',
|
||||
title: String(job.ocrRootRelativePath || '').split('/').filter(Boolean).pop() || 'OCR',
|
||||
path: job.ocrRootRelativePath,
|
||||
objectIdentity: `local-ocr:${job.ocrRootRelativePath}`,
|
||||
assetId: `local-ocr:${job.ocrRootRelativePath}`,
|
||||
documentId: job.ownerDocumentId || currentWebShellDocumentId() || '',
|
||||
ownerDocumentId: job.ownerDocumentId || currentWebShellDocumentId() || '',
|
||||
workspaceId: currentWebShellWorkspaceId() || '',
|
||||
sourceKind: 'local_folder',
|
||||
rootUri: localOcrTaskState.rootUri || '',
|
||||
resourceKind: 'markdown',
|
||||
}).catch((error) => console.warn('mnote local OCR 任务打开失败', error));
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent('mnote:open-knowledge-rag-settings'));
|
||||
}
|
||||
const retryButton = event.target instanceof Element ? event.target.closest('[data-mnote-local-ocr-task-retry]') : null;
|
||||
if (retryButton instanceof HTMLElement) {
|
||||
@@ -1670,7 +1676,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
.filter((node) => node instanceof HTMLButtonElement);
|
||||
taskToggles.forEach((toggle) => {
|
||||
const opensSettings = toggle.getAttribute('data-mnote-action') === 'open-ocr-settings';
|
||||
const label = runningCount > 0 ? `${runningCount} 个 OCR 处理中,打开 OCR 设置` : (jobs.length > 0 ? `${jobs.length} 个 OCR 任务,打开 OCR 设置` : 'OCR 设置');
|
||||
const label = runningCount > 0 ? `${runningCount} 个资料库索引处理中,打开资料库设置` : (jobs.length > 0 ? `${jobs.length} 个资料库任务,打开资料库设置` : '资料库设置');
|
||||
const taskLabel = runningCount > 0 ? `${runningCount} 个后台任务正在运行` : (jobs.length > 0 ? `${jobs.length} 个后台任务` : '后台任务');
|
||||
toggle.setAttribute('title', opensSettings ? label : taskLabel);
|
||||
toggle.setAttribute('aria-label', opensSettings ? label : taskLabel);
|
||||
@@ -1681,7 +1687,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
badge.textContent = String(runningCount > 0 ? runningCount : jobs.length);
|
||||
badge.hidden = jobs.length === 0;
|
||||
} else {
|
||||
toggle.textContent = runningCount > 0 ? `OCR ${runningCount} 处理中` : `OCR ${jobs.length}`;
|
||||
toggle.textContent = runningCount > 0 ? `索引 ${runningCount} 处理中` : `索引 ${jobs.length}`;
|
||||
}
|
||||
});
|
||||
const drawer = dock.querySelector('[data-testid="mnote-local-ocr-task-drawer"]');
|
||||
@@ -1731,7 +1737,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
row.setAttribute('data-mnote-local-ocr-task-row', String(job.sourceRootRelativePath || ''));
|
||||
row.setAttribute('data-mnote-local-ocr-task-status', String(job.status || ''));
|
||||
row.setAttribute('data-mnote-local-ocr-task-category', localOcrTaskCategory(job));
|
||||
const title = String(job.sourceRootRelativePath || '').split('/').filter(Boolean).pop() || 'OCR';
|
||||
const title = String(job.sourceRootRelativePath || '').split('/').filter(Boolean).pop() || '资料库索引';
|
||||
const category = localOcrTaskCategory(job);
|
||||
const progress = localOcrTaskProgress(job);
|
||||
row.innerHTML = '<div class="mnote-local-ocr-task-main"><div class="mnote-local-ocr-task-title-line"><strong></strong><em></em></div><span></span><div class="mnote-local-ocr-task-progress" role="progressbar"><i></i></div></div><div class="mnote-local-ocr-task-actions"><button type="button" data-mnote-local-ocr-task-open>打开</button><button type="button" data-mnote-local-ocr-task-retry>重试</button><button type="button" data-mnote-local-ocr-task-clear>清除</button><button type="button" data-mnote-local-ocr-task-delete>删除</button></div>';
|
||||
@@ -1766,7 +1772,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
if (open instanceof HTMLButtonElement) {
|
||||
open.setAttribute('data-mnote-local-ocr-task-open', String(job.sourceRootRelativePath || ''));
|
||||
open.disabled = !job.ocrRootRelativePath;
|
||||
open.hidden = job.taskKind === 'local_index';
|
||||
open.hidden = job.taskKind === 'local_index' || job.taskKind === 'knowledge_rag';
|
||||
}
|
||||
const retry = row.querySelector('[data-mnote-local-ocr-task-retry]');
|
||||
if (retry instanceof HTMLButtonElement) {
|
||||
@@ -1780,7 +1786,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const deleteOcr = row.querySelector('[data-mnote-local-ocr-task-delete]');
|
||||
if (deleteOcr instanceof HTMLButtonElement) {
|
||||
deleteOcr.setAttribute('data-mnote-local-ocr-task-delete', String(job.sourceRootRelativePath || ''));
|
||||
deleteOcr.hidden = job.taskKind === 'local_index' || !job.ocrRootRelativePath;
|
||||
deleteOcr.hidden = job.taskKind === 'local_index' || !String(job.sourceRootRelativePath || '').trim();
|
||||
}
|
||||
list.appendChild(row);
|
||||
});
|
||||
@@ -1790,13 +1796,15 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
const normalizedRoot = String(rootUri || '').trim();
|
||||
if (!normalizedRoot) return;
|
||||
localOcrTaskState.rootUri = normalizedRoot;
|
||||
const url = new URL('/api/local-folder/ocr/jobs', window.location.origin);
|
||||
const url = new URL('/api/knowledge-rag/status', window.location.origin);
|
||||
url.searchParams.set('rootUri', normalizedRoot);
|
||||
const workspaceId = String(currentWebShellWorkspaceId() || '').trim();
|
||||
if (workspaceId) url.searchParams.set('workspaceId', workspaceId);
|
||||
const response = await fetch(url.toString(), { cache: 'no-store', headers: { accept: 'application/json' } });
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok || !payload || payload.ok !== true) return;
|
||||
(Array.isArray(payload.jobs) ? payload.jobs : []).forEach((job) => {
|
||||
if (job && typeof job === 'object') job.rootUri = normalizedRoot;
|
||||
knowledgeRagRegistryEntries(payload).forEach((entry) => {
|
||||
const job = knowledgeRagJobFromRegistryEntry(entry, normalizedRoot);
|
||||
updateLocalOcrTaskState(job);
|
||||
});
|
||||
renderLocalOcrTaskDock();
|
||||
@@ -1827,74 +1835,37 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
};
|
||||
|
||||
const openLocalOcrSidecar = async (entry, job) => {
|
||||
const target = job || entry?.localOcrJob || null;
|
||||
const ocrPath = String(target?.ocrRootRelativePath || '').trim();
|
||||
if (!ocrPath || typeof openResourceInActiveTab !== 'function') return false;
|
||||
const title = ocrPath.split('/').filter(Boolean).pop() || 'OCR';
|
||||
return await openResourceInActiveTab({
|
||||
kind: 'markdown',
|
||||
title,
|
||||
path: ocrPath,
|
||||
objectIdentity: `local-ocr:${ocrPath}`,
|
||||
assetId: `local-ocr:${ocrPath}`,
|
||||
documentId: String(entry.ownerDocumentId || entry.documentId || currentWebShellDocumentId() || '').trim(),
|
||||
ownerDocumentId: String(entry.ownerDocumentId || entry.documentId || currentWebShellDocumentId() || '').trim(),
|
||||
workspaceId: String(entry.workspaceId || currentWebShellWorkspaceId() || '').trim(),
|
||||
sourceKind: 'local_folder',
|
||||
rootUri: String(entry.rootUri || '').trim(),
|
||||
resourceKind: 'markdown',
|
||||
paneRole: normalizePaneRole(entry.paneRole),
|
||||
});
|
||||
window.dispatchEvent(new CustomEvent('mnote:open-knowledge-rag-settings'));
|
||||
return false;
|
||||
};
|
||||
|
||||
const insertLocalOcrLink = async (entry, job) => {
|
||||
const target = job || entry?.localOcrJob || null;
|
||||
const ocrPath = String(target?.ocrRootRelativePath || '').trim();
|
||||
if (!ocrPath) return false;
|
||||
const response = await fetch('/api/local-folder/ocr/insert', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json', accept: 'application/json' },
|
||||
body: JSON.stringify({
|
||||
rootUri: String(entry.rootUri || '').trim(),
|
||||
documentId: String(entry.ownerDocumentId || entry.documentId || currentWebShellDocumentId() || '').trim(),
|
||||
ocrRootRelativePath: ocrPath,
|
||||
mode: 'link',
|
||||
}),
|
||||
});
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok || !payload || payload.ok !== true) {
|
||||
throw new Error(payload?.error?.message || `local_ocr_insert_failed_${response.status}`);
|
||||
}
|
||||
setLocalOcrStatus(entry, 'done', 'OCR 链接已插入正文', target);
|
||||
return true;
|
||||
throw new Error('OCR sidecar 已退役,请使用 LightRAG 资料库引用与问答。');
|
||||
};
|
||||
|
||||
const createLocalOcrJob = async (entry) => {
|
||||
if (!isLocalOcrSourceEntry(entry)) return null;
|
||||
const provider = localOcrProvider();
|
||||
const entryRootUri = String(entry.rootUri || '').trim();
|
||||
if (entryRootUri) localOcrTaskState.rootUri = entryRootUri;
|
||||
const startedAt = Date.now();
|
||||
const pendingJob = localOcrJobSnapshotFromEntry(entry, 'running', provider, '处理中', startedAt);
|
||||
setLocalOcrStatus(entry, 'running', 'OCR 处理中', pendingJob);
|
||||
const pendingJob = localOcrJobSnapshotFromEntry(entry, 'running', 'lightrag', '资料库索引中', startedAt);
|
||||
pendingJob.taskKind = 'knowledge_rag';
|
||||
setLocalOcrStatus(entry, 'running', '资料库索引中', pendingJob);
|
||||
updateLocalOcrTaskState(pendingJob);
|
||||
const workspaceId = String(entry.workspaceId || currentWebShellWorkspaceId() || '').trim();
|
||||
const body = {
|
||||
workspaceId,
|
||||
rootUri: String(entry.rootUri || '').trim(),
|
||||
documentId: String(entry.ownerDocumentId || entry.documentId || currentWebShellDocumentId() || '').trim(),
|
||||
sourceRootRelativePath: String(entry.path || '').trim(),
|
||||
provider,
|
||||
sources: [{ sourcePath: String(entry.path || '').trim() }],
|
||||
};
|
||||
if (provider === 'mock') {
|
||||
body.mockMarkdown = `# OCR Result\n\n${entry.title || entry.path} OCR UI smoke text`;
|
||||
}
|
||||
const response = await fetch('/api/local-folder/ocr/jobs', {
|
||||
const response = await fetch('/api/knowledge-rag/ingest', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json', accept: 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok || !payload || payload.ok !== true) {
|
||||
const message = payload?.error?.message || payload?.message || payload?.error?.code || `local_ocr_job_failed_${response.status}`;
|
||||
const message = payload?.error?.message || payload?.message || payload?.error?.code || `knowledge_rag_ingest_failed_${response.status}`;
|
||||
const failedJob = {
|
||||
...pendingJob,
|
||||
status: 'failed',
|
||||
@@ -1907,10 +1878,22 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
updateLocalOcrTaskState(failedJob);
|
||||
throw new Error(message);
|
||||
}
|
||||
const job = payload.job && typeof payload.job === 'object' ? { ...payload.job, rootUri: entryRootUri } : null;
|
||||
const registryEntry = knowledgeRagRegistryEntries(payload).find((candidate) => {
|
||||
return String(candidate?.sourceRootRelativePath || '').trim().replace(/\\/g, '/').replace(/^\/+/, '') === String(entry.path || '').trim().replace(/\\/g, '/').replace(/^\/+/, '');
|
||||
});
|
||||
const job = knowledgeRagJobFromRegistryEntry(registryEntry, entryRootUri) || {
|
||||
...pendingJob,
|
||||
status: payload.retryRequired ? 'running' : 'done',
|
||||
stageLabel: payload.retryRequired ? 'LightRAG 忙碌,等待重试' : '资料库已提交索引',
|
||||
updatedAtMs: Date.now(),
|
||||
finishedAtMs: payload.retryRequired ? null : Date.now(),
|
||||
};
|
||||
const displayStatus = localOcrDisplayStatus(job, 'done');
|
||||
setLocalOcrStatus(entry, displayStatus, displayStatus === 'stale' ? 'OCR 需更新' : 'OCR 已完成', job);
|
||||
setLocalOcrStatus(entry, displayStatus, displayStatus === 'stale' ? '资料库需更新' : statusTextForLocalOcrJob(job), job);
|
||||
if (job) updateLocalOcrTaskState(job);
|
||||
window.dispatchEvent(new CustomEvent('mnote:knowledge-rag-source-updated', {
|
||||
detail: { rootUri: entryRootUri, workspaceId, sourceRootRelativePath: String(entry.path || '').trim(), result: payload }
|
||||
}));
|
||||
return job;
|
||||
};
|
||||
|
||||
@@ -1919,27 +1902,24 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
if (!sourcePath) return false;
|
||||
const job = localOcrTaskState.jobsBySource.get(sourcePath) || null;
|
||||
const rootUri = String(job?.rootUri || localOcrTaskState.rootUri || currentWebShellRootUri() || '').trim();
|
||||
const response = await fetch('/api/local-folder/ocr/delete', {
|
||||
const response = await fetch('/api/knowledge-rag/delete-source', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json', accept: 'application/json' },
|
||||
body: JSON.stringify({
|
||||
rootUri,
|
||||
sourceRootRelativePath: sourcePath,
|
||||
workspaceId: String(currentWebShellWorkspaceId() || '').trim(),
|
||||
sourcePath,
|
||||
}),
|
||||
});
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok || !payload || payload.ok !== true) {
|
||||
throw new Error(payload?.error?.message || `local_ocr_delete_failed_${response.status}`);
|
||||
}
|
||||
if (payload.deleted !== true) {
|
||||
throw new Error('local_ocr_delete_noop');
|
||||
throw new Error(payload?.error?.message || `knowledge_rag_delete_failed_${response.status}`);
|
||||
}
|
||||
localOcrTaskState.jobsBySource.delete(sourcePath);
|
||||
renderLocalOcrTaskDock();
|
||||
const ocrPath = String(job?.ocrRootRelativePath || '').trim();
|
||||
if (ocrPath) {
|
||||
dispatchLocalOcrFileTreeRefresh({ ...job, status: 'stale', updatedAtMs: Date.now(), ocrRootRelativePath: ocrPath }, localOcrTaskState.rootUri);
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent('mnote:knowledge-rag-source-updated', {
|
||||
detail: { rootUri, workspaceId: String(currentWebShellWorkspaceId() || '').trim(), sourceRootRelativePath: sourcePath, result: payload }
|
||||
}));
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -2118,14 +2098,14 @@ export const createResourceTabRuntime = (dependencies = {}) => {
|
||||
});
|
||||
});
|
||||
}
|
||||
setLocalOcrStatus(entry, 'idle', 'OCR 未生成', null);
|
||||
setLocalOcrStatus(entry, 'idle', '资料库未索引', null);
|
||||
ensureLocalOcrTaskDock();
|
||||
ensureLocalOcrTaskEvents(entry.rootUri);
|
||||
void loadLocalOcrJobs(entry.rootUri).catch(() => undefined);
|
||||
void readLocalOcrStatus(entry).then((job) => {
|
||||
if (!job) return;
|
||||
const displayStatus = localOcrDisplayStatus(job, 'done');
|
||||
setLocalOcrStatus(entry, displayStatus, displayStatus === 'stale' ? 'OCR 需更新' : 'OCR 已完成', job);
|
||||
setLocalOcrStatus(entry, displayStatus, displayStatus === 'stale' ? '资料库需更新' : statusTextForLocalOcrJob(job), job);
|
||||
updateLocalOcrTaskState(job);
|
||||
}).catch(() => undefined);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user