chore: harden lightrag knowledge rag runtime

This commit is contained in:
lix-2026
2026-06-09 22:12:09 +08:00
parent 922965d30f
commit f698aad964
22 changed files with 899 additions and 101 deletions
@@ -690,11 +690,18 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const entry = resourceTabRegistry.get(activeResource);
const documentId = String(entry?.ownerDocumentId || entry?.documentId || '').trim();
if (documentId) url.pathname = `/documents/${encodeURIComponent(documentId)}`;
const sourceKind = String(entry?.sourceKind || currentWebShellSourceKind() || '').trim();
const rootUri = String(entry?.rootUri || currentWebShellRootUri() || '').trim();
const resourcePath = String(entry?.path || entry?.session?.resourcePath || '').trim();
if (sourceKind) url.searchParams.set('sourceKind', sourceKind);
if (rootUri) url.searchParams.set('rootUri', rootUri);
if (resourcePath) url.searchParams.set('resourcePath', resourcePath);
url.searchParams.set('resourceTab', activeResource);
} else {
const documentId = currentWebShellDocumentId();
if (documentId) url.pathname = `/documents/${encodeURIComponent(documentId)}`;
url.searchParams.delete('resourceTab');
url.searchParams.delete('resourcePath');
}
replaceUrlState(url);
};
@@ -1085,6 +1092,59 @@ export const createResourceTabRuntime = (dependencies = {}) => {
overlay.style.height = `${Math.max(1, bbox.y1 - bbox.y0)}px`;
};
const applyPdfEvidenceOverlayToCanvas = (canvas, locator) => {
if (!(canvas instanceof HTMLCanvasElement)) return null;
const frame = canvas.parentElement instanceof HTMLElement && canvas.parentElement.hasAttribute('data-mnote-pdf-page-frame')
? canvas.parentElement
: null;
if (!(frame instanceof HTMLElement)) return null;
const bbox = normalizeEvidenceBBox(locator?.bbox);
let overlay = frame.querySelector('[data-mnote-evidence-bbox-highlight]');
if (!bbox) {
if (overlay instanceof HTMLElement) overlay.hidden = true;
return null;
}
const viewport = canvas.__mnotePdfViewport;
if (!viewport || typeof viewport.convertToViewportRectangle !== 'function') return null;
if (!(overlay instanceof HTMLElement)) {
overlay = document.createElement('div');
overlay.className = 'mnote-resource-tab-bbox-highlight';
overlay.setAttribute('data-mnote-evidence-bbox-highlight', 'true');
frame.append(overlay);
}
const normalizedMineruBox = bbox.x0 >= 0 && bbox.y0 >= 0 && bbox.x1 <= 1000 && bbox.y1 <= 1000;
let x;
let y;
let width;
let height;
if (normalizedMineruBox) {
x = Math.min(bbox.x0, bbox.x1) / 1000 * viewport.width;
y = Math.min(bbox.y0, bbox.y1) / 1000 * viewport.height;
width = Math.max(1, Math.abs(bbox.x1 - bbox.x0) / 1000 * viewport.width);
height = Math.max(1, Math.abs(bbox.y1 - bbox.y0) / 1000 * viewport.height);
} else {
const rect = viewport.convertToViewportRectangle([bbox.x0, bbox.y0, bbox.x1, bbox.y1]);
x = Math.min(rect[0], rect[2]);
y = Math.min(rect[1], rect[3]);
width = Math.max(1, Math.abs(rect[2] - rect[0]));
height = Math.max(1, Math.abs(rect[3] - rect[1]));
}
overlay.hidden = false;
overlay.style.left = `${Math.max(0, x)}px`;
overlay.style.top = `${Math.max(0, y)}px`;
overlay.style.width = `${width}px`;
overlay.style.height = `${height}px`;
return overlay;
};
const scrollPdfEvidenceTargetIntoView = (canvas, overlay) => {
const target = overlay instanceof HTMLElement && !overlay.hidden
? overlay
: (canvas?.parentElement instanceof HTMLElement ? canvas.parentElement : canvas);
if (!(target instanceof HTMLElement)) return;
window.setTimeout(() => target.scrollIntoView({ block: 'center', inline: 'nearest' }), 0);
};
const applyEvidenceLocatorToTextPanel = (entry, locator) => {
if (!(entry?.panel instanceof HTMLElement) || !locator) return;
const root = entry.panel.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"]');
@@ -1119,8 +1179,12 @@ export const createResourceTabRuntime = (dependencies = {}) => {
entry.panel.querySelectorAll('canvas.mnote-pdf-page[data-mnote-evidence-page="true"]').forEach((node) => {
if (node instanceof HTMLElement) node.removeAttribute('data-mnote-evidence-page');
});
entry.panel.querySelectorAll('[data-mnote-evidence-bbox-highlight]').forEach((node) => {
if (node instanceof HTMLElement) node.hidden = true;
});
canvas.setAttribute('data-mnote-evidence-page', 'true');
canvas.scrollIntoView({ block: 'center', inline: 'nearest' });
const overlay = applyPdfEvidenceOverlayToCanvas(canvas, locator);
scrollPdfEvidenceTargetIntoView(canvas, overlay);
};
const applyEvidenceLocatorToEntry = (entry, input = {}) => {
@@ -1328,16 +1392,23 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const scale = Math.max(0.6, Math.min(2.4, availableWidth / baseViewport.width));
const viewport = page.getViewport({ scale });
const outputScale = Math.min(2.5, Math.max(2, window.devicePixelRatio || 1));
const frame = document.createElement('div');
frame.setAttribute('data-mnote-pdf-page-frame', 'true');
frame.style.position = 'relative';
frame.style.width = `${Math.floor(viewport.width)}px`;
frame.style.maxWidth = '100%';
frame.style.margin = '0 auto 14px';
const canvas = document.createElement('canvas');
canvas.className = 'mnote-pdf-page';
canvas.setAttribute('data-page-number', String(pageNumber));
canvas.__mnotePdfViewport = viewport;
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.display = 'block';
canvas.style.maxWidth = '100%';
canvas.style.width = `${Math.floor(viewport.width)}px`;
canvas.style.height = `${Math.floor(viewport.height)}px`;
canvas.style.margin = '0 auto 14px';
canvas.style.margin = '0';
canvas.style.background = '#fff';
canvas.style.border = '1px solid #d8d8d2';
canvas.style.boxShadow = '0 2px 10px rgba(25, 25, 22, .08)';
@@ -1351,25 +1422,12 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const evidencePage = Number(evidenceLocator?.page || 0);
if (evidencePage === pageNumber) {
canvas.setAttribute('data-mnote-evidence-page', 'true');
const bbox = normalizeEvidenceBBox(evidenceLocator?.bbox);
if (bbox) {
const rect = viewport.convertToViewportRectangle([bbox.x0, bbox.y0, bbox.x1, bbox.y1]);
const x = Math.min(rect[0], rect[2]);
const y = Math.min(rect[1], rect[3]);
const width = Math.max(1, Math.abs(rect[2] - rect[0]));
const height = Math.max(1, Math.abs(rect[3] - rect[1]));
context.save();
context.scale(outputScale, outputScale);
context.fillStyle = 'rgba(37, 99, 235, 0.18)';
context.strokeStyle = 'rgba(37, 99, 235, 0.9)';
context.lineWidth = 2;
context.fillRect(x, y, width, height);
context.strokeRect(x, y, width, height);
context.restore();
}
}
if (entry.inlinePdfDocument === pdf) viewer.append(canvas);
if (evidencePage === pageNumber) window.setTimeout(() => canvas.scrollIntoView({ block: 'center', inline: 'nearest' }), 0);
frame.append(canvas);
let evidenceOverlay = null;
if (evidencePage === pageNumber) evidenceOverlay = applyPdfEvidenceOverlayToCanvas(canvas, evidenceLocator);
if (entry.inlinePdfDocument === pdf) viewer.append(frame);
if (evidencePage === pageNumber) scrollPdfEvidenceTargetIntoView(canvas, evidenceOverlay);
};
const openInlinePdfResourceTab = async (entry, input) => {