yiyan-browser-agent 1.7.9 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/browser.js +43 -66
package/package.json
CHANGED
package/src/browser.js
CHANGED
|
@@ -297,26 +297,49 @@ class YiyanBrowser {
|
|
|
297
297
|
if (!appeared) logger.warn('Response may have been delayed — continuing to wait...');
|
|
298
298
|
|
|
299
299
|
// Phase 2: wait for completion
|
|
300
|
-
// 条件: dialogCardBottom 出现 +
|
|
300
|
+
// 条件: dialogCardBottom 出现 + answer稳定 + 思考区域稳定
|
|
301
301
|
let lastText = '';
|
|
302
|
+
let lastThinkingText = '';
|
|
302
303
|
let stableCount = 0;
|
|
303
|
-
let
|
|
304
|
+
let thinkingStableCount = 0;
|
|
305
|
+
let lastCheckTime = Date.now();
|
|
304
306
|
let dotCount = 0;
|
|
305
307
|
let hasCompletionMarker = false;
|
|
306
308
|
|
|
307
309
|
while (Date.now() - start < timeout) {
|
|
308
310
|
const text = await this._extractLastMessage();
|
|
309
311
|
|
|
310
|
-
// ──
|
|
312
|
+
// ── 思考区域内容检测 ──
|
|
313
|
+
const thinkingInfo = await this.page.evaluate(() => {
|
|
314
|
+
const thinkingEl = document.querySelector('.container__SPpahQHm, [class*="container__SPpah"]');
|
|
315
|
+
if (!thinkingEl) return { text: '', exists: false };
|
|
316
|
+
|
|
317
|
+
const s = window.getComputedStyle(thinkingEl);
|
|
318
|
+
const isVisible = s.display !== 'none' && s.visibility !== 'hidden';
|
|
319
|
+
const text = isVisible ? (thinkingEl.innerText || '') : '';
|
|
320
|
+
|
|
321
|
+
return { text, exists: true };
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
// ── 思考区域稳定性检测 ──
|
|
325
|
+
if (thinkingInfo.text === lastThinkingText && thinkingInfo.text.length > 5) {
|
|
326
|
+
if (Date.now() - lastCheckTime >= stableDelay) {
|
|
327
|
+
thinkingStableCount++;
|
|
328
|
+
logger.dim(`Thinking stable: ${thinkingStableCount}/2 (${thinkingInfo.text.length} chars)`);
|
|
329
|
+
}
|
|
330
|
+
} else if (thinkingInfo.text !== lastThinkingText) {
|
|
331
|
+
lastThinkingText = thinkingInfo.text;
|
|
332
|
+
thinkingStableCount = 0;
|
|
333
|
+
lastCheckTime = Date.now();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// ── answer 稳定性检测 ──
|
|
311
337
|
if (text === lastText && text.length > 50) {
|
|
312
|
-
// 内容没变化,检查是否达到稳定时间
|
|
313
338
|
if (Date.now() - lastCheckTime >= stableDelay) {
|
|
314
339
|
stableCount++;
|
|
315
|
-
|
|
316
|
-
logger.dim(`Stable count: ${stableCount}/2 (${text.length} chars)`);
|
|
340
|
+
logger.dim(`Answer stable: ${stableCount}/2 (${text.length} chars)`);
|
|
317
341
|
}
|
|
318
|
-
} else {
|
|
319
|
-
// 内容变化,重置
|
|
342
|
+
} else if (text !== lastText) {
|
|
320
343
|
lastText = text;
|
|
321
344
|
stableCount = 0;
|
|
322
345
|
lastCheckTime = Date.now();
|
|
@@ -344,30 +367,14 @@ class YiyanBrowser {
|
|
|
344
367
|
hasCompletionMarker = true;
|
|
345
368
|
}
|
|
346
369
|
|
|
347
|
-
// ──
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (!thinkingEl) return { exists: false, hasContent: false };
|
|
353
|
-
|
|
354
|
-
const s = window.getComputedStyle(thinkingEl);
|
|
355
|
-
const isVisible = s.display !== 'none' && s.visibility !== 'hidden';
|
|
356
|
-
const text = thinkingEl.innerText || '';
|
|
357
|
-
const hasContent = text.length > 5;
|
|
358
|
-
|
|
359
|
-
return { exists: true, isVisible, hasContent };
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
// 思考区域存在且可见且有内容 → 还在思考,继续等待
|
|
363
|
-
if (thinkingStatus.exists && thinkingStatus.isVisible && thinkingStatus.hasContent) {
|
|
364
|
-
stableCount = 0;
|
|
365
|
-
lastCheckTime = Date.now();
|
|
366
|
-
logger.dim('Thinking in progress, continue waiting...');
|
|
367
|
-
continue;
|
|
368
|
-
}
|
|
370
|
+
// ── 完成判断 ──
|
|
371
|
+
// 条件1: 标记出现 + answer稳定 + 思考区域稳定
|
|
372
|
+
// 条件2(备用): 两者都稳定达到 4 次(即使没有完成标记)
|
|
373
|
+
const condition1 = hasCompletionMarker && stableCount >= 2 && thinkingStableCount >= 2;
|
|
374
|
+
const condition2 = stableCount >= 4 && thinkingStableCount >= 4;
|
|
369
375
|
|
|
370
|
-
|
|
376
|
+
if (condition1 || condition2) {
|
|
377
|
+
// 检查 _isGenerating 作为最终确认
|
|
371
378
|
if (!await this._isGenerating()) {
|
|
372
379
|
await this.page.waitForTimeout(500);
|
|
373
380
|
logger.clearLine();
|
|
@@ -376,6 +383,7 @@ class YiyanBrowser {
|
|
|
376
383
|
}
|
|
377
384
|
// _isGenerating 说还在生成,重置计数继续等待
|
|
378
385
|
stableCount = 0;
|
|
386
|
+
thinkingStableCount = 0;
|
|
379
387
|
lastCheckTime = Date.now();
|
|
380
388
|
}
|
|
381
389
|
|
|
@@ -472,19 +480,7 @@ class YiyanBrowser {
|
|
|
472
480
|
return result.trim();
|
|
473
481
|
}
|
|
474
482
|
|
|
475
|
-
// ──
|
|
476
|
-
const thinkingEl = document.querySelector('.container__SPpahQHm, [class*="container__SPpah"]');
|
|
477
|
-
if (thinkingEl) {
|
|
478
|
-
const s = window.getComputedStyle(thinkingEl);
|
|
479
|
-
const isVisible = s.display !== 'none' && s.visibility !== 'hidden';
|
|
480
|
-
const thinkingText = thinkingEl.innerText || '';
|
|
481
|
-
if (isVisible && thinkingText.length > 5) {
|
|
482
|
-
// 思考区域有内容,返回空字符串(等待思考完成)
|
|
483
|
-
return '';
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// ── 思考区域无内容,从 answer_text_id 提取 ──
|
|
483
|
+
// ── 从 answer_text_id 提取内容 ──
|
|
488
484
|
const answerEl = document.querySelector('#answer_text_id');
|
|
489
485
|
if (answerEl) {
|
|
490
486
|
return getFullText(answerEl);
|
|
@@ -497,26 +493,7 @@ class YiyanBrowser {
|
|
|
497
493
|
|
|
498
494
|
async _isGenerating() {
|
|
499
495
|
return await this.page.evaluate(() => {
|
|
500
|
-
// ── 1.
|
|
501
|
-
const thinkingSelectors = [
|
|
502
|
-
'.container__SPpahQHm', // Yiyan 思考过程区域
|
|
503
|
-
'[class*="container__SPpah"]',
|
|
504
|
-
'[class*="thinking"]',
|
|
505
|
-
'[class*="Thinking"]',
|
|
506
|
-
'[class*="thought"]',
|
|
507
|
-
];
|
|
508
|
-
for (const sel of thinkingSelectors) {
|
|
509
|
-
const el = document.querySelector(sel);
|
|
510
|
-
if (el) {
|
|
511
|
-
const s = window.getComputedStyle(el);
|
|
512
|
-
// 元素可见且有内容
|
|
513
|
-
if (s.display !== 'none' && s.visibility !== 'hidden' && el.innerText && el.innerText.length > 5) {
|
|
514
|
-
return true; // 思考区域有内容,还在生成
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// ── 2. 检测停止按钮/生成状态 UI ──
|
|
496
|
+
// ── 1. 检测停止按钮/生成状态 UI ──
|
|
520
497
|
const stopSelectors = [
|
|
521
498
|
'button[aria-label*="Stop" i]',
|
|
522
499
|
'button[aria-label*="停止"]',
|
|
@@ -533,7 +510,7 @@ class YiyanBrowser {
|
|
|
533
510
|
}
|
|
534
511
|
}
|
|
535
512
|
|
|
536
|
-
// ──
|
|
513
|
+
// ── 2. 检测加载动画/typing指示器 ──
|
|
537
514
|
const loaderSelectors = [
|
|
538
515
|
'[class*="typing"]',
|
|
539
516
|
'[class*="loading"]',
|
|
@@ -555,7 +532,7 @@ class YiyanBrowser {
|
|
|
555
532
|
}
|
|
556
533
|
}
|
|
557
534
|
|
|
558
|
-
// ──
|
|
535
|
+
// ── 3. 检测是否缺少完成标记元素 ──
|
|
559
536
|
const completionMarkers = [
|
|
560
537
|
'[class*="dialogCardBottom"]',
|
|
561
538
|
'.dialogCardBottom__qoXjps3z',
|