#!/usr/bin/env node "use strict"; const assert = require("node:assert"); const { chromium } = require("playwright"); const { BASE_URL, UI_TIMEOUT_MS, cleanupDocuments, createTempDocument, ensureAuthenticated, renameDocument, requestJson, } = require("./tree-shell-smoke-helpers"); async function main() { const suffix = Date.now().toString(36); const title = `TEST-HERMES-AI-tool-${suffix}`; const createdIds = []; const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: 1280, height: 900 } }); const page = await context.newPage(); try { await ensureAuthenticated(page, context.request); const target = await createTempDocument(context.request); createdIds.push(target.documentId); await renameDocument(context.request, target.workspaceId, target.documentId, title); const manifest = await requestJson(context.request, "/api/hermes/tools/mnote/manifest", { method: "GET", headers: { "x-mnote-actor-id": "smoke-user" }, }); const tools = manifest?.manifest?.tools || []; assert(tools.some((tool) => tool.name === "mnote.page.get"), "manifest 缺少 mnote.page.get"); const call = await requestJson(context.request, "/api/hermes/tools/mnote/call", { method: "POST", headers: { "x-mnote-actor-id": "smoke-user" }, data: { toolName: "mnote.page.get", workspaceId: target.workspaceId, documentId: target.documentId, actorId: "smoke-user", sessionId: `mnote_smoke_tool_${suffix}`, runId: `run_smoke_tool_${suffix}`, toolCallId: `call_smoke_tool_${suffix}`, traceId: `trace_smoke_tool_${suffix}`, capabilityScope: ["page.read"], args: { includeBody: true, includeOptions: true, includeBlocks: true, }, }, }); assert.equal(call.ok, true, "tool call 应成功"); assert.equal(call.toolName, "mnote.page.get", "toolName 不一致"); assert.equal(call.toolCallId, `call_smoke_tool_${suffix}`, "toolCallId 不一致"); assert.equal(call.result.documentId, target.documentId, "工具结果 documentId 不一致"); assert.equal(call.result.workspaceId, target.workspaceId, "工具结果 workspaceId 不一致"); assert(call.result.title, "工具结果缺少标题"); assert(call.audit && call.audit.effect === "read", "工具结果缺少 read audit"); console.log( JSON.stringify( { ok: true, baseUrl: BASE_URL, documentId: target.documentId, workspaceId: target.workspaceId, toolName: call.toolName, title: call.result.title, audit: call.audit, }, null, 2, ), ); } finally { await cleanupDocuments(context.request, createdIds).catch(() => undefined); await context.close().catch(() => undefined); await browser.close().catch(() => undefined); } } main().catch((error) => { console.error(error instanceof Error ? error.stack || error.message : String(error)); process.exit(1); });