feat(rag): align LightRAG native citations and MCP bridge

This commit is contained in:
lix-2026
2026-06-09 09:20:56 +08:00
parent 0e8b03daf8
commit 8e3be8b0b7
39 changed files with 2255 additions and 2732 deletions
@@ -2135,6 +2135,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
'<div class="wolai-search-options-left">' +
'<span class="wolai-search-switch-control"><span>仅匹配标题</span><button type="button" class="wolai-search-switch" data-search-switch="title" role="switch" aria-checked="false" aria-label="仅匹配标题"></button></span>' +
'<span class="wolai-search-switch-control"><span>精确匹配</span><button type="button" class="wolai-search-switch" data-search-switch="exact" role="switch" aria-checked="false" aria-label="精确匹配"></button></span>' +
'<span class="wolai-search-sort-control"><span>资料库模式</span><select class="wolai-search-sort-value" data-search-knowledge-mode aria-label="资料库检索模式"><option value="mix">综合</option><option value="hybrid">图谱混合</option><option value="naive">向量</option><option value="local">实体</option><option value="global">关系</option><option value="exact">关键词</option></select></span>' +
'<span class="wolai-search-sort-control"><span>按编辑时间</span><button type="button" class="wolai-search-sort-value" data-search-sort="updated" aria-label="按编辑时间范围">所有</button></span>' +
'<span class="wolai-search-sort-control"><span>按创建时间</span><button type="button" class="wolai-search-sort-value" data-search-sort="created" aria-label="按创建时间范围">所有</button></span>' +
'</div>' +
@@ -2170,6 +2171,13 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
scheduleSearchResultsRender();
});
});
var knowledgeModeSelect = overlay.querySelector('[data-search-knowledge-mode]');
if (knowledgeModeSelect) {
knowledgeModeSelect.addEventListener('change', function() {
searchUiState.hasRendered = false;
scheduleSearchResultsRender();
});
}
if (closeButton) closeButton.addEventListener('click', closeSearchModal);
overlay.addEventListener('click', function(event) {
if (event.target === overlay) closeSearchModal();
@@ -2186,6 +2194,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
metaHtml: '',
resultsHtml: '',
items: [],
knowledgeMode: 'mix',
sourceCollapsed: {},
scrollTop: 0,
signature: '',
@@ -2236,6 +2245,27 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return button instanceof HTMLElement && button.getAttribute('aria-checked') === 'true';
}
function searchKnowledgeModeValue(overlay) {
var select = overlay.querySelector('[data-search-knowledge-mode]');
var value = select && 'value' in select ? searchText(select.value).toLowerCase() : '';
if (['mix', 'hybrid', 'naive', 'local', 'global', 'exact'].indexOf(value) >= 0) return value;
return 'mix';
}
function knowledgeSearchRequestMode(overlay) {
if (searchSwitchValue(overlay, 'exact')) return 'exact';
return searchKnowledgeModeValue(overlay);
}
function knowledgeSearchModeLabel(mode) {
if (mode === 'exact') return '关键词';
if (mode === 'naive') return '向量';
if (mode === 'local') return '实体';
if (mode === 'global') return '关系';
if (mode === 'hybrid') return '图谱混合';
return '综合';
}
function readSearchCollapseSourcesDefault() {
try {
var stored = window.localStorage && window.localStorage.getItem(SEARCH_COLLAPSE_SOURCES_KEY);
@@ -2284,6 +2314,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
title: Boolean(switches.title),
exact: Boolean(switches.exact),
collapseSource: Boolean(switches.collapseSource),
knowledgeMode: searchKnowledgeModeValue(overlay),
workspaceId: resolveWorkspaceId(document.body) || '',
rootUri: currentRootUri() || ''
});
@@ -2297,6 +2328,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var query = input && 'value' in input ? searchText(input.value) : searchUiState.query;
searchUiState.query = query;
searchUiState.switches = collectSearchSwitchState(overlay);
searchUiState.knowledgeMode = searchKnowledgeModeValue(overlay);
searchUiState.metaHtml = meta ? meta.innerHTML : searchUiState.metaHtml;
searchUiState.resultsHtml = results ? results.innerHTML : searchUiState.resultsHtml;
searchUiState.items = Array.isArray(window.__mnoteSearchResults) ? window.__mnoteSearchResults.slice() : searchUiState.items;
@@ -2312,6 +2344,8 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var results = overlay.querySelector('[data-testid="wolai-search-results"]');
if (input && 'value' in input) input.value = searchUiState.query || '';
applySearchSwitchState(overlay, searchUiState.switches);
var knowledgeModeSelect = overlay.querySelector('[data-search-knowledge-mode]');
if (knowledgeModeSelect && 'value' in knowledgeModeSelect) knowledgeModeSelect.value = searchUiState.knowledgeMode || 'mix';
if (options instanceof HTMLElement) options.hidden = !searchText(searchUiState.query);
if (meta && searchUiState.metaHtml) meta.innerHTML = searchUiState.metaHtml;
if (results && searchUiState.resultsHtml) {
@@ -2421,7 +2455,8 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
function renderSearchResultButton(item, index, query, exact, grouped) {
var title = searchText(item.title || item.name || item.documentTitle || '无标题');
var snippet = cleanSearchDisplayText(item.snippet || item.evidence && item.evidence.quote || (Array.isArray(item.evidence) && item.evidence[0] && (item.evidence[0].quote || item.evidence[0].snippet)) || '');
var snippet = searchText(item.displayQuote || item.snippet || item.evidence && item.evidence.displayQuote || item.evidence && item.evidence.quote || (Array.isArray(item.evidence) && item.evidence[0] && (item.evidence[0].displayQuote || item.evidence[0].quote || item.evidence[0].snippet)) || '');
if (!item.displayQuote) snippet = cleanSearchDisplayText(snippet);
var path = searchText(item.path || item.parentTitle || item.workspaceName || currentWorkspaceName());
var resourceType = searchText(item.resourceType || item.resourceKind || 'page');
var locator = searchResultEvidenceLocator(item);
@@ -2545,10 +2580,11 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var resourceKind = evidenceLocatorResourceKind(locator, item && item.resourceType);
var overlay = document.querySelector('[data-testid="wolai-search-modal"]');
var searchInput = overlay instanceof HTMLElement ? overlay.querySelector('[data-testid="wolai-search-input"]') : null;
var searchQueryText = searchText(item && (item.query || item.searchQuery))
var searchQueryText = searchText(item && (item.searchQuery || item.query) || locator && locator.openAction && locator.openAction.params && locator.openAction.params.searchQuery)
|| searchText(searchInput && 'value' in searchInput ? searchInput.value : '')
|| searchText(searchUiState.query);
var locatorEvidenceText = searchText(locator.evidenceText || locator.query || locator.openAction && locator.openAction.params && locator.openAction.params.query || '');
var locatorEvidenceText = searchText(item && item.locatorEvidenceText || locator.evidenceText || locator.query || locator.openAction && locator.openAction.params && (locator.openAction.params.evidenceText || locator.openAction.params.query) || '');
var locatorParams = locator && locator.openAction && locator.openAction.params && typeof locator.openAction.params === 'object' ? locator.openAction.params : {};
var openTarget = event && event.altKey ? 'side' : 'active-tab';
if (resourcePath && resourceKind) {
var fileName = resourcePath.split('/').filter(Boolean).pop() || resourcePath;
@@ -2573,6 +2609,10 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
bbox: locator.bbox,
sourceMapPath: searchText(locator.sourceMapPath || locator.source_map_path),
blockId: evidenceLocatorBlockId(locator),
paragraphOrdinal: searchText(locator.paragraphOrdinal || locatorParams.paragraphOrdinal),
paraIdStart: searchText(locator.paraIdStart || locatorParams.paraIdStart),
paraIdEnd: searchText(locator.paraIdEnd || locatorParams.paraIdEnd),
textFingerprint: searchText(locator.textFingerprint || locatorParams.textFingerprint),
evidenceText: locatorEvidenceText,
query: searchQueryText,
searchQuery: searchQueryText,
@@ -2593,6 +2633,10 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var bbox = evidenceLocatorBbox(locator);
if (bbox) target.searchParams.set('bbox', bbox);
if (sourceMapPath) target.searchParams.set('sourceMapPath', sourceMapPath);
if (locatorParams.paragraphOrdinal != null) target.searchParams.set('paragraphOrdinal', searchText(locatorParams.paragraphOrdinal));
if (locatorParams.paraIdStart) target.searchParams.set('paraIdStart', searchText(locatorParams.paraIdStart));
if (locatorParams.paraIdEnd) target.searchParams.set('paraIdEnd', searchText(locatorParams.paraIdEnd));
if (locatorParams.textFingerprint) target.searchParams.set('textFingerprint', searchText(locatorParams.textFingerprint));
window.location.assign(target.pathname + target.search + target.hash);
} catch (_) {
window.location.assign(url);
@@ -2643,6 +2687,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return;
}
var requestId = ++activeSearchRequestId;
var knowledgeRequestMode = knowledgeMode ? knowledgeSearchRequestMode(overlay) : '';
meta.innerHTML = '<span>搜索中…</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
results.innerHTML = '<div class="wolai-search-empty" data-search-loading="true">搜索中…</div>';
try {
@@ -2653,7 +2698,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
workspaceId: resolveWorkspaceId(document.body),
rootUri: currentRootUri() || null,
query: query,
mode: 'hybrid',
mode: knowledgeRequestMode,
topK: 12,
chunkTopK: 24,
includeChunkContent: true
@@ -2677,7 +2722,8 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
var payload = await response.json();
if (requestId !== activeSearchRequestId) return;
var items = Array.isArray(payload.results) ? payload.results : [];
meta.innerHTML = '<span>' + (knowledgeMode ? '资料库检索' : '工作区搜索') + ' · 共 ' + items.length + ' 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
var ownerLabel = knowledgeMode ? ('资料库检索 · ' + knowledgeSearchModeLabel(payload.retrievalMode || knowledgeRequestMode)) : '工作区搜索';
meta.innerHTML = '<span>' + ownerLabel + ' · 共 ' + items.length + ' 条匹配结果</span><span>Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开</span>';
if (!items.length) {
results.innerHTML = '<div class="wolai-search-empty" data-search-empty="true">没有搜索结果</div>';
window.__mnoteSearchResults = [];