feat(rag): align LightRAG native citations and MCP bridge
This commit is contained in:
@@ -13,6 +13,7 @@ const { BASE_URL, UI_TIMEOUT_MS } = require(path.join(ROOT, "scripts", "tree-she
|
||||
const OUTPUT_DIR = path.join(ROOT, "tmp", "task530-knowledge-rag-page-ai-final-answer-smoke");
|
||||
const RESULT_PATH = path.join(OUTPUT_DIR, "result.json");
|
||||
const SCREENSHOT_PATH = path.join(OUTPUT_DIR, "page-ai-knowledge-rag-answer.png");
|
||||
const CITATION_OPEN_SCREENSHOT_PATH = path.join(OUTPUT_DIR, "page-ai-knowledge-rag-citation-open.png");
|
||||
const CONTROL_PLANE_DB =
|
||||
process.env.MNOTE_CONTROL_PLANE_DB_PATH || "/mnt/Data1T/Mnote_data/control-plane/control-plane.db";
|
||||
const CHROME = process.env.MNOTE_PAGE_AI_CHROME || "/usr/bin/google-chrome";
|
||||
@@ -114,6 +115,60 @@ async function newestAssistantLinks(page, initialCount) {
|
||||
}, initialCount);
|
||||
}
|
||||
|
||||
async function clickNewestAssistantCitation(page, initialCount, expectedResource) {
|
||||
const total = await page
|
||||
.locator('[data-testid="wolai-page-ai-drawer"] .wolai-page-ai-message--assistant')
|
||||
.count();
|
||||
const latestIndex = Math.max(initialCount, total - 1);
|
||||
const latestMessage = page
|
||||
.locator('[data-testid="wolai-page-ai-drawer"] .wolai-page-ai-message--assistant')
|
||||
.nth(latestIndex);
|
||||
const citationLink = latestMessage.locator('a[data-page-ai-citation-link="true"]').first();
|
||||
await citationLink.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
|
||||
const popupPromise = page.waitForEvent("popup", { timeout: 5_000 }).catch(() => null);
|
||||
await citationLink.click({ timeout: UI_TIMEOUT_MS });
|
||||
const openedPage = (await popupPromise) || page;
|
||||
await openedPage.waitForLoadState("domcontentloaded", { timeout: UI_TIMEOUT_MS }).catch(() => undefined);
|
||||
await openedPage.waitForFunction(
|
||||
(resourcePath) => {
|
||||
const panel = document.querySelector(
|
||||
`[data-mnote-resource-tab-panel][data-resource-path="${CSS.escape(resourcePath)}"]`,
|
||||
);
|
||||
return panel && !panel.hidden;
|
||||
},
|
||||
expectedResource,
|
||||
{ timeout: UI_TIMEOUT_MS },
|
||||
);
|
||||
await openedPage.waitForTimeout(1500);
|
||||
const state = await openedPage.evaluate((resourcePath) => {
|
||||
const panel = document.querySelector(
|
||||
`[data-mnote-resource-tab-panel][data-resource-path="${CSS.escape(resourcePath)}"]`,
|
||||
);
|
||||
const activeTab = document.querySelector(".mnote-main-tab.is-active, [data-mnote-tab-kind].is-active");
|
||||
const image = panel ? panel.querySelector("img, [data-mnote-image-viewer], [data-mnote-resource-image]") : null;
|
||||
return {
|
||||
url: location.href,
|
||||
openedInPopup: window.opener != null,
|
||||
activeTabText: activeTab ? activeTab.textContent.trim().slice(0, 120) : "",
|
||||
activeTabKind: activeTab ? activeTab.getAttribute("data-mnote-tab-kind") : "",
|
||||
panelVisible: !!panel && !panel.hidden,
|
||||
panelResourcePath: panel ? panel.getAttribute("data-resource-path") : "",
|
||||
panelLocator: panel ? panel.getAttribute("data-mnote-evidence-locator") : "",
|
||||
panelBlockId: panel ? panel.getAttribute("data-mnote-evidence-block-id") : "",
|
||||
imageVisible: !!image,
|
||||
};
|
||||
}, expectedResource);
|
||||
await openedPage.screenshot({ path: CITATION_OPEN_SCREENSHOT_PATH, fullPage: true });
|
||||
assert.equal(state.panelVisible, true, `点击 AI citation 后未打开资源 panel: ${JSON.stringify(state, null, 2)}`);
|
||||
assert.equal(state.panelResourcePath, expectedResource, `点击 AI citation 后资源路径不匹配: ${JSON.stringify(state, null, 2)}`);
|
||||
assert(
|
||||
state.url.includes("resourceTab=") || state.url.includes("resourcePath="),
|
||||
`点击 AI citation 后 URL 缺少资源定位参数: ${JSON.stringify(state, null, 2)}`,
|
||||
);
|
||||
return state;
|
||||
}
|
||||
|
||||
function summarizeRun(body) {
|
||||
return {
|
||||
workspaceId: body.workspaceId || "",
|
||||
@@ -228,6 +283,7 @@ async function main() {
|
||||
);
|
||||
|
||||
await page.screenshot({ path: SCREENSHOT_PATH, fullPage: true });
|
||||
const citationOpenState = await clickNewestAssistantCitation(page, assistantCount, "新页面233155/image copy 6.png");
|
||||
const result = {
|
||||
ok: true,
|
||||
baseUrl: BASE_URL,
|
||||
@@ -238,9 +294,13 @@ async function main() {
|
||||
assistantLinks,
|
||||
capturedRuns: capturedRuns.map(summarizeRun),
|
||||
capturedRunsFullPath: path.join(OUTPUT_DIR, "captured-runs-full.json"),
|
||||
citationOpenState,
|
||||
pageErrors,
|
||||
consoleErrors,
|
||||
screenshot: SCREENSHOT_PATH,
|
||||
screenshots: {
|
||||
answer: SCREENSHOT_PATH,
|
||||
citationOpen: CITATION_OPEN_SCREENSHOT_PATH,
|
||||
},
|
||||
};
|
||||
fs.writeFileSync(
|
||||
path.join(OUTPUT_DIR, "captured-runs-full.json"),
|
||||
|
||||
Reference in New Issue
Block a user