feat: Page AI Reasonix desktop session alignment, settings IA cleanup, knowledge RAG hardening
- ACP client/session manager: Reasonix desktop live session context - Hermes tools: knowledge_rag tool manifest and skill updates - Browser runtime: sidebar page AI permission/profile/render/session/tree modules - Routes: hermes_client, hermes_tools, knowledge_rag, web_shell - Scripts: reasonix ACP wrapper, LightRAG MCP, smoke tasks 159/558/559/561/562 - Skills: mnote-knowledge-rag and mnote-lightrag-bridge SKILL.md updates
This commit is contained in:
@@ -124,11 +124,48 @@ async function main() {
|
||||
url.searchParams.set("workspaceId", workspaceId);
|
||||
await page.goto(url.toString(), { waitUntil: "domcontentloaded", timeout: TIMEOUT_MS });
|
||||
await page.getByTestId("wolai-floating-ai").click({ timeout: TIMEOUT_MS });
|
||||
await page.locator('[data-page-ai-tab="agent"]').first().click({ timeout: TIMEOUT_MS });
|
||||
const settingTabs = page.locator('[data-page-ai-panel="agent"] .wolai-page-ai-settings-tabs [data-page-ai-tab]');
|
||||
const settingTabTexts = await settingTabs.evaluateAll((nodes) => nodes.map((node) => node.textContent.trim()).filter(Boolean));
|
||||
assert.deepEqual(settingTabTexts, ['MNote', 'Reasonix', 'Hermes'], `设置页 tabs 应只包含 MNote / Reasonix / Hermes: ${JSON.stringify(settingTabTexts)}`);
|
||||
assert(!settingTabTexts.includes('Common') && !settingTabTexts.includes('Chat-only') && !settingTabTexts.includes('高级') && !settingTabTexts.includes('Runtime'), `设置页不应显示旧一级 tab: ${JSON.stringify(settingTabTexts)}`);
|
||||
const mnotePanelText = await page.locator('[data-page-ai-panel="agent"]').textContent({ timeout: TIMEOUT_MS });
|
||||
assert(String(mnotePanelText || '').includes('授权区域'), 'MNote tab 应显示授权区域');
|
||||
assert(String(mnotePanelText || '').includes('默认上下文'), 'MNote tab 应显示默认上下文');
|
||||
assert(String(mnotePanelText || '').includes('MNote 工具'), 'MNote tab 应显示 MNote 工具');
|
||||
assert(String(mnotePanelText || '').includes('会话与审计'), 'MNote tab 应显示会话与审计');
|
||||
await page.locator('[data-page-ai-panel="agent"] [data-page-ai-tab="reasonix-settings"]').click({ timeout: TIMEOUT_MS });
|
||||
const reasonixPanelText = await page.locator('[data-page-ai-panel="reasonix-settings"]').textContent({ timeout: TIMEOUT_MS });
|
||||
assert(String(reasonixPanelText || '').includes('ACP runtime'), 'Reasonix tab 应显示 ACP runtime');
|
||||
assert(!/MNOTE_WEB_HERMES_UPSTREAM_URL|API key|Hermes 设置入口/.test(String(reasonixPanelText || '')), `Reasonix tab 不应显示 Hermes gateway/API key 错误: ${reasonixPanelText}`);
|
||||
await page.locator('[data-page-ai-panel="reasonix-settings"] [data-page-ai-tab="hermes-settings"]').click({ timeout: TIMEOUT_MS });
|
||||
const hermesPanelText = await page.locator('[data-page-ai-panel="hermes-settings"]').textContent({ timeout: TIMEOUT_MS });
|
||||
assert(String(hermesPanelText || '').includes('Hermes profile'), 'Hermes tab 应显示 profile');
|
||||
assert(String(hermesPanelText || '').includes('Hermes gateway'), 'Hermes tab 应显示 gateway');
|
||||
assert(!String(hermesPanelText || '').includes('native-live queue'), 'Hermes tab 不应显示 Reasonix native-live queue 当前状态');
|
||||
const settingsScreenshotPath = path.join(OUT_DIR, "task561-settings-ia.png");
|
||||
await page.screenshot({ path: settingsScreenshotPath, fullPage: true });
|
||||
await page.locator('[data-page-ai-action="history"]').first().click({ timeout: TIMEOUT_MS });
|
||||
const row = page.locator(`[data-page-ai-session-row="${sessionId}"]`).first();
|
||||
await row.waitFor({ state: "visible", timeout: TIMEOUT_MS });
|
||||
const statusFilter = page.locator('[data-page-ai-session-status-filter]');
|
||||
await statusFilter.waitFor({ state: "visible", timeout: TIMEOUT_MS });
|
||||
const statusValues = await statusFilter.locator('option').evaluateAll((options) => options.map((option) => option.value));
|
||||
assert(statusValues.includes('completed'), `status filter 应包含 completed: ${JSON.stringify(statusValues)}`);
|
||||
assert.equal(await row.getAttribute('data-page-ai-session-status'), 'completed');
|
||||
await statusFilter.selectOption('completed', { timeout: TIMEOUT_MS });
|
||||
await row.waitFor({ state: "visible", timeout: TIMEOUT_MS });
|
||||
await page.locator('[data-page-ai-session-search]').fill(`dashboard seed ${suffix}`, { timeout: TIMEOUT_MS });
|
||||
await row.waitFor({ state: "visible", timeout: TIMEOUT_MS });
|
||||
const beforeDeleteScreenshotPath = path.join(OUT_DIR, "task561-session-dashboard-before-delete.png");
|
||||
await page.screenshot({ path: beforeDeleteScreenshotPath, fullPage: true });
|
||||
const exportApiResponse = await context.request.fetch(`${baseUrl}/api/page-ai/sessions/${encodeURIComponent(sessionId)}/export?workspaceId=${encodeURIComponent(workspaceId)}&documentId=${encodeURIComponent(documentId)}&limit=200`, { timeout: TIMEOUT_MS });
|
||||
const exportApiText = await exportApiResponse.text();
|
||||
assert(exportApiResponse.ok(), `/api/page-ai/sessions export 失败: ${exportApiResponse.status()} ${exportApiText.slice(0, 500)}`);
|
||||
const exportApiPayload = JSON.parse(exportApiText);
|
||||
assert.deepEqual(exportApiPayload.export.formats, ['json', 'markdown', 'jsonl']);
|
||||
assert(String(exportApiPayload.export.markdown || '').includes(sessionId), 'markdown export 应包含 sessionId');
|
||||
assert(String(exportApiPayload.export.jsonl || '').includes('"eventType"'), 'jsonl export 应包含事件行');
|
||||
await page.locator(`[data-page-ai-session-export="${sessionId}"]`).click({ timeout: TIMEOUT_MS });
|
||||
await page.waitForFunction((id) => document.documentElement.getAttribute('data-mnote-page-ai-session-exported') === id, sessionId, { timeout: TIMEOUT_MS });
|
||||
await page.evaluate(() => { window.prompt = () => 'Task561 Renamed'; });
|
||||
@@ -144,7 +181,7 @@ async function main() {
|
||||
assert(deletedRows[0] && deletedRows[0].deletedAt, "delete 应软删除 SQLite session runs");
|
||||
const screenshotPath = path.join(OUT_DIR, "task561-session-dashboard.png");
|
||||
await page.screenshot({ path: screenshotPath, fullPage: true });
|
||||
const result = { ok: true, baseUrl, outDir: OUT_DIR, workspaceId, documentId, sessionId, runId, screenshotPath };
|
||||
const result = { ok: true, baseUrl, outDir: OUT_DIR, workspaceId, documentId, sessionId, runId, settingsScreenshotPath, beforeDeleteScreenshotPath, screenshotPath };
|
||||
fs.writeFileSync(path.join(OUT_DIR, "result.json"), `${JSON.stringify(result, null, 2)}\n`, "utf8");
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
await context.close().catch(() => undefined);
|
||||
|
||||
Reference in New Issue
Block a user