fix(gemini-ops): 注释临时会话逻辑,优化图片上传路径校验和超时配置
This commit is contained in:
14
src/demo.js
14
src/demo.js
@@ -34,13 +34,13 @@ async function main() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 进入临时会话(不留聊天记录,保持账号干净)
|
// 1. 进入临时会话(不留聊天记录,保持账号干净)
|
||||||
console.log('[1] 进入临时会话...');
|
// console.log('[1] 进入临时会话...');
|
||||||
const tempResult = await ops.clickTempChat();
|
// const tempResult = await ops.clickTempChat();
|
||||||
if (!tempResult.ok) {
|
// if (!tempResult.ok) {
|
||||||
console.warn('[1] 临时会话按钮未找到,跳过(可能已在临时模式或页面结构变化)');
|
// console.warn('[1] 临时会话按钮未找到,跳过(可能已在临时模式或页面结构变化)');
|
||||||
} else {
|
// } else {
|
||||||
console.log('[1] 已进入临时会话');
|
// console.log('[1] 已进入临时会话');
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 2. 探测页面状态
|
// 2. 探测页面状态
|
||||||
console.log('\n[2] 探测页面元素...');
|
console.log('\n[2] 探测页面元素...');
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
import { createOperator } from './operator.js';
|
import { createOperator } from './operator.js';
|
||||||
import { sleep } from './util.js';
|
import { sleep } from './util.js';
|
||||||
import config from './config.js';
|
import config from './config.js';
|
||||||
import { mkdirSync } from 'node:fs';
|
import { mkdirSync, existsSync } from 'node:fs';
|
||||||
|
import { resolve as pathResolve, normalize as pathNormalize } from 'node:path';
|
||||||
import { removeWatermarkFromFile, removeWatermarkFromDataUrl } from './watermark-remover.js';
|
import { removeWatermarkFromFile, removeWatermarkFromDataUrl } from './watermark-remover.js';
|
||||||
|
|
||||||
// ── Gemini 页面元素选择器 ──
|
// ── Gemini 页面元素选择器 ──
|
||||||
@@ -923,6 +924,13 @@ export function createOps(page) {
|
|||||||
*/
|
*/
|
||||||
async uploadImage(filePath) {
|
async uploadImage(filePath) {
|
||||||
try {
|
try {
|
||||||
|
// 路径规范化(兼容 Windows 反斜杠、混合斜杠等)
|
||||||
|
filePath = pathResolve(pathNormalize(filePath));
|
||||||
|
|
||||||
|
if (!existsSync(filePath)) {
|
||||||
|
return { ok: false, error: 'file_not_found', detail: `文件不存在: ${filePath}` };
|
||||||
|
}
|
||||||
|
|
||||||
// 1. 点击加号面板按钮,展开上传菜单
|
// 1. 点击加号面板按钮,展开上传菜单
|
||||||
const panelClick = await this.click('uploadPanelBtn');
|
const panelClick = await this.click('uploadPanelBtn');
|
||||||
if (!panelClick.ok) {
|
if (!panelClick.ok) {
|
||||||
@@ -934,7 +942,7 @@ export function createOps(page) {
|
|||||||
|
|
||||||
// 3. Promise.all 是精髓:一边开始监听文件选择器弹窗,一边点击"上传文件"按钮
|
// 3. Promise.all 是精髓:一边开始监听文件选择器弹窗,一边点击"上传文件"按钮
|
||||||
const [fileChooser] = await Promise.all([
|
const [fileChooser] = await Promise.all([
|
||||||
page.waitForFileChooser({ timeout: 3_000 }),
|
page.waitForFileChooser({ timeout: 5_000 }),
|
||||||
this.click('uploadFileBtn'),
|
this.click('uploadFileBtn'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -943,8 +951,8 @@ export function createOps(page) {
|
|||||||
console.log(`[ops] 文件已塞入,等待 Gemini 加载图片...`);
|
console.log(`[ops] 文件已塞入,等待 Gemini 加载图片...`);
|
||||||
|
|
||||||
// 5. 等待图片加载完成(.image-preview.loading 消失)
|
// 5. 等待图片加载完成(.image-preview.loading 消失)
|
||||||
const loadTimeout = 10_000;
|
const loadTimeout = 15_000;
|
||||||
const loadInterval = 250;
|
const loadInterval = 500;
|
||||||
const loadStart = Date.now();
|
const loadStart = Date.now();
|
||||||
await sleep(500); // 短暂等待 UI 响应
|
await sleep(500); // 短暂等待 UI 响应
|
||||||
while (Date.now() - loadStart < loadTimeout) {
|
while (Date.now() - loadStart < loadTimeout) {
|
||||||
@@ -953,7 +961,7 @@ export function createOps(page) {
|
|||||||
return !!el;
|
return !!el;
|
||||||
});
|
});
|
||||||
if (!loading) {
|
if (!loading) {
|
||||||
console.log(`[ops] 图片加载完成 (${Date.now() - loadStart}ms): ${filePath}`);
|
console.log(`[ops] 图片上传成功 (${Date.now() - loadStart}ms): ${filePath}`);
|
||||||
return { ok: true, elapsed: Date.now() - loadStart };
|
return { ok: true, elapsed: Date.now() - loadStart };
|
||||||
}
|
}
|
||||||
await sleep(loadInterval);
|
await sleep(loadInterval);
|
||||||
|
|||||||
@@ -48,16 +48,18 @@ server.registerTool(
|
|||||||
isError: true,
|
isError: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// 检查是否需要新建会话
|
||||||
|
if (newSession) {
|
||||||
|
await ops.click('newChatBtn');
|
||||||
|
await sleep(250);
|
||||||
|
}
|
||||||
|
|
||||||
// 确保是 pro 模型(生图需要 Pro)
|
// 确保是 pro 模型(生图需要 Pro)
|
||||||
await ops.ensureModelPro();
|
await ops.ensureModelPro();
|
||||||
|
|
||||||
// 如果有参考图,需要先新建会话再上传,最后 generateImage 不再新建
|
// 如果有参考图,需要上传参考图
|
||||||
if (referenceImages.length > 0) {
|
if (referenceImages.length > 0) {
|
||||||
if (newSession) {
|
|
||||||
await ops.click('newChatBtn');
|
|
||||||
await sleep(250);
|
|
||||||
}
|
|
||||||
for (const imgPath of referenceImages) {
|
for (const imgPath of referenceImages) {
|
||||||
console.error(`[mcp] 正在上传参考图: ${imgPath}`);
|
console.error(`[mcp] 正在上传参考图: ${imgPath}`);
|
||||||
const uploadResult = await ops.uploadImage(imgPath);
|
const uploadResult = await ops.uploadImage(imgPath);
|
||||||
|
|||||||
Reference in New Issue
Block a user