yiyan-browser-agent 1.7.6 → 1.7.8

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/browser.js +17 -87
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yiyan-browser-agent",
3
- "version": "1.7.6",
3
+ "version": "1.7.8",
4
4
  "description": "AI coding agent powered by Yiyan (文心一言) via browser automation — no API key needed",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/browser.js CHANGED
@@ -344,29 +344,30 @@ class YiyanBrowser {
344
344
  hasCompletionMarker = true;
345
345
  }
346
346
 
347
- // ── 完成判断:标记出现 + 连续两次稳定 + _isGenerating 确认 + 思考区域检查 ──
347
+ // ── 完成判断:标记出现 + 连续两次稳定 + 思考区域已消失 ──
348
348
  if (hasCompletionMarker && stableCount >= 2) {
349
- // 检查思考区域是否有内容
350
- const hasThinkingContent = await this.page.evaluate(() => {
349
+ // 检查思考区域是否存在且有内容
350
+ const thinkingStatus = await this.page.evaluate(() => {
351
351
  const thinkingEl = document.querySelector('.container__SPpahQHm, [class*="container__SPpah"]');
352
- if (thinkingEl) {
353
- const s = window.getComputedStyle(thinkingEl);
354
- if (s.display !== 'none' && s.visibility !== 'hidden') {
355
- const text = thinkingEl.innerText || '';
356
- return text.length > 5; // 思考区域有内容
357
- }
358
- }
359
- return false;
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
360
  });
361
361
 
362
- if (hasThinkingContent) {
363
- // 思考区域有内容,还没完成
362
+ // 思考区域存在且可见且有内容 → 还在思考,继续等待
363
+ if (thinkingStatus.exists && thinkingStatus.isVisible && thinkingStatus.hasContent) {
364
364
  stableCount = 0;
365
365
  lastCheckTime = Date.now();
366
366
  logger.dim('Thinking in progress, continue waiting...');
367
367
  continue;
368
368
  }
369
369
 
370
+ // 思考区域已消失/不可见/无内容 → 检查 _isGenerating
370
371
  if (!await this._isGenerating()) {
371
372
  await this.page.waitForTimeout(500);
372
373
  logger.clearLine();
@@ -471,84 +472,13 @@ class YiyanBrowser {
471
472
  return result.trim();
472
473
  }
473
474
 
474
- // ── 优先:仅从 answer_text_id 提取内容(排除思考区域)──
475
+ // ── 仅从 answer_text_id 提取内容,不使用任何 fallback ──
475
476
  const answerEl = document.querySelector('#answer_text_id');
476
477
  if (answerEl) {
477
- const t = getFullText(answerEl);
478
- if (t.length > 0) return t;
478
+ return getFullText(answerEl);
479
479
  }
480
480
 
481
- // ── 备用:其他选择器(仅当 answer_text_id 不存在时)──
482
- const backupSelectors = [
483
- '[class*="answer"]',
484
- '[class*="response"]',
485
- '[class*="message"][class*="content"]',
486
- '.ds-markdown',
487
- '[class*="assistant"] [class*="markdown"]',
488
- '[class*="assistant"] [class*="content"]',
489
- '[data-role="assistant"] [class*="content"]',
490
- '[class*="ai-message"] [class*="content"]',
491
- '[class*="bot-message"] [class*="content"]',
492
- '[class*="response-content"]',
493
- '[class*="message-content"]:last-child',
494
- ];
495
-
496
- for (const sel of backupSelectors) {
497
- try {
498
- const els = document.querySelectorAll(sel);
499
- if (els.length > 0) {
500
- const t = getFullText(els[els.length - 1]);
501
- if (t.length > 5) return t;
502
- }
503
- } catch {}
504
- }
505
-
506
- try {
507
- const markdownEls = document.querySelectorAll(
508
- '[class*="markdown"], [class*="prose"], [class*="rendered"], [class*="content"]'
509
- );
510
- if (markdownEls.length > 0) {
511
- const t = getFullText(markdownEls[markdownEls.length - 1]);
512
- if (t.length > 10) return t;
513
- }
514
- } catch {}
515
-
516
- try {
517
- const allBlocks = Array.from(
518
- document.querySelectorAll('[class*="message"], [class*="chat-item"], [class*="turn"], [class*="answer"], [class*="content"]')
519
- );
520
- const candidates = allBlocks.filter(el => {
521
- const cls = el.className || '';
522
- const id = el.id || '';
523
- return (
524
- !cls.toLowerCase().includes('input') &&
525
- !cls.toLowerCase().includes('user') &&
526
- !cls.toLowerCase().includes('editable') &&
527
- !id.toLowerCase().includes('input') &&
528
- !el.querySelector('textarea, input[type="text"], [contenteditable="true"]') &&
529
- (el.innerText || '').length > 20
530
- );
531
- });
532
-
533
- if (candidates.length > 0) {
534
- return getFullText(candidates[candidates.length - 1]);
535
- }
536
- } catch {}
537
-
538
- try {
539
- const allDivs = Array.from(document.querySelectorAll('div, section'));
540
- const textBlocks = allDivs.filter(el => {
541
- const text = el.innerText || '';
542
- const cls = el.className || '';
543
- if (cls.includes('input') || cls.includes('editable') || cls.includes('user')) return false;
544
- return text.length > 50 && !el.querySelector('textarea, [contenteditable]');
545
- });
546
- if (textBlocks.length > 0) {
547
- textBlocks.sort((a, b) => (b.innerText || '').length - (a.innerText || '').length);
548
- return getFullText(textBlocks[0]);
549
- }
550
- } catch {}
551
-
481
+ // answer_text_id 不存在,返回空字符串
552
482
  return '';
553
483
  });
554
484
  }