From 9ba918cdf479ad88cb1afddecb389038321fa688 Mon Sep 17 00:00:00 2001 From: WJZ_P <110795301+WJZ-P@users.noreply.github.com> Date: Mon, 23 Mar 2026 01:38:40 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gemini):=20=E4=BC=98=E5=8C=96=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB=E4=B8=8E=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E7=AE=A1=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gemini-ops.js | 29 +++++++++++++---------------- src/mcp-server.js | 16 ++++++++++------ 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/gemini-ops.js b/src/gemini-ops.js index 84dc447..58e4367 100644 --- a/src/gemini-ops.js +++ b/src/gemini-ops.js @@ -824,9 +824,15 @@ export function createOps(page) { // 5. 点击"下载完整尺寸"按钮(带重试:hover 可能需要更长时间触发工具栏) const btnSelector = 'button[data-test-id="download-generated-image-button"]'; - // 先检查按钮是否出现 - let clickResult = await op.click(btnSelector); - console.log(`[downloadFullSizeImage] 第1次点击下载按钮: ok=${clickResult.ok}, error=${clickResult.error || 'none'}`); + let clickResult; + for (let attempt = 1; attempt <= 3; attempt++) { + clickResult = await op.click(btnSelector); + if (clickResult.ok) break; + // 按钮还没出来,可能工具栏动画还没完成,再 hover 一次并多等一会儿 + console.log(`[downloadFullSizeImage] 第${attempt}次点击下载按钮失败,重试 hover...`); + await page.mouse.move(imgInfo.x, imgInfo.y); + await sleep(500); + } if (!clickResult.ok) { return { ok: false, error: 'full_size_download_btn_not_found', src: imgInfo.src, index: imgInfo.index, total: imgInfo.total }; @@ -1025,27 +1031,18 @@ export function createOps(page) { }, /** - * 完整生图流程:新建会话 → 发送提示词 → 等待 → 提取图片 + * 完整生图流程:发送提示词 → 等待 → 提取图片 + * 注意:新建会话、上传参考图等前置操作由调用方负责 * @param {string} prompt * @param {object} [opts] * @param {number} [opts.timeout=120000] - * @param {boolean} [opts.newChat=true] * @param {boolean} [opts.fullSize=false] - true 时通过 CDP 拦截下载完整尺寸原图到 outputDir;false 时提取页面预览图 base64 * @param {(status: object) => void} [opts.onPoll] */ async generateImage(prompt, opts = {}) { - const { timeout = 120_000, newChat = true, fullSize = false, onPoll } = opts; + const { timeout = 120_000, fullSize = false, onPoll } = opts; - // 1. 可选:新建会话 - if (newChat) { - const newChatResult = await this.click('newChatBtn'); - if (!newChatResult.ok) { - console.warn('[ops] newChatBtn click failed, continuing anyway'); - } - await sleep(1500); - } - - // 2. 发送并等待 + // 1. 发送并等待 const waitResult = await this.sendAndWait(prompt, { timeout, onPoll }); if (!waitResult.ok) { return { ...waitResult, step: 'sendAndWait' }; diff --git a/src/mcp-server.js b/src/mcp-server.js index a855cf2..4aa11dd 100644 --- a/src/mcp-server.js +++ b/src/mcp-server.js @@ -91,10 +91,14 @@ server.registerTool( console.error(`[mcp] ${referenceImages.length} 张参考图上传完成`); } - // 如果有参考图,已在上面手动新建会话,generateImage 内部不再新建 - // 如果没有参考图,newSession 直接传给 generateImage 内部处理 - const needNewChat = referenceImages.length > 0 ? false : newSession; - const result = await ops.generateImage(prompt, { newChat: needNewChat, fullSize, timeout }); + + // 新建会话(如需) + if (newSession) { + await ops.click('newChatBtn'); + await sleep(250); + } + + const result = await ops.generateImage(prompt, { fullSize, timeout }); // 执行完毕立刻断开,交还给 Daemon 倒计时 disconnect(); @@ -106,8 +110,8 @@ server.registerTool( }; } - // 完整尺寸下载模式:文件已由 CDP 保存到 outputDir - if (result.method === 'fullSize') { + if (fullSize) { + // 完整尺寸下载模式:文件已由 CDP 保存到 outputDir,失败则直接报错 console.error(`[mcp] 完整尺寸图片已保存至 ${result.filePath}`); return { content: [