@roomi-fields/notebooklm-mcp 1.1.2
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/LICENSE +22 -0
- package/README.md +548 -0
- package/dist/auth/auth-manager.d.ts +139 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +981 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/config.d.ts +89 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-wrapper.d.ts +8 -0
- package/dist/http-wrapper.d.ts.map +1 -0
- package/dist/http-wrapper.js +221 -0
- package/dist/http-wrapper.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +499 -0
- package/dist/index.js.map +1 -0
- package/dist/library/notebook-library.d.ts +81 -0
- package/dist/library/notebook-library.d.ts.map +1 -0
- package/dist/library/notebook-library.js +362 -0
- package/dist/library/notebook-library.js.map +1 -0
- package/dist/library/types.d.ts +67 -0
- package/dist/library/types.d.ts.map +1 -0
- package/dist/library/types.js +8 -0
- package/dist/library/types.js.map +1 -0
- package/dist/session/browser-session.d.ts +108 -0
- package/dist/session/browser-session.d.ts.map +1 -0
- package/dist/session/browser-session.js +630 -0
- package/dist/session/browser-session.js.map +1 -0
- package/dist/session/session-manager.d.ts +76 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +273 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/shared-context-manager.d.ts +107 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -0
- package/dist/session/shared-context-manager.js +447 -0
- package/dist/session/shared-context-manager.js.map +1 -0
- package/dist/tools/index.d.ts +225 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +1396 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +133 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +673 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +92 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/page-utils.d.ts +54 -0
- package/dist/utils/page-utils.d.ts.map +1 -0
- package/dist/utils/page-utils.js +422 -0
- package/dist/utils/page-utils.js.map +1 -0
- package/dist/utils/stealth-utils.d.ts +135 -0
- package/dist/utils/stealth-utils.d.ts.map +1 -0
- package/dist/utils/stealth-utils.js +398 -0
- package/dist/utils/stealth-utils.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Session
|
|
3
|
+
*
|
|
4
|
+
* Represents a single browser session for NotebookLM interactions.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Human-like question typing
|
|
8
|
+
* - Streaming response detection
|
|
9
|
+
* - Auto-login on session expiry
|
|
10
|
+
* - Session activity tracking
|
|
11
|
+
* - Chat history reset
|
|
12
|
+
*
|
|
13
|
+
* Based on the Python implementation from browser_session.py
|
|
14
|
+
*/
|
|
15
|
+
import { humanType, randomDelay } from "../utils/stealth-utils.js";
|
|
16
|
+
import { waitForLatestAnswer, snapshotAllResponses, } from "../utils/page-utils.js";
|
|
17
|
+
import { CONFIG } from "../config.js";
|
|
18
|
+
import { log } from "../utils/logger.js";
|
|
19
|
+
import { RateLimitError } from "../errors.js";
|
|
20
|
+
export class BrowserSession {
|
|
21
|
+
sessionId;
|
|
22
|
+
notebookUrl;
|
|
23
|
+
createdAt;
|
|
24
|
+
lastActivity;
|
|
25
|
+
messageCount;
|
|
26
|
+
context;
|
|
27
|
+
sharedContextManager;
|
|
28
|
+
authManager;
|
|
29
|
+
page = null;
|
|
30
|
+
initialized = false;
|
|
31
|
+
constructor(sessionId, sharedContextManager, authManager, notebookUrl) {
|
|
32
|
+
this.sessionId = sessionId;
|
|
33
|
+
this.sharedContextManager = sharedContextManager;
|
|
34
|
+
this.authManager = authManager;
|
|
35
|
+
this.notebookUrl = notebookUrl;
|
|
36
|
+
this.createdAt = Date.now();
|
|
37
|
+
this.lastActivity = Date.now();
|
|
38
|
+
this.messageCount = 0;
|
|
39
|
+
log.info(`🆕 BrowserSession ${sessionId} created`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Initialize the session by creating a page and navigating to the notebook
|
|
43
|
+
*/
|
|
44
|
+
async init() {
|
|
45
|
+
if (this.initialized) {
|
|
46
|
+
log.warning(`⚠️ Session ${this.sessionId} already initialized`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
log.info(`🚀 Initializing session ${this.sessionId}...`);
|
|
50
|
+
try {
|
|
51
|
+
// Ensure a valid shared context
|
|
52
|
+
this.context = await this.sharedContextManager.getOrCreateContext();
|
|
53
|
+
// Create new page (tab) in the shared context (with auto-recovery)
|
|
54
|
+
try {
|
|
55
|
+
this.page = await this.context.newPage();
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
const msg = String(e?.message || e);
|
|
59
|
+
if (/has been closed|Target .* closed|Browser has been closed|Context .* closed/i.test(msg)) {
|
|
60
|
+
log.warning(" ♻️ Context was closed. Recreating and retrying newPage...");
|
|
61
|
+
this.context = await this.sharedContextManager.getOrCreateContext();
|
|
62
|
+
this.page = await this.context.newPage();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
log.success(` ✅ Created new page`);
|
|
69
|
+
// Navigate to notebook
|
|
70
|
+
log.info(` 🌐 Navigating to: ${this.notebookUrl}`);
|
|
71
|
+
await this.page.goto(this.notebookUrl, {
|
|
72
|
+
waitUntil: "domcontentloaded",
|
|
73
|
+
timeout: CONFIG.browserTimeout,
|
|
74
|
+
});
|
|
75
|
+
// Wait for page to stabilize
|
|
76
|
+
await randomDelay(2000, 3000);
|
|
77
|
+
// Check if we need to login
|
|
78
|
+
const isAuthenticated = await this.authManager.validateCookiesExpiry(this.context);
|
|
79
|
+
if (!isAuthenticated) {
|
|
80
|
+
log.warning(` 🔑 Session ${this.sessionId} needs authentication`);
|
|
81
|
+
const loginSuccess = await this.ensureAuthenticated();
|
|
82
|
+
if (!loginSuccess) {
|
|
83
|
+
throw new Error("Failed to authenticate session");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
log.success(` ✅ Session already authenticated`);
|
|
88
|
+
}
|
|
89
|
+
// CRITICAL: Restore sessionStorage from saved state
|
|
90
|
+
// This is essential for maintaining Google session state!
|
|
91
|
+
log.info(` 🔄 Restoring sessionStorage...`);
|
|
92
|
+
const sessionData = await this.authManager.loadSessionStorage();
|
|
93
|
+
if (sessionData) {
|
|
94
|
+
const entryCount = Object.keys(sessionData).length;
|
|
95
|
+
if (entryCount > 0) {
|
|
96
|
+
await this.restoreSessionStorage(sessionData, entryCount);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
log.info(` ℹ️ SessionStorage empty (fresh session)`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
log.info(` ℹ️ No saved sessionStorage found (fresh session)`);
|
|
104
|
+
}
|
|
105
|
+
// Wait for NotebookLM interface to load
|
|
106
|
+
log.info(` ⏳ Waiting for NotebookLM interface...`);
|
|
107
|
+
await this.waitForNotebookLMReady();
|
|
108
|
+
this.initialized = true;
|
|
109
|
+
this.updateActivity();
|
|
110
|
+
log.success(`✅ Session ${this.sessionId} initialized successfully`);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
log.error(`❌ Failed to initialize session ${this.sessionId}: ${error}`);
|
|
114
|
+
if (this.page) {
|
|
115
|
+
await this.page.close();
|
|
116
|
+
this.page = null;
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Wait for NotebookLM interface to be ready
|
|
123
|
+
*
|
|
124
|
+
* IMPORTANT: Matches Python implementation EXACTLY!
|
|
125
|
+
* - Uses SPECIFIC selectors (textarea.query-box-input)
|
|
126
|
+
* - Checks ONLY for "visible" state (NOT disabled!)
|
|
127
|
+
* - NO placeholder checks (let NotebookLM handle that!)
|
|
128
|
+
*
|
|
129
|
+
* Based on Python _wait_for_ready() from browser_session.py:104-113
|
|
130
|
+
*/
|
|
131
|
+
async waitForNotebookLMReady() {
|
|
132
|
+
if (!this.page) {
|
|
133
|
+
throw new Error("Page not initialized");
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
// PRIMARY: Exact Python selector - textarea.query-box-input
|
|
137
|
+
log.info(" ⏳ Waiting for chat input (textarea.query-box-input)...");
|
|
138
|
+
await this.page.waitForSelector("textarea.query-box-input", {
|
|
139
|
+
timeout: 10000, // Python uses 10s timeout
|
|
140
|
+
state: "visible", // ONLY check visibility (NO disabled check!)
|
|
141
|
+
});
|
|
142
|
+
log.success(" ✅ Chat input ready!");
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// FALLBACK: Python alternative selector
|
|
146
|
+
try {
|
|
147
|
+
log.info(" ⏳ Trying fallback selector (aria-label)...");
|
|
148
|
+
await this.page.waitForSelector('textarea[aria-label="Feld für Anfragen"]', {
|
|
149
|
+
timeout: 5000, // Python uses 5s for fallback
|
|
150
|
+
state: "visible",
|
|
151
|
+
});
|
|
152
|
+
log.success(" ✅ Chat input ready (fallback)!");
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
log.error(` ❌ NotebookLM interface not ready: ${error}`);
|
|
156
|
+
const currentUrl = this.page?.url() || 'unknown';
|
|
157
|
+
throw new Error(`Could not find NotebookLM chat input.\n\n` +
|
|
158
|
+
`Current URL: ${currentUrl}\n\n` +
|
|
159
|
+
`Possible causes:\n` +
|
|
160
|
+
`1. Invalid notebook URL - the notebook may not exist or you don't have access\n` +
|
|
161
|
+
`2. NotebookLM page structure changed (rare)\n` +
|
|
162
|
+
`3. Page took too long to load (timeout after 15 seconds)\n\n` +
|
|
163
|
+
`Please verify:\n` +
|
|
164
|
+
`- The notebook URL is correct\n` +
|
|
165
|
+
`- You have access to this notebook\n` +
|
|
166
|
+
`- The URL format: https://notebooklm.google.com/notebook/[id]`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
isPageClosedSafe() {
|
|
171
|
+
if (!this.page)
|
|
172
|
+
return true;
|
|
173
|
+
const p = this.page;
|
|
174
|
+
try {
|
|
175
|
+
if (typeof p.isClosed === 'function') {
|
|
176
|
+
if (p.isClosed())
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
// Accessing URL should be safe; if page is gone, this may throw
|
|
180
|
+
void this.page.url();
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Ensure the session is authenticated, perform auto-login if needed
|
|
189
|
+
*/
|
|
190
|
+
async ensureAuthenticated() {
|
|
191
|
+
if (!this.page) {
|
|
192
|
+
throw new Error("Page not initialized");
|
|
193
|
+
}
|
|
194
|
+
log.info(`🔑 Checking authentication for session ${this.sessionId}...`);
|
|
195
|
+
// Check cookie validity
|
|
196
|
+
const isValid = await this.authManager.validateCookiesExpiry(this.context);
|
|
197
|
+
if (isValid) {
|
|
198
|
+
log.success(` ✅ Cookies valid`);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
log.warning(` ⚠️ Cookies expired or invalid`);
|
|
202
|
+
// Try to get valid auth state
|
|
203
|
+
const statePath = await this.authManager.getValidStatePath();
|
|
204
|
+
if (statePath) {
|
|
205
|
+
// Load saved state
|
|
206
|
+
log.info(` 📂 Loading auth state from: ${statePath}`);
|
|
207
|
+
await this.authManager.loadAuthState(this.context, statePath);
|
|
208
|
+
// Reload page to apply new auth
|
|
209
|
+
log.info(` 🔄 Reloading page...`);
|
|
210
|
+
await this.page.reload({ waitUntil: "domcontentloaded" });
|
|
211
|
+
await randomDelay(2000, 3000);
|
|
212
|
+
// Check if it worked
|
|
213
|
+
const nowValid = await this.authManager.validateCookiesExpiry(this.context);
|
|
214
|
+
if (nowValid) {
|
|
215
|
+
log.success(` ✅ Auth state loaded successfully`);
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Need fresh login
|
|
220
|
+
log.warning(` 🔑 Fresh login required`);
|
|
221
|
+
if (CONFIG.autoLoginEnabled) {
|
|
222
|
+
log.info(` 🤖 Attempting auto-login...`);
|
|
223
|
+
const loginSuccess = await this.authManager.loginWithCredentials(this.context, this.page, CONFIG.loginEmail, CONFIG.loginPassword);
|
|
224
|
+
if (loginSuccess) {
|
|
225
|
+
log.success(` ✅ Auto-login successful`);
|
|
226
|
+
// Navigate back to notebook
|
|
227
|
+
await this.page.goto(this.notebookUrl, {
|
|
228
|
+
waitUntil: "domcontentloaded",
|
|
229
|
+
});
|
|
230
|
+
await randomDelay(2000, 3000);
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
log.error(` ❌ Auto-login failed`);
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
log.error(` ❌ Auto-login disabled and no valid auth state - manual login required`);
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
getOriginFromUrl(url) {
|
|
244
|
+
try {
|
|
245
|
+
return new URL(url).origin;
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Safely restore sessionStorage when the page is on the expected origin
|
|
253
|
+
*/
|
|
254
|
+
async restoreSessionStorage(sessionData, entryCount) {
|
|
255
|
+
if (!this.page) {
|
|
256
|
+
log.warning(` ⚠️ Cannot restore sessionStorage without an active page`);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const targetOrigin = this.getOriginFromUrl(this.notebookUrl);
|
|
260
|
+
if (!targetOrigin) {
|
|
261
|
+
log.warning(` ⚠️ Unable to determine target origin for sessionStorage restore`);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
let restored = false;
|
|
265
|
+
const applyToPage = async () => {
|
|
266
|
+
if (!this.page) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
const currentOrigin = this.getOriginFromUrl(this.page.url());
|
|
270
|
+
if (currentOrigin !== targetOrigin) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
await this.page.evaluate((data) => {
|
|
275
|
+
for (const [key, value] of Object.entries(data)) {
|
|
276
|
+
// @ts-expect-error - sessionStorage exists in browser context
|
|
277
|
+
sessionStorage.setItem(key, value);
|
|
278
|
+
}
|
|
279
|
+
}, sessionData);
|
|
280
|
+
restored = true;
|
|
281
|
+
log.success(` ✅ SessionStorage restored: ${entryCount} entries`);
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
log.warning(` ⚠️ Failed to restore sessionStorage: ${error}`);
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
if (await applyToPage()) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
log.info(` ⏳ Waiting for NotebookLM origin before restoring sessionStorage...`);
|
|
293
|
+
const handleNavigation = async () => {
|
|
294
|
+
if (restored) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (await applyToPage()) {
|
|
298
|
+
this.page?.off("framenavigated", handleNavigation);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
this.page.on("framenavigated", handleNavigation);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Ask a question to NotebookLM
|
|
305
|
+
*/
|
|
306
|
+
async ask(question, sendProgress) {
|
|
307
|
+
const askOnce = async () => {
|
|
308
|
+
if (!this.initialized || !this.page || this.isPageClosedSafe()) {
|
|
309
|
+
log.warning(` ℹ️ Session not initialized or page missing → re-initializing...`);
|
|
310
|
+
await this.init();
|
|
311
|
+
}
|
|
312
|
+
log.info(`💬 [${this.sessionId}] Asking: "${question.substring(0, 100)}..."`);
|
|
313
|
+
const page = this.page;
|
|
314
|
+
// Ensure we're still authenticated
|
|
315
|
+
await sendProgress?.("Verifying authentication...", 2, 5);
|
|
316
|
+
const isAuth = await this.authManager.validateCookiesExpiry(this.context);
|
|
317
|
+
if (!isAuth) {
|
|
318
|
+
log.warning(` 🔑 Session expired, re-authenticating...`);
|
|
319
|
+
await sendProgress?.("Re-authenticating session...", 2, 5);
|
|
320
|
+
const reAuthSuccess = await this.ensureAuthenticated();
|
|
321
|
+
if (!reAuthSuccess) {
|
|
322
|
+
throw new Error("Failed to re-authenticate session");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Snapshot existing responses BEFORE asking
|
|
326
|
+
log.info(` 📸 Snapshotting existing responses...`);
|
|
327
|
+
const existingResponses = await snapshotAllResponses(page);
|
|
328
|
+
log.success(` ✅ Captured ${existingResponses.length} existing responses`);
|
|
329
|
+
// Find the chat input
|
|
330
|
+
const inputSelector = await this.findChatInput();
|
|
331
|
+
if (!inputSelector) {
|
|
332
|
+
throw new Error("Could not find visible chat input element. " +
|
|
333
|
+
"Please check if the notebook page has loaded correctly.");
|
|
334
|
+
}
|
|
335
|
+
log.info(` ⌨️ Typing question with human-like behavior...`);
|
|
336
|
+
await sendProgress?.("Typing question with human-like behavior...", 2, 5);
|
|
337
|
+
await humanType(page, inputSelector, question, {
|
|
338
|
+
withTypos: true,
|
|
339
|
+
wpm: Math.max(CONFIG.typingWpmMin, CONFIG.typingWpmMax),
|
|
340
|
+
});
|
|
341
|
+
// Small pause before submitting
|
|
342
|
+
await randomDelay(500, 1000);
|
|
343
|
+
// Submit the question (Enter key)
|
|
344
|
+
log.info(` 📤 Submitting question...`);
|
|
345
|
+
await sendProgress?.("Submitting question...", 3, 5);
|
|
346
|
+
await page.keyboard.press("Enter");
|
|
347
|
+
// Small pause after submit
|
|
348
|
+
await randomDelay(1000, 1500);
|
|
349
|
+
// Wait for the response with streaming detection
|
|
350
|
+
log.info(` ⏳ Waiting for response (with streaming detection)...`);
|
|
351
|
+
await sendProgress?.("Waiting for NotebookLM response (streaming detection active)...", 3, 5);
|
|
352
|
+
const answer = await waitForLatestAnswer(page, {
|
|
353
|
+
question,
|
|
354
|
+
timeoutMs: 120000, // 2 minutes
|
|
355
|
+
pollIntervalMs: 1000,
|
|
356
|
+
ignoreTexts: existingResponses,
|
|
357
|
+
debug: true, // Enable debug to see exact text
|
|
358
|
+
});
|
|
359
|
+
if (!answer) {
|
|
360
|
+
throw new Error("Timeout waiting for response from NotebookLM");
|
|
361
|
+
}
|
|
362
|
+
// Check for rate limit errors AFTER receiving answer
|
|
363
|
+
log.info(` 🔍 Checking for rate limit errors...`);
|
|
364
|
+
if (await this.detectRateLimitError()) {
|
|
365
|
+
throw new RateLimitError("NotebookLM rate limit reached (50 queries/day for free accounts)");
|
|
366
|
+
}
|
|
367
|
+
// Update session stats
|
|
368
|
+
this.messageCount++;
|
|
369
|
+
this.updateActivity();
|
|
370
|
+
log.success(`✅ [${this.sessionId}] Received answer (${answer.length} chars, ${this.messageCount} total messages)`);
|
|
371
|
+
return answer;
|
|
372
|
+
};
|
|
373
|
+
try {
|
|
374
|
+
return await askOnce();
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
const msg = String(error?.message || error);
|
|
378
|
+
if (/has been closed|Target .* closed|Browser has been closed|Context .* closed/i.test(msg)) {
|
|
379
|
+
log.warning(` ♻️ Detected closed page/context. Recovering session and retrying ask...`);
|
|
380
|
+
try {
|
|
381
|
+
this.initialized = false;
|
|
382
|
+
if (this.page) {
|
|
383
|
+
try {
|
|
384
|
+
await this.page.close();
|
|
385
|
+
}
|
|
386
|
+
catch { }
|
|
387
|
+
}
|
|
388
|
+
this.page = null;
|
|
389
|
+
await this.init();
|
|
390
|
+
return await askOnce();
|
|
391
|
+
}
|
|
392
|
+
catch (e2) {
|
|
393
|
+
log.error(`❌ Recovery failed: ${e2}`);
|
|
394
|
+
throw e2;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
log.error(`❌ [${this.sessionId}] Failed to ask question: ${msg}`);
|
|
398
|
+
throw error;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Find the chat input element
|
|
403
|
+
*
|
|
404
|
+
* IMPORTANT: Matches Python implementation EXACTLY!
|
|
405
|
+
* - Uses SPECIFIC selectors from Python
|
|
406
|
+
* - Checks ONLY visibility (NOT disabled state!)
|
|
407
|
+
*
|
|
408
|
+
* Based on Python ask() method from browser_session.py:166-171
|
|
409
|
+
*/
|
|
410
|
+
async findChatInput() {
|
|
411
|
+
if (!this.page) {
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
// Use EXACT Python selectors (in order of preference)
|
|
415
|
+
const selectors = [
|
|
416
|
+
"textarea.query-box-input", // ← PRIMARY Python selector
|
|
417
|
+
'textarea[aria-label="Feld für Anfragen"]', // ← Python fallback
|
|
418
|
+
];
|
|
419
|
+
for (const selector of selectors) {
|
|
420
|
+
try {
|
|
421
|
+
const element = await this.page.$(selector);
|
|
422
|
+
if (element) {
|
|
423
|
+
const isVisible = await element.isVisible();
|
|
424
|
+
if (isVisible) {
|
|
425
|
+
// NO disabled check! Just like Python!
|
|
426
|
+
log.success(` ✅ Found chat input: ${selector}`);
|
|
427
|
+
return selector;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
log.error(` ❌ Could not find visible chat input`);
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Detect if a rate limit error occurred
|
|
440
|
+
*
|
|
441
|
+
* Searches the page for error messages indicating rate limit/quota exhaustion.
|
|
442
|
+
* Free NotebookLM accounts have 50 queries/day limit.
|
|
443
|
+
*
|
|
444
|
+
* @returns true if rate limit error detected, false otherwise
|
|
445
|
+
*/
|
|
446
|
+
async detectRateLimitError() {
|
|
447
|
+
if (!this.page) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
// Error message selectors (common patterns for error containers)
|
|
451
|
+
const errorSelectors = [
|
|
452
|
+
".error-message",
|
|
453
|
+
".error-container",
|
|
454
|
+
"[role='alert']",
|
|
455
|
+
".rate-limit-message",
|
|
456
|
+
"[data-error]",
|
|
457
|
+
".notification-error",
|
|
458
|
+
".alert-error",
|
|
459
|
+
".toast-error",
|
|
460
|
+
];
|
|
461
|
+
// Keywords that indicate rate limiting
|
|
462
|
+
const keywords = [
|
|
463
|
+
"rate limit",
|
|
464
|
+
"limit exceeded",
|
|
465
|
+
"quota exhausted",
|
|
466
|
+
"daily limit",
|
|
467
|
+
"limit reached",
|
|
468
|
+
"too many requests",
|
|
469
|
+
"ratenlimit",
|
|
470
|
+
"quota",
|
|
471
|
+
"query limit",
|
|
472
|
+
"request limit",
|
|
473
|
+
];
|
|
474
|
+
// Check error containers for rate limit messages
|
|
475
|
+
for (const selector of errorSelectors) {
|
|
476
|
+
try {
|
|
477
|
+
const elements = await this.page.$$(selector);
|
|
478
|
+
for (const el of elements) {
|
|
479
|
+
try {
|
|
480
|
+
const text = await el.innerText();
|
|
481
|
+
const lower = text.toLowerCase();
|
|
482
|
+
if (keywords.some((k) => lower.includes(k))) {
|
|
483
|
+
log.error(`🚫 Rate limit detected: ${text.slice(0, 100)}`);
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
catch {
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
// Also check if chat input is disabled (sometimes NotebookLM disables input when rate limited)
|
|
497
|
+
try {
|
|
498
|
+
const inputSelector = "textarea.query-box-input";
|
|
499
|
+
const input = await this.page.$(inputSelector);
|
|
500
|
+
if (input) {
|
|
501
|
+
const isDisabled = await input.evaluate((el) => {
|
|
502
|
+
return el.disabled || el.hasAttribute("disabled");
|
|
503
|
+
});
|
|
504
|
+
if (isDisabled) {
|
|
505
|
+
// Check if there's an error message near the input
|
|
506
|
+
const parent = await input.evaluateHandle((el) => el.parentElement);
|
|
507
|
+
const parentEl = parent.asElement();
|
|
508
|
+
if (parentEl) {
|
|
509
|
+
try {
|
|
510
|
+
const parentText = await parentEl.innerText();
|
|
511
|
+
const lower = parentText.toLowerCase();
|
|
512
|
+
if (keywords.some((k) => lower.includes(k))) {
|
|
513
|
+
log.error(`🚫 Rate limit detected: Chat input disabled with error message`);
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
catch {
|
|
518
|
+
// Ignore
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
// Ignore errors checking input state
|
|
526
|
+
}
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Reset the chat history (start a new conversation)
|
|
531
|
+
*/
|
|
532
|
+
async reset() {
|
|
533
|
+
const resetOnce = async () => {
|
|
534
|
+
if (!this.initialized || !this.page || this.isPageClosedSafe()) {
|
|
535
|
+
await this.init();
|
|
536
|
+
}
|
|
537
|
+
log.info(`🔄 [${this.sessionId}] Resetting chat history...`);
|
|
538
|
+
// Reload the page to clear chat history
|
|
539
|
+
await this.page.reload({ waitUntil: "domcontentloaded" });
|
|
540
|
+
await randomDelay(2000, 3000);
|
|
541
|
+
// Wait for interface to be ready again
|
|
542
|
+
await this.waitForNotebookLMReady();
|
|
543
|
+
// Reset message count
|
|
544
|
+
this.messageCount = 0;
|
|
545
|
+
this.updateActivity();
|
|
546
|
+
log.success(`✅ [${this.sessionId}] Chat history reset`);
|
|
547
|
+
};
|
|
548
|
+
try {
|
|
549
|
+
await resetOnce();
|
|
550
|
+
}
|
|
551
|
+
catch (error) {
|
|
552
|
+
const msg = String(error?.message || error);
|
|
553
|
+
if (/has been closed|Target .* closed|Browser has been closed|Context .* closed/i.test(msg)) {
|
|
554
|
+
log.warning(` ♻️ Detected closed page/context during reset. Recovering and retrying...`);
|
|
555
|
+
this.initialized = false;
|
|
556
|
+
if (this.page) {
|
|
557
|
+
try {
|
|
558
|
+
await this.page.close();
|
|
559
|
+
}
|
|
560
|
+
catch { }
|
|
561
|
+
}
|
|
562
|
+
this.page = null;
|
|
563
|
+
await this.init();
|
|
564
|
+
await resetOnce();
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
log.error(`❌ [${this.sessionId}] Failed to reset: ${msg}`);
|
|
568
|
+
throw error;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Close the session
|
|
573
|
+
*/
|
|
574
|
+
async close() {
|
|
575
|
+
log.info(`🛑 Closing session ${this.sessionId}...`);
|
|
576
|
+
if (this.page) {
|
|
577
|
+
try {
|
|
578
|
+
await this.page.close();
|
|
579
|
+
this.page = null;
|
|
580
|
+
log.success(` ✅ Page closed`);
|
|
581
|
+
}
|
|
582
|
+
catch (error) {
|
|
583
|
+
log.warning(` ⚠️ Error closing page: ${error}`);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
this.initialized = false;
|
|
587
|
+
log.success(`✅ Session ${this.sessionId} closed`);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Update last activity timestamp
|
|
591
|
+
*/
|
|
592
|
+
updateActivity() {
|
|
593
|
+
this.lastActivity = Date.now();
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Check if session has expired (inactive for too long)
|
|
597
|
+
*/
|
|
598
|
+
isExpired(timeoutSeconds) {
|
|
599
|
+
const inactiveSeconds = (Date.now() - this.lastActivity) / 1000;
|
|
600
|
+
return inactiveSeconds > timeoutSeconds;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Get session information
|
|
604
|
+
*/
|
|
605
|
+
getInfo() {
|
|
606
|
+
const now = Date.now();
|
|
607
|
+
return {
|
|
608
|
+
id: this.sessionId,
|
|
609
|
+
created_at: this.createdAt,
|
|
610
|
+
last_activity: this.lastActivity,
|
|
611
|
+
age_seconds: (now - this.createdAt) / 1000,
|
|
612
|
+
inactive_seconds: (now - this.lastActivity) / 1000,
|
|
613
|
+
message_count: this.messageCount,
|
|
614
|
+
notebook_url: this.notebookUrl,
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Get the underlying page (for advanced operations)
|
|
619
|
+
*/
|
|
620
|
+
getPage() {
|
|
621
|
+
return this.page;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Check if session is initialized
|
|
625
|
+
*/
|
|
626
|
+
isInitialized() {
|
|
627
|
+
return this.initialized && this.page !== null;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
//# sourceMappingURL=browser-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-session.js","sourceRoot":"","sources":["../../src/session/browser-session.ts"],"names":[],"mappings":"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"}
|