yiyan-browser-agent 1.0.22 → 1.0.24
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-manager.js +45 -39
package/package.json
CHANGED
package/src/browser-manager.js
CHANGED
|
@@ -10,35 +10,47 @@ const config = require('./config');
|
|
|
10
10
|
|
|
11
11
|
const CDP_PORT_FILE = path.join(os.homedir(), '.yiyan-agent', 'cdp-port.json');
|
|
12
12
|
const CDP_PORT = 9222;
|
|
13
|
+
const SESSION_DIR = path.join(os.homedir(), '.yiyan-agent', 'session');
|
|
13
14
|
|
|
14
15
|
class BrowserManager {
|
|
15
16
|
/**
|
|
16
17
|
* Get browser - connect existing or launch new
|
|
17
18
|
*/
|
|
18
19
|
static async getInstance() {
|
|
20
|
+
// Ensure directories exist
|
|
21
|
+
fs.mkdirSync(SESSION_DIR, { recursive: true });
|
|
22
|
+
|
|
19
23
|
// Try connect existing browser
|
|
20
24
|
try {
|
|
21
25
|
if (fs.existsSync(CDP_PORT_FILE)) {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
26
|
+
const endpointInfo = JSON.parse(fs.readFileSync(CDP_PORT_FILE, 'utf8'));
|
|
27
|
+
const wsEndpoint = endpointInfo.wsEndpoint;
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
if (!wsEndpoint) {
|
|
30
|
+
throw new Error('No wsEndpoint in file');
|
|
31
|
+
}
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
const
|
|
33
|
+
logger.info('Connecting to existing browser...');
|
|
34
|
+
const browser = await chromium.connect({ wsEndpoint, timeout: 5000 });
|
|
35
|
+
|
|
36
|
+
// Create NEW context and page (tab) for this task
|
|
37
|
+
const context = await browser.newContext({
|
|
38
|
+
viewport: { width: 1280, height: 900 },
|
|
39
|
+
userAgent: 'Mozilla/5.0 AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36',
|
|
40
|
+
});
|
|
41
|
+
const page = await context.newPage();
|
|
30
42
|
await page.goto(config.YIYAN_URL, { waitUntil: 'domcontentloaded', timeout: 15000 });
|
|
31
43
|
await page.waitForTimeout(500);
|
|
32
44
|
|
|
33
|
-
logger.success('Connected!
|
|
34
|
-
return { browser, page, isNew: false };
|
|
45
|
+
logger.success('Connected! New tab opened.');
|
|
46
|
+
return { browser, context, page, isNew: false };
|
|
35
47
|
}
|
|
36
48
|
} catch (err) {
|
|
37
49
|
logger.warn('Connection failed, launching new browser...');
|
|
38
50
|
try { fs.unlinkSync(CDP_PORT_FILE); } catch {}
|
|
39
51
|
}
|
|
40
52
|
|
|
41
|
-
// Launch new browser with CDP
|
|
53
|
+
// Launch new browser with CDP port
|
|
42
54
|
return await this._launchNew();
|
|
43
55
|
}
|
|
44
56
|
|
|
@@ -46,53 +58,47 @@ class BrowserManager {
|
|
|
46
58
|
* Launch new browser with CDP port
|
|
47
59
|
*/
|
|
48
60
|
static async _launchNew() {
|
|
49
|
-
logger.info('Launching new browser...');
|
|
50
|
-
|
|
51
|
-
// Ensure session directory
|
|
52
|
-
const sessionDir = path.join(os.homedir(), '.yiyan-agent', 'session');
|
|
53
|
-
fs.mkdirSync(sessionDir, { recursive: true });
|
|
61
|
+
logger.info('Launching new browser server...');
|
|
54
62
|
|
|
55
|
-
//
|
|
56
|
-
|
|
63
|
+
// Use launchServer to create independent browser process
|
|
64
|
+
// Browser will NOT close when Node.js process exits
|
|
65
|
+
const browserServer = await chromium.launchServer({
|
|
57
66
|
headless: false,
|
|
58
|
-
viewport: { width: 1280, height: 900 },
|
|
59
67
|
args: [
|
|
60
|
-
`--remote-debugging-port=${CDP_PORT}`,
|
|
61
68
|
'--disable-blink-features=AutomationControlled',
|
|
62
69
|
'--no-first-run',
|
|
63
70
|
'--no-sandbox',
|
|
64
71
|
],
|
|
65
|
-
userAgent: 'Mozilla/5.0 AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36',
|
|
66
72
|
});
|
|
67
73
|
|
|
68
|
-
// Get the
|
|
69
|
-
const
|
|
74
|
+
// Get the WebSocket endpoint
|
|
75
|
+
const wsEndpoint = browserServer.wsEndpoint();
|
|
76
|
+
const port = wsEndpoint.match(/:(\d+)/)?.[1] || CDP_PORT;
|
|
70
77
|
|
|
71
|
-
// Save
|
|
78
|
+
// Save endpoint info
|
|
72
79
|
fs.writeFileSync(CDP_PORT_FILE, JSON.stringify({
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
wsEndpoint: wsEndpoint,
|
|
81
|
+
port: port,
|
|
75
82
|
launchedAt: Date.now()
|
|
76
83
|
}));
|
|
77
84
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
logger.success('Browser server started!');
|
|
86
|
+
|
|
87
|
+
// Connect to our own server
|
|
88
|
+
const browser = await chromium.connect({ wsEndpoint });
|
|
89
|
+
|
|
90
|
+
// Create context and page
|
|
91
|
+
const context = await browser.newContext({
|
|
92
|
+
viewport: { width: 1280, height: 900 },
|
|
93
|
+
userAgent: 'Mozilla/5.0 AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36',
|
|
94
|
+
});
|
|
95
|
+
const page = await context.newPage();
|
|
81
96
|
|
|
82
97
|
await page.goto(config.YIYAN_URL, { waitUntil: 'domcontentloaded', timeout: 15000 });
|
|
83
98
|
await page.waitForTimeout(800);
|
|
84
99
|
|
|
85
|
-
logger.success('
|
|
86
|
-
return { browser, context, page, isNew: true };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Close current page (tab) but keep browser running
|
|
91
|
-
*/
|
|
92
|
-
static async closePage(page) {
|
|
93
|
-
try {
|
|
94
|
-
await page.close();
|
|
95
|
-
} catch {}
|
|
100
|
+
logger.success('Tab ready.');
|
|
101
|
+
return { browser, context, page, isNew: true, browserServer };
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
/**
|
|
@@ -100,7 +106,7 @@ class BrowserManager {
|
|
|
100
106
|
*/
|
|
101
107
|
static async forceClose() {
|
|
102
108
|
try { fs.unlinkSync(CDP_PORT_FILE); } catch {}
|
|
103
|
-
// Browser
|
|
109
|
+
// Browser continues running independently
|
|
104
110
|
}
|
|
105
111
|
}
|
|
106
112
|
|