yiyan-browser-agent 1.0.8 → 1.0.10
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 +17 -26
- package/src/config.js +3 -3
package/package.json
CHANGED
package/src/browser.js
CHANGED
|
@@ -135,14 +135,12 @@ class YiyanBrowser {
|
|
|
135
135
|
|
|
136
136
|
async _navigate(url) {
|
|
137
137
|
try {
|
|
138
|
-
//
|
|
139
|
-
await this.page.goto(url, { waitUntil: '
|
|
140
|
-
//
|
|
141
|
-
await this.page.waitForTimeout(800);
|
|
138
|
+
// Fast navigation - domcontentloaded is faster than networkidle
|
|
139
|
+
await this.page.goto(url, { waitUntil: 'domcontentloaded', timeout: 15_000 });
|
|
140
|
+
await this.page.waitForTimeout(300); // Minimal wait for SPA render
|
|
142
141
|
} catch (err) {
|
|
143
142
|
logger.warn(`Navigation warning: ${err.message}`);
|
|
144
|
-
|
|
145
|
-
await this.page.waitForTimeout(2000);
|
|
143
|
+
await this.page.waitForTimeout(800);
|
|
146
144
|
}
|
|
147
145
|
}
|
|
148
146
|
|
|
@@ -150,10 +148,10 @@ class YiyanBrowser {
|
|
|
150
148
|
try {
|
|
151
149
|
for (const sel of SEL.newChat) {
|
|
152
150
|
try {
|
|
153
|
-
const el = await this.page.waitForSelector(sel, { timeout:
|
|
151
|
+
const el = await this.page.waitForSelector(sel, { timeout: 1_500, state: 'visible' });
|
|
154
152
|
if (el) {
|
|
155
153
|
await el.click();
|
|
156
|
-
await this.page.waitForTimeout(
|
|
154
|
+
await this.page.waitForTimeout(200);
|
|
157
155
|
logger.dim('Started new chat session');
|
|
158
156
|
return;
|
|
159
157
|
}
|
|
@@ -168,9 +166,8 @@ class YiyanBrowser {
|
|
|
168
166
|
// ── Login handling (optimized) ─────────────────────────────────────────────
|
|
169
167
|
|
|
170
168
|
async _ensureLoggedIn() {
|
|
171
|
-
//
|
|
172
|
-
await this.page.
|
|
173
|
-
await this.page.waitForTimeout(500);
|
|
169
|
+
// Quick check, no unnecessary waiting
|
|
170
|
+
await this.page.waitForTimeout(200);
|
|
174
171
|
|
|
175
172
|
const needsLogin = await this.page.evaluate(() => {
|
|
176
173
|
const url = window.location.href;
|
|
@@ -190,7 +187,7 @@ class YiyanBrowser {
|
|
|
190
187
|
if (needsLogin) {
|
|
191
188
|
this._printLoginBanner();
|
|
192
189
|
await this._waitForEnter();
|
|
193
|
-
await this.page.waitForNavigation({ waitUntil: '
|
|
190
|
+
await this.page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 15_000 }).catch(() => {});
|
|
194
191
|
}
|
|
195
192
|
}
|
|
196
193
|
|
|
@@ -235,14 +232,14 @@ class YiyanBrowser {
|
|
|
235
232
|
|
|
236
233
|
// Focus and select all existing content
|
|
237
234
|
await el.click({ clickCount: 3, force: true });
|
|
238
|
-
await this.page.waitForTimeout(
|
|
235
|
+
await this.page.waitForTimeout(100);
|
|
239
236
|
|
|
240
237
|
// Clear by pressing Delete
|
|
241
238
|
await this.page.keyboard.press('Delete');
|
|
242
|
-
await this.page.waitForTimeout(
|
|
239
|
+
await this.page.waitForTimeout(50);
|
|
243
240
|
|
|
244
241
|
// Type text character by character (stable, works reliably)
|
|
245
|
-
await this.page.keyboard.type(text, { delay:
|
|
242
|
+
await this.page.keyboard.type(text, { delay: 10 });
|
|
246
243
|
|
|
247
244
|
// Press Enter to send
|
|
248
245
|
await this.page.keyboard.press('Enter');
|
|
@@ -271,13 +268,6 @@ class YiyanBrowser {
|
|
|
271
268
|
|
|
272
269
|
/**
|
|
273
270
|
* Wait until Yiyan finishes generating and return the response text.
|
|
274
|
-
*
|
|
275
|
-
* Algorithm:
|
|
276
|
-
* 1. Record how many assistant messages are on the page right now.
|
|
277
|
-
* 2. Wait until a new message appears (count goes up).
|
|
278
|
-
* 3. Poll the last message text every 300 ms.
|
|
279
|
-
* 4. When the text has not changed for STABLE_DELAY ms AND
|
|
280
|
-
* no stop/loading indicator is visible → done.
|
|
281
271
|
*/
|
|
282
272
|
async waitForResponse() {
|
|
283
273
|
const timeout = config.RESPONSE_TIMEOUT;
|
|
@@ -288,10 +278,10 @@ class YiyanBrowser {
|
|
|
288
278
|
const initialCount = await this._getMessageCount();
|
|
289
279
|
let appeared = false;
|
|
290
280
|
|
|
291
|
-
for (let i = 0; i <
|
|
281
|
+
for (let i = 0; i < 40; i++) {
|
|
292
282
|
const count = await this._getMessageCount();
|
|
293
283
|
if (count > initialCount) { appeared = true; break; }
|
|
294
|
-
await this.page.waitForTimeout(
|
|
284
|
+
await this.page.waitForTimeout(200);
|
|
295
285
|
}
|
|
296
286
|
|
|
297
287
|
if (!appeared) logger.warn('Response may have been delayed — continuing to wait...');
|
|
@@ -310,8 +300,8 @@ class YiyanBrowser {
|
|
|
310
300
|
} else if (text.length > 0) {
|
|
311
301
|
if (!stableStart) stableStart = Date.now();
|
|
312
302
|
else if (Date.now() - stableStart >= stableDelay) {
|
|
313
|
-
if (!await this._isGenerating()) break;
|
|
314
|
-
stableStart = null;
|
|
303
|
+
if (!await this._isGenerating()) break;
|
|
304
|
+
stableStart = null;
|
|
315
305
|
}
|
|
316
306
|
}
|
|
317
307
|
|
|
@@ -319,6 +309,7 @@ class YiyanBrowser {
|
|
|
319
309
|
dotCount = (dotCount + 1) % 4;
|
|
320
310
|
logger.thinking(`Receiving response${'.'.repeat(dotCount)} (${text.length} chars)`);
|
|
321
311
|
}
|
|
312
|
+
await this.page.waitForTimeout(200);
|
|
322
313
|
|
|
323
314
|
logger.clearLine();
|
|
324
315
|
|
package/src/config.js
CHANGED
|
@@ -12,10 +12,10 @@ const defaults = {
|
|
|
12
12
|
SESSION_DIR : path.join(os.homedir(), '.yiyan-agent', 'session'),
|
|
13
13
|
HEADLESS : false,
|
|
14
14
|
|
|
15
|
-
// Timing (
|
|
15
|
+
// Timing (configurable for speed vs stability tradeoff)
|
|
16
16
|
RESPONSE_TIMEOUT : 180_000,
|
|
17
|
-
STABLE_DELAY :
|
|
18
|
-
SEND_DELAY : 100, // Reduced
|
|
17
|
+
STABLE_DELAY : 1_000, // 1s stability check (faster, may cut off long responses)
|
|
18
|
+
SEND_DELAY : 100, // Reduced for faster operation
|
|
19
19
|
|
|
20
20
|
// Agent
|
|
21
21
|
MAX_ITERATIONS : 40,
|